Ubuntu 24.04 howdy 3.0.0 beta installation
I found many issues related to Ubuntu 24.04. However, they are messing up different howdy versions and don't solve the problem. So, I decided to create this issue and post my working solution.
- Clone the project with version 3.0.0 beta
- Edit
meson.optionsand modifyoption('install_pam_config', type: 'boolean', value: true, description: 'Install pam config file (for Debian/Ubuntu)'). Build and install as mentioned in README. I have no idea why this isn't a default behavior. sudo howdy add. It might give errors. Most python modules can be installed using apt except dlib.sudo pip3 install dlib --break-system-packages. Try to add face again. It will ask you to run a script to download models. Chinese users may have network problems. Check the script and manually do that.- Config the camera https://github.com/boltgolt/howdy/wiki/Common-issues#error-when-trying-to-add-a-face-model
- Now, you can add and test the face. Authentication for sudo should work now.
- The login face recognition still has a problem. You need to manually modify
/usr/local/lib/x86_64-linux-gnu/howdy/compare.py. Addsys.path.append('/usr/local/lib/python3.12/dist-packages')after theimport sysline. - The new version has a GUI utility howdy-gtk. Python module
elevateis needed which is also not provide by apt.sudo pip3 install elevate --break-system-packages. Withsudo howdy-gtk, you get the following GUI:
Thank you so much! Personally I also had to add the following to the top of /etc/pam.d/common-auth in order to get the PAM integration to work.
auth sufficient /usr/local/lib/x86_64-linux-gnu/security/pam_howdy.so
I think you posted this somewhere else, but it's here for reference.
I thought step 2 would do this (Install pam config file). Sorry for not testing this step. I found a file named /usr/share/pam-configs/howdy (Maybe created by previous install) and I modified it with the following content:
Name: Howdy
Default: yes
Priority: 512
Auth-Type: Primary
Auth:
[success=end default=ignore] /usr/local/lib/x86_64-linux-gnu/security/pam_howdy.so
Maybe you will have to run sudo pam-auth-update and enable Howdy there.
After this, the common-auth is automatically modified with the following line:
auth [success=3 default=ignore] /usr/local/lib/x86_64-linux-gnu/security/pam_howdy.so
The meson build default prefix (for me) seems to be /usr/local, so the howdy pam config ends up in /usr/local/share/pam-configs/howdy, and so pam-auth-update does not detect it.
Sym linking /usr/local/share/pam-configs/howdy to /usr/share/pam-configs/howdy seems to work for me.
There is an issue with the keyring being locked when first logging in. I found the solution here:
https://gist.github.com/kizzard/166470fefe8fa64d2aa65e0235115318
This worked. I had a couple of places I need to research to get it to work.
I had to install meson separately.
sudo apt install meson
I had to setup a sym link to python3
sudo ln -s /usr/bin/python3 /usr/bin/python
I think I also had to cd to the build dir after the first step of building.
I did not need to edit the
/usr/local/lib/x86_64-linux-gnu/howdy/compare.py
As mentioned above I did
add the following to the top of /etc/pam.d/common-auth in order to get the PAM integration to work.
sudo nano /etc/pam.d/common-auth
auth sufficient /usr/local/lib/x86_64-linux-gnu/security/pam_howdy.so
sudo pam-auth-update
did not show howdy
I had to do this symlink
sudo ln -s /usr/local/share/pam-configs/howdy /usr/share/pam-configs/howdy
Then sudo -i used the camera for authentication.
It’s the default branch (beta).
Thanks. I'm on c4521c14ab8c672cadbc826a3dbec9ef95b7adb1 and was following the README and ran into some trouble here, logging it for returning later:
$ meson setup build
The Meson build system
Version: 1.6.1
Source dir: /home/erget/Documents/howdy
Build dir: /home/erget/Documents/howdy/build
Build type: native build
Project name: howdy
Project version: beta
C++ compiler for the host machine: c++ (gcc 13.3.0 "c++ (Ubuntu 13.3.0-6ubuntu2~24.04) 13.3.0")
C++ linker for the host machine: c++ ld.bfd 2.42
Host machine cpu family: x86_64
Host machine cpu: x86_64
Configuring paths.py using configuration
Program python3 found: YES (/usr/bin/python3)
Found pkg-config: YES (/usr/bin/pkg-config) 1.8.1
Run-time dependency python found: YES 3.12
Configuring howdy-gtk using configuration
Traceback (most recent call last):
File "/usr/lib/python3/dist-packages/mesonbuild/mesonmain.py", line 193, in run
return options.run_func(options)
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3/dist-packages/mesonbuild/msetup.py", line 365, in run
app.generate()
File "/usr/lib/python3/dist-packages/mesonbuild/msetup.py", line 188, in generate
return self._generate(env, capture, vslite_ctx)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3/dist-packages/mesonbuild/msetup.py", line 227, in _generate
intr.run()
File "/usr/lib/python3/dist-packages/mesonbuild/interpreter/interpreter.py", line 3065, in run
super().run()
File "/usr/lib/python3/dist-packages/mesonbuild/interpreterbase/interpreterbase.py", line 169, in run
self.evaluate_codeblock(self.ast, start=1)
File "/usr/lib/python3/dist-packages/mesonbuild/interpreterbase/interpreterbase.py", line 195, in evaluate_codeblock
raise e
File "/usr/lib/python3/dist-packages/mesonbuild/interpreterbase/interpreterbase.py", line 187, in evaluate_codeblock
self.evaluate_statement(cur)
File "/usr/lib/python3/dist-packages/mesonbuild/interpreterbase/interpreterbase.py", line 201, in evaluate_statement
return self.function_call(cur)
^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3/dist-packages/mesonbuild/interpreterbase/interpreterbase.py", line 528, in function_call
res = func(node, func_args, kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3/dist-packages/mesonbuild/interpreterbase/decorators.py", line 237, in wrapper
return f(*nargs, **wrapped_kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3/dist-packages/mesonbuild/interpreterbase/decorators.py", line 556, in wrapper
return f(*wrapped_args, **wrapped_kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3/dist-packages/mesonbuild/interpreter/interpreter.py", line 2478, in func_subdir
self.evaluate_codeblock(codeblock)
File "/usr/lib/python3/dist-packages/mesonbuild/interpreterbase/interpreterbase.py", line 195, in evaluate_codeblock
raise e
File "/usr/lib/python3/dist-packages/mesonbuild/interpreterbase/interpreterbase.py", line 187, in evaluate_codeblock
self.evaluate_statement(cur)
File "/usr/lib/python3/dist-packages/mesonbuild/interpreterbase/interpreterbase.py", line 201, in evaluate_statement
return self.function_call(cur)
^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3/dist-packages/mesonbuild/interpreterbase/interpreterbase.py", line 528, in function_call
res = func(node, func_args, kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3/dist-packages/mesonbuild/interpreterbase/decorators.py", line 237, in wrapper
return f(*nargs, **wrapped_kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3/dist-packages/mesonbuild/interpreterbase/decorators.py", line 556, in wrapper
return f(*wrapped_args, **wrapped_kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3/dist-packages/mesonbuild/interpreter/interpreter.py", line 2478, in func_subdir
self.evaluate_codeblock(codeblock)
File "/usr/lib/python3/dist-packages/mesonbuild/interpreterbase/interpreterbase.py", line 195, in evaluate_codeblock
raise e
File "/usr/lib/python3/dist-packages/mesonbuild/interpreterbase/interpreterbase.py", line 187, in evaluate_codeblock
self.evaluate_statement(cur)
File "/usr/lib/python3/dist-packages/mesonbuild/interpreterbase/interpreterbase.py", line 205, in evaluate_statement
self.assignment(cur)
File "/usr/lib/python3/dist-packages/mesonbuild/interpreterbase/interpreterbase.py", line 642, in assignment
value = self.evaluate_statement(node.value)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3/dist-packages/mesonbuild/interpreterbase/interpreterbase.py", line 207, in evaluate_statement
return self.method_call(cur)
^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3/dist-packages/mesonbuild/interpreterbase/interpreterbase.py", line 557, in method_call
res = obj.method_call(method_name, args, kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3/dist-packages/mesonbuild/interpreter/interpreterobjects.py", line 885, in method_call
ret = method(state, args, kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3/dist-packages/mesonbuild/interpreterbase/decorators.py", line 85, in wrapped
ret = f(*wrapped_args, **wrapped_kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3/dist-packages/mesonbuild/interpreterbase/decorators.py", line 237, in wrapper
return f(*nargs, **wrapped_kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3/dist-packages/mesonbuild/interpreterbase/decorators.py", line 556, in wrapper
return f(*wrapped_args, **wrapped_kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3/dist-packages/mesonbuild/modules/python.py", line 509, in find_installation
python = self._find_installation_impl(state, display_name, name_or_path, required)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3/dist-packages/mesonbuild/modules/python.py", line 465, in _find_installation_impl
if python.sanity(state):
^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3/dist-packages/mesonbuild/modules/python.py", line 74, in sanity
ret = super().sanity()
^^^^^^^^^^^^^^^^
File "/usr/lib/python3/dist-packages/mesonbuild/dependencies/python.py", line 125, in sanity
p, stdout, stderr = mesonlib.Popen_safe(cmd, env=env)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3/dist-packages/mesonbuild/utils/universal.py", line 1544, in Popen_safe
p = subprocess.Popen(args, universal_newlines=True, encoding=encoding, close_fds=False,
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.12/subprocess.py", line 1026, in __init__
self._execute_child(args, executable, preexec_fn, close_fds,
File "/usr/lib/python3.12/subprocess.py", line 1840, in _execute_child
self._posix_spawn(args, executable, env, restore_signals,
File "/usr/lib/python3.12/subprocess.py", line 1784, in _posix_spawn
self.pid = os.posix_spawn(executable, args, env, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
FileNotFoundError: [Errno 2] No such file or directory: '/usr/bin/python'
ERROR: Unhandled python OSError. This is probably not a Meson bug, but an issue with your build environment.
It looks like Python's not found, and indeed, it's not there:
$ ls /usr/bin/python3
/usr/bin/python3
I'm wondering if something like ln -s /usr/bin/python3 /usr/bin/python is safe? That sounds dangerous to me.
Also curious as to why that full path is hardcoded. Do you think just linking to the executable is a bad idea, as I would assume, or might there be a more elegant way to handle it?
Ok, I installed python-is-python3 and now I can build... Will check back in later :)
``Ok, worked up to sudo howdy add and then it cuoldn't find my device:
erget@erget:/usr/local/share/dlib-data$ sudo howdy add
Adding face model for the user erget
Enter a label for this new model [Model #0]: daniel
Howdy could not find a camera device at the path specified in the config file.
It is very likely that the path is not configured correctly, please edit the 'device_path' config value by running:
sudo howdy config
howdy config calls up an editor for /usr/local/etc/howdy/config.ini:
erget@erget:/usr/local/share/dlib-data$ grep device_path /usr/local/etc/howdy/config.ini -B 2
# The path of the device to capture frames from
# Video devices are usually found in /dev/v4l/by-path/
device_path = pci-0000:00:14.0-usbv2-0:5:1.0-video-index1
That's the result after having tried all these permutations:
erget@erget:/usr/local/share/dlib-data$ ls /dev/v4l/by-path/
pci-0000:00:14.0-usb-0:5:1.0-video-index0 pci-0000:00:14.0-usbv2-0:5:1.0-video-index0
pci-0000:00:14.0-usb-0:5:1.0-video-index1 pci-0000:00:14.0-usbv2-0:5:1.0-video-index1
But still howdy's not able to find the camera device. Any ideas?
Sorry for spamming - it was /dev/video0, just tried it on a lucky guess. Moving on...
Ok... Hit my next roadblock. After editing /usr/local/etc/howdy/config.ini to point to /dev/video0 I can now sudo howdy test and I see my face. Yay progress! I've also setup a model for my user and I can sudo howdy list the model. However, when I try to sudo anything it still wants a password. Any clues? I see that in Fedora this can be a known issue; I'm using Tuxedo OS, which is based off Ubuntu 24.04 so I assume it shouldn't be an issue for me. Would be grateful for any ideas!
Ok... Made it a bit farther now. Following the advice in https://github.com/boltgolt/howdy/issues/953#issuecomment-2547600379 I added a line to /etc/pam.d/common-auth and now it uses my face on sudo. Almost there!
And updating /usr/local/lib/x86_64-linux-gnu/howdy/compare.py as described in the OP works, now I can login with my face.
Would it be helpful to update the instructions in the "install from source" section of the README? I'd be happy to make a PR... Also I assume the modifications to meson.options and stuff might be worthwhile to update in the main branch? Or are these changes to distro-specific?
I'm running a fresh install of Ubuntu 24.10, and I ran into a couple issues. I figure I'll provide my notes in case it helps anyone else.
- Needed to run
apt install meson(looks like this should be in the readme but its just missing) - Needed to run
apt install python-is-python3 - Needed to symlink the pam config and update pam auth to enable howdy
ln -s /usr/local/share/pam-configs/howdy /usr/share/pam-configs/howdysudo pam-auth-update(I didn't need to use this, but it can't hurt)- Enable howdy if it isn't already
- See https://github.com/boltgolt/howdy/issues/976#issuecomment-2562157850
- Did not need step 7 of the original post
- There is an issue with the keyring being locked on login as mentioned in https://github.com/boltgolt/howdy/issues/976#issuecomment-2629274798
- The instructions on the gist don't work, but this comment does https://gist.github.com/kizzard/166470fefe8fa64d2aa65e0235115318?permalink_comment_id=5306557#gistcomment-5306557
Anyway, huge thanks for this. Hopefully a more graceful solution will be implemented soon so these workarounds aren't necessary.
This one worked for me, thanks! However I got an error on meson build that I'm not inside venv (though I was in) So I had to use the native file approach and it worked (also dlib still wasn't found by howdy after all the steps, but sudoing pip install dlib did the job)