pyinfra-dev / pyinfra

pyinfra turns Python code into shell commands and runs them on your servers. Execute ad-hoc commands and write declarative operations. Target SSH servers, local machine and Docker containers. Fast and scales from one server to thousands.
https://pyinfra.com
MIT License
3.85k stars 374 forks source link

Installing a package may create a user but not update the fact #987

Closed link2xt closed 7 months ago

link2xt commented 1 year ago

Describe the bug

Operation server.user depends on the facts about the user to choose between using useradd and usermod. If the facts about users say that user does not exist, but in fact the user exists, pyinfra effectively does nothing.

To Reproduce

Create the following deploy.py file:

from pyinfra.operations import apt, server

apt.packages(name="Install postfix", packages=["postfix"], update=True)
server.group(name="Create group foo", group="foo", system=True)
server.user(
    name="Add user postfix to group foo", user="postfix", group="foo", system=True
)

Run pyinfra -vvvv --ssh-user root example.org deploy.py, where example.org is a freshly installed Ubuntu 22.04 VM.

Expected behavior

I expect that postfix package is installed and then pyinfra adds the user postfix to the group foo. Instead, pyinfra does not add the user to the group, but checks that user exists and does not execute useradd.

--> Starting operation: Add user postfix to group foo 
[example.org] >>> sh -c 'grep '"'"'^postfix:'"'"' /etc/passwd || useradd -d /home/postfix -g foo -r postfix'
[example.org] postfix:x:114:120::/var/spool/postfix:/usr/sbin/nologin
[example.org] >>> sh -c 'mkdir -p /home/postfix'
[example.org] >>> sh -c 'chown postfix:foo /home/postfix'
[example.org] Success

It should instead run usermod.

The solution would be to fix apt to update the facts about the users to include the information about the user postfix added by the post-install script.

link2xt commented 1 year ago

My current workaround for this is creating all the groups and users at the beginning of the deploy, but this may not be possible in a structured deploy with functions calling each other.

Fizzadar commented 1 year ago

Another unfortunate example of operation side effects impacting each other (#805), I am working on a new approach that may resolve these once and for all 🤞!

Fizzadar commented 7 months ago

v3 fixes this, now that the first beta is out I’ll close this issue.