howdy icon indicating copy to clipboard operation
howdy copied to clipboard

Ubuntu 24.04 howdy 3.0.0 beta installation

Open joezhouchenye opened this issue 1 year ago • 18 comments

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.

  1. Clone the project with version 3.0.0 beta
  2. Edit meson.options and modify option('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.
  3. sudo howdy add. It might give errors. Most python modules can be installed using apt except dlib.
  4. 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.
  5. Config the camera https://github.com/boltgolt/howdy/wiki/Common-issues#error-when-trying-to-add-a-face-model
  6. Now, you can add and test the face. Authentication for sudo should work now.
  7. The login face recognition still has a problem. You need to manually modify /usr/local/lib/x86_64-linux-gnu/howdy/compare.py. Add sys.path.append('/usr/local/lib/python3.12/dist-packages') after the import sys line.
  8. The new version has a GUI utility howdy-gtk. Python module elevate is needed which is also not provide by apt. sudo pip3 install elevate --break-system-packages. With sudo howdy-gtk, you get the following GUI:

image

joezhouchenye avatar Dec 17 '24 13:12 joezhouchenye

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.

Halmoni100 avatar Dec 25 '24 21:12 Halmoni100

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 

joezhouchenye avatar Dec 26 '24 03:12 joezhouchenye

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.

Halmoni100 avatar Dec 26 '24 05:12 Halmoni100

There is an issue with the keyring being locked when first logging in. I found the solution here:

https://gist.github.com/kizzard/166470fefe8fa64d2aa65e0235115318

joezhouchenye avatar Feb 02 '25 07:02 joezhouchenye

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.

jaud7of8 avatar Feb 10 '25 22:02 jaud7of8

Where did you get v3.0.0 beta? I only see tags and releases up to v2.6.1.

erget avatar Feb 14 '25 18:02 erget

It’s the default branch (beta).

Halmoni100 avatar Feb 15 '25 01:02 Halmoni100

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?

erget avatar Feb 15 '25 10:02 erget

Ok, I installed python-is-python3 and now I can build... Will check back in later :)

erget avatar Feb 15 '25 10:02 erget

``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?

erget avatar Feb 15 '25 17:02 erget

Sorry for spamming - it was /dev/video0, just tried it on a lucky guess. Moving on...

erget avatar Feb 15 '25 17:02 erget

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!

erget avatar Feb 15 '25 17:02 erget

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!

erget avatar Feb 15 '25 17:02 erget

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?

erget avatar Feb 15 '25 17:02 erget

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/howdy
    • sudo 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.

BobDotCom avatar Feb 27 '25 04:02 BobDotCom

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)

kgamora avatar May 08 '25 23:05 kgamora