holo-users-groups - Holo plugin to provision user accounts and groups


This plugin provisions UNIX user accounts to passwd(5), and groups to group(5). Provisioning uses the standard commands useradd(8), usermod(8), userdel(8), groupadd(8), groupmod(8) and groupdel(8).

Entity definitions are placed at /usr/share/holo/users-groups/*.toml and are written in TOML. The following fields are accepted for users and groups:

name    = "mygroup"            # string,  the group name
system  = false                # if true, gives --system to groupadd
gid     = 1001                 # integer, given to groupadd as --gid

name    = "myuser"             # string,  the user name
system  = false                # if true, gives --system to useradd
comment = "My Own User"        # string,  given to useradd as --comment
uid     = 1023                 # integer, given to useradd as --uid
group   = "mygroup"            # string,  given to useradd as --gid
groups  = [ "audio", "video" ] # strings, given to useradd as --groups
home    = "/var/lib/myuser"    # string,  given to useradd as --home-dir
shell   = "/usr/bin/zsh"       # string,  given to useradd as --shell

In either case, name is the only required attribute. Multiple entity definitions may apply to the same entity if they have the same name attribute. This can be useful if a base hologram creates the entity and a later hologram requires more specific configuration for this entity. When entity definitions are stacked on each other, they are not allowed to contradict one another. (Different lists of auxiliary groups are allowed and will be merged.)

The entity names for users and groups are user:$name and group:$name, respectively, where $name is the user name or group name.

Apply operation

Ensure that the entity is present on the system and conforms to the entity definition. --force is required to overwrite properties that conflict between the actual state and the entity definition.

When an entity is applied for the first time, the previous state of the entity is saved into /var/lib/holo/users-groups/base/$entity_id.toml. If the entity did not exist before, the base image will only contain the type and name. The base image will be restored by holo apply when all definition files for this entity are deleted.

Whenever an entity is successfully applied, its state will be recorded into /var/lib/holo/users-groups/provisioned/$entity_id.toml. This provisioned image will be used for diffing.

UNKNOWN {"type":"head3","attrs":{"start_line":"59"},"content":"Merging of attributes"}

The desired state of the entity is computed by merging each attribute of the entity definition into the base image at /var/lib/holo/users-groups/base/$entity_id.toml. For most attributes, merging succeeds if the attribute is set by only one side or the other (or by neither side), or if the attribute is set to the same value on both sides.

As an exception, the groups field (the list of auxiliary groups) of a user definition is merged by compiling a list of all groups mentioned on either side. For example, if /etc/passwd contains a user http by default, which is part of the auxiliary group grp1, and you then add an entity definition like so:

name = "http"
groups = ["grp2"]

Then after holo apply user:http, the user will be part of both grp1 and grp2. If you want to overwrite the set of auxiliary groups from the base image, set the skipBaseGroups flag like so:

name = "http"
groups = ["grp2"]
skipBaseGroups = true

Diff operation

Display a diff if the current state of the entity conflicts with the entity definition. The right side of the diff is always a serialization of the actual state of the entity, as stated by /etc/passwd and/or /etc/group. For example:

diff --holo /var/lib/holo/users-groups/provisioned/user:wrongshell.toml /tmp/holo/users-groups/user:wrongshell/actual.toml
--- /var/lib/holo/users-groups/provisioned/user:wrongshell.toml
+++ /tmp/holo/users-groups/user:wrongshell/actual.toml
@@ -3,4 +3,4 @@ name = "wrongshell"
 uid = 1005
 home = "/home/wrongshell"
 group = "users"
-shell = "/bin/zsh"
+shell = "/bin/bash"

For entities that have been applied at least once, the left side of the diff is /var/lib/holo/users-groups/provisioned/$entity_id.toml. For entities that have not been applied yet, the left side of the diff is the "desired state", obtained by merging the entity definition with the actual state. If any attributes have conflicting values, the entity definition takes precedence.


holo(8) provides the user interface for using this plugin.


Stefan Majewsky

Further documentation is available at the project homepage:

Please report any issues and feature requests at GitHub: