Skip to content

[ADD] ops/server.user: allow to add user to more secondary groups #1331

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 16, 2025

Conversation

Pirols
Copy link
Contributor

@Pirols Pirols commented Apr 4, 2025

It is often necessary to add a user to a secondary group, without dropping it from other secondary groups it already belonged to. usermod provides a -a flag dedicated to this very need. This commit allows to leverage that flag via pyinfra.

In fact, in pyinfra this is even more necessary as facts are collected and never updated, making so that:

from pyinfra import host
from pyinfra.facts.server import Users
from pyinfra.operations import server

server.group(
    name="create main group",
    group="user",
)

server.group(
    name="create secondary group 1",
    group="extra_group1",
)

server.user(
    name="create user `user`",
    user="user",
    groups=["extra_group1"],
)

server.group(
    name="create secondary group 2",
    group="extra_group2",
)

server.user(
    name="Add user to extra group 2",
    user="user",
    groups=[
        *host.get_fact(Users).get("user", {}).get("groups", []),
        "extra_group2",
    ],
)
  • yields usermod -G extra_group1,extra_group2 user if user was member of extra_group1 before the task started, or
  • yields usermod -G extra_group2 user, if it was not part of the task

Notice that it does not matter whether the user user was added to the extra_group1 group by pyinfra.

It is often necessary to add a user to a secondary group, without dropping it
from other secondary groups it already belonged to. `usermod` provides a `-a`
flag dedicated to this very need. This commit allows to leverage that flag via
`pyinfra`.

In fact, in `pyinfra` this is even more necessary as facts are collected and
never updated, making so that:

```python
from pyinfra import host
from pyinfra.facts.server import Users
from pyinfra.operations import server

server.group(
    name="create main group",
    group="user",
)

server.group(
    name="create secondary group 1",
    group="extra_group1",
)

server.user(
    name="create user `user`",
    user="user",
    groups=["extra_group1"],
)

server.group(
    name="create secondary group 2",
    group="extra_group2",
)

server.user(
    name="Add user to extra group 2",
    user="user",
    groups=[
        *host.get_fact(Users).get("user", {}).get("groups", []),
        "extra_group2",
    ],
)
```

* yields `usermod -G extra_group1,extra_group2 user` if `user` was member of
`extra_group1` before the task started, or
* yields `usermod -G extra_group2 user`, if it was not part of the task

Notice that it does not matter whether the user `user` was added to the
`extra_group1` group by `pyinfra`.
@Pirols Pirols force-pushed the 3.x-append_secondary_users-Pirols branch 2 times, most recently from d66475b to f68e4b2 Compare April 4, 2025 16:00
@Pirols
Copy link
Contributor Author

Pirols commented Apr 4, 2025

The CI linting seems to be failing, while scripts/dev-lint.sh does not highlight any issue. And the error message in the CI message is cryptic to me.

Copy link
Member

@Fizzadar Fizzadar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, thank you for adding this @Pirols!

Re:CI - it's the black formatter failing on a completely unrelated file, so ignoring!

@Fizzadar Fizzadar merged commit 79d72bd into pyinfra-dev:3.x Apr 16, 2025
8 of 12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants