[2/5] allow creation of users/groups before rootfs creation

Message ID 20230125090156.284309-3-tobias.schaffner@siemens.com
State Superseded, archived
Headers show
Series allow creation of users/groups before rootfs creation | expand

Commit Message

Tobias Schaffner Jan. 25, 2023, 9:01 a.m. UTC
From: Tobias Schaffner <tobias.schaffner@siemens.com>

Allow the user to specify that a user or group should be created before
rootfs creation instead of in the postprocessing step.

If a user or group is tagged with `USER_x[pre] = "true"` it will be
created in the rootfs configuration step instead.

Signed-off-by: Tobias Schaffner <tobias.schaffner@siemens.com>
---
 doc/user_manual.md                           |  2 ++
 meta/classes/image-account-extension.bbclass | 25 ++++++++++++++++++--
 2 files changed, 25 insertions(+), 2 deletions(-)

Patch

diff --git a/doc/user_manual.md b/doc/user_manual.md
index ec639e7..1d209b3 100644
--- a/doc/user_manual.md
+++ b/doc/user_manual.md
@@ -661,6 +661,7 @@  The `GROUP_<groupname>` variable contains the settings of a group named `groupna
  - `gid` - The numeric group id.
  - `flags` - A list of additional flags of the group. Those are the currently recognized flags:
    - `system` - The group is created using the `--system` parameter.
+ - `pre` - Creates the group in the rootfs configuration instead of the postprocessing step if set to `true`.
 
 The `USERS` and `USER_<username>` variable works similar to the `GROUPS` and `GROUP_<groupname>` variable. The difference are the accepted flags of the `USER_<username>` variable. It accepts the following flags:
 
@@ -680,6 +681,7 @@  The `USERS` and `USER_<username>` variable works similar to the `GROUPS` and `GR
    - `allow-empty-password` - Even if the `password` flag is empty, it will still be set. This results in a login without password.
    - `clear-text-password` - The `password` flag of the given user contains a clear-text password and not an encrypted version of it.
    - `force-passwd-change` - Force the user to change to password on first login.
+ - `pre` - Creates the user in the rootfs configuration instead of the postprocessing step if set to `true`.
 
 #### Home directory contents prefilling
 
diff --git a/meta/classes/image-account-extension.bbclass b/meta/classes/image-account-extension.bbclass
index 127732a..c0f2269 100644
--- a/meta/classes/image-account-extension.bbclass
+++ b/meta/classes/image-account-extension.bbclass
@@ -18,19 +18,23 @@  USERS ??= ""
 #USER_root[shell] = "/bin/sh"
 #USER_root[groups] = "audio video"
 #USER_root[flags] = "no-create-home create-home system allow-empty-password clear-text-password force-passwd-change"
+#USER_root[pre] = ""
 
 GROUPS ??= ""
 
 #GROUPS += "root"
 #GROUP_root[gid] = ""
 #GROUP_root[flags] = "system"
+#GROUP_root[pre] = ""
 
 
-def image_create_groups(d: "DataSmart") -> None:
+def image_create_groups(d: "DataSmart", pre: bool = False) -> None:
     """Creates the groups defined in the ``GROUPS`` bitbake variable.
 
     Args:
         d (DataSmart): The bitbake datastore.
+        pre (bool): Creates only the entries tagged with GROUP_x[pre] = "true" if True or all others
+            if set to False (default).
 
     Returns:
         None
@@ -43,6 +47,10 @@  def image_create_groups(d: "DataSmart") -> None:
         args = []
         group_entry = "GROUP_{}".format(entry)
 
+        pre_flag = (d.getVarFlag(group_entry, "pre", True) or "") == "true"
+        if pre_flag != pre:
+            continue
+
         with open("{}/etc/group".format(rootfsdir), "r") as group_file:
             exists = any(line.startswith("{}:".format(entry)) for line in group_file)
 
@@ -62,11 +70,13 @@  def image_create_groups(d: "DataSmart") -> None:
             bb.process.run([*chroot, "/usr/sbin/groupadd", *args, entry])
 
 
-def image_create_users(d: "DataSmart") -> None:
+def image_create_users(d: "DataSmart", pre: bool = False) -> None:
     """Creates the users defined in the ``USERS`` bitbake variable.
 
     Args:
         d (DataSmart): The bitbake datastore.
+        pre (bool): Creates only the entries tagged with USER_x[pre] = "true" if True or all others
+            if set to False (default).
 
     Returns:
         None
@@ -82,6 +92,10 @@  def image_create_users(d: "DataSmart") -> None:
         args = []
         user_entry = "USER_{}".format(entry)
 
+        pre_flag = (d.getVarFlag(user_entry, "pre", True) or "") == "true"
+        if pre_flag != pre:
+            continue
+
         with open("{}/etc/passwd".format(rootfsdir), "r") as passwd_file:
             exists = any(line.startswith("{}:".format(entry)) for line in passwd_file)
 
@@ -148,6 +162,13 @@  def image_create_users(d: "DataSmart") -> None:
             bb.process.run([*chroot, "/usr/sbin/passwd", "--expire", entry])
 
 
+ROOTFS_CONFIGURE_COMMAND += "image_configure_accounts"
+image_configure_accounts[weight] = "3"
+python image_configure_accounts() {
+    image_create_groups(d, True)
+    image_create_users(d, True)
+}
+
 ROOTFS_POSTPROCESS_COMMAND += "image_postprocess_accounts"
 python image_postprocess_accounts() {
     image_create_groups(d)