Pyinfra: Don't hide fact failure due to no sudo password/etc

Created on 10 Jul 2020  路  10Comments  路  Source: Fizzadar/pyinfra

I don't know why such a basic function doesn't work and is not pretty usable.

pyinfra v0.16.2

pyinfra -v @local tt.py

tt.py:

from pyinfra import host


SUDO = True

assert host.fact.linux_name is not None

Outcome:

--> Loading config...
--> Loading inventory...

--> Connecting to hosts...
    [@local] Connected

--> Preparing operations...
    Loading: tt.py
    Loaded fact linux_distribution
--> An unexpected exception occurred:

  File "tt.py", line 6, in <module>
    assert host.fact.linux_name is not None
AssrtionError

Bug Facts

All 10 comments

Which Linux Distribution the above run host has?

It is Ubuntu 20.04. But other than linux_name, every other attributes are None as well. Like host_names, etc.

@FooBarQuaxx @Fizzadar Looks like this is a bug. This is because of the line SUDO = True; without this line it works correctly. Or when --sudo is passed. I can also reproduce in the latest master 1.0.dev1.

@wookayin yes a verbose run of pyinfra -vv --debug @local tt.py gives something similar to this:

...
[pyinfra.api.connectors.local] --> Running command on localhost: sudo -H -n sh -c 'cat /etc/*-release'
[@local] >>> sudo -H -n sh -c 'cat /etc/*-release'
[@local] sudo: a password is required
...

Edit: With a regular use, I don't thing you needed a SUDO run for all types of invocations.

I see, thanks! This is because all sudo commands fail. Could we have better error handling in gathering facts? Throwing error should be more intuitive than having facts being None.

Your point was brought up before here and here

So this is a bit more involved - v1 implements fact failure, but only where we don't expect facts to fail (ie deb_packages is expected to fail on some systems, so we return the default).

I agree when sudo password request is in the output pyinfra should make it explicitly obvious why the fact failed (and the need to pass use_sudo_password=True. Slightly related: https://github.com/Fizzadar/pyinfra/issues/359

Currently planning to properly review the facts api for v1.1.

This is now covered by https://github.com/Fizzadar/pyinfra/commit/d8e97d36243be8d78a29e419afb33abad38332b5, which will print out the sudo password required error.

FYI: one of the examples doesn't work.

examples/docker_ce,py fails quietly - the command runs but nothing is executed. It seems host.fact.linux becomes None and skips the conditional block containing the commands.

Bypassing that, another problem: an error is thrown at the second apt.packages command, requiring a password, but none was asked. I tried the following but nothing works:

> pyinfra @local /path/to/docker_ce.py 
> pyinfra @local /path/to/docker_ce.py use_sudo_password=true
> pyinfra @local /path/to/docker_ce.py --use_sudo_password

A third issue: later host.fact.command("apt-key list") complains that no such fact exists.

UPDATE: the second issue regarding passwords was somewhat resolved adding use_sudo_password=True into the appropriate operation function (in code, not the terminal). See also more insight on env vars in config.py.

apt.key, isn't adding new gpgs when apt-key list is called.

Can confirm other facts are returning None, e.g. linux_id and code_name

The other issues remain.

Nice spot @pylang! I've added https://github.com/Fizzadar/pyinfra/issues/408 to track this.

Was this page helpful?
0 / 5 - 0 ratings