> On May 9, 2016, at 5:55 PM, Stephano Cetola <[email protected]> > wrote: > > On 05/09, Khem Raj wrote: >> >>> On May 9, 2016, at 4:42 PM, Stephano Cetola >>> <[email protected]> wrote: >>> >>> This fix ensures that systemd users are created at build and that any >>> staticids for the users or groups are preserved. This functionality only >>> existed for readonly filesystems, however it seems wise to be sure these >>> users are added rather than relying on systemd to create them. >> >> We need to cover the case where online package management is used. If you >> were to fix >> it in systemd recipe itself which takes care of creating these users in post >> installs >> that will fix it for this case too. > I'm not sure I follow you. I can see how this could be done in a post > install script, but I'm missing how this would help online package > management. Could you please point me in the right direction?
Lets say, I did not install microhttpserver in default image. But later on I decided to install it via O_P_M feeds. or remove for that matter. >> >>> >>> [ YOCTO #9497 ] >>> >>> Signed-off-by: Stephano Cetola <[email protected]> >>> --- >>> meta/classes/rootfs-postcommands.bbclass | 66 >>> +++++++++++++++++++++----------- >>> meta/classes/useradd-staticids.bbclass | 56 +-------------------------- >>> useradd-staticids-list.bbclass | 56 +++++++++++++++++++++++++++ >>> 3 files changed, 100 insertions(+), 78 deletions(-) >>> create mode 100644 useradd-staticids-list.bbclass >>> >>> diff --git a/meta/classes/rootfs-postcommands.bbclass >>> b/meta/classes/rootfs-postcommands.bbclass >>> index 95d28af..db4cc75 100644 >>> --- a/meta/classes/rootfs-postcommands.bbclass >>> +++ b/meta/classes/rootfs-postcommands.bbclass >>> @@ -1,4 +1,4 @@ >>> - >>> +inherit useradd-staticids-list >>> # Zap the root password if debug-tweaks feature is not enabled >>> ROOTFS_POSTPROCESS_COMMAND += '${@bb.utils.contains_any("IMAGE_FEATURES", [ >>> 'debug-tweaks', 'empty-root-password' ], "", "zap_empty_root_password ; >>> ",d)}' >>> >>> @@ -23,6 +23,9 @@ POSTINST_LOGFILE ?= "${localstatedir}/log/postinstall.log" >>> SYSTEMD_DEFAULT_TARGET ?= '${@bb.utils.contains("IMAGE_FEATURES", >>> "x11-base", "graphical.target", "multi-user.target", d)}' >>> ROOTFS_POSTPROCESS_COMMAND += '${@bb.utils.contains("DISTRO_FEATURES", >>> "systemd", "set_systemd_default_target; ", "", d)}' >>> >>> +# Create systemd users at build rather than at runtime >>> +ROOTFS_POSTPROCESS_COMMAND += '${@bb.utils.contains("DISTRO_FEATURES", >>> "systemd", "create_systemd_sysusers; ", "", d)}' >>> + >>> ROOTFS_POSTPROCESS_COMMAND += 'empty_var_volatile;' >>> >>> # Disable DNS lookups, the SSH_DISABLE_DNS_LOOKUP can be overridden to allow >>> @@ -30,7 +33,45 @@ ROOTFS_POSTPROCESS_COMMAND += 'empty_var_volatile;' >>> SSH_DISABLE_DNS_LOOKUP ?= " ssh_disable_dns_lookup ; " >>> ROOTFS_POSTPROCESS_COMMAND_append_qemuall = "${SSH_DISABLE_DNS_LOOKUP}" >>> >>> - >>> +# Add systemd users checking for any staticids >>> +python create_systemd_sysusers () { >>> + import shlex >>> + import subprocess >>> + s_users = merge_files(get_passwd_list(d), 7) >>> + s_groups = merge_files(get_group_list(d), 4) >>> + confs = ['%s/usr/lib/sysusers.d/systemd.conf' % >>> d.getVar('IMAGE_ROOTFS', d), '%s/usr/lib/sysusers.d/systemd-remote.conf' % >>> d.getVar('IMAGE_ROOTFS', d)] >>> + for conf in confs: >>> + if os.path.isfile(conf): >>> + with open(conf, 'r') as f: >>> + for line in f: >>> + if line.startswith('#'): >>> + continue >>> + fields = shlex.split(line.rstrip()) >>> + if not fields: >>> + continue >>> + if fields[0] == 'u': >>> + useradd_params = '' >>> + if fields[1] in s_users: >>> + useradd_params += '--uid %s' % >>> s_users[fields[1]][2] >>> + bb.warn("Changing user %s's uid to (%s), >>> verify configuration files!" % (fields[1], s_users[fields[1]][2])) >>> + elif fields[2] != '-': >>> + useradd_params += '--uid %s' % fields[2] >>> + if fields[3] != '-': >>> + useradd_params += ' --comment "%s"' % fields[3] >>> + useradd_params += ' --root "%s" --shell >>> /sbin/nologin --system %s' % (d.getVar("IMAGE_ROOTFS", d), fields[1]) >>> + code = subprocess.call('useradd %s' % >>> useradd_params, shell=True) >>> + elif fields[0] == 'g': >>> + groupadd_params = "" >>> + if fields[1] in s_groups: >>> + groupadd_params += '--gid %s' % >>> s_groups[fields[1]][2] >>> + bb.warn("Changing group %s's gid to (%s), >>> verify configuration files!" % (fields[1], s_groups[fields[1]][2])) >>> + elif fields[2] != '-': >>> + groupadd_params += '--gid %s' % fields[2] >>> + if fields[3] != '-': >>> + groupadd_params += ' --comment "%s"' % >>> (d.getVar("IMAGE_ROOTFS", d), fields[3]) >>> + groupadd_params += ' --root "%s" --system %s' % >>> (d.getVar("IMAGE_ROOTFS", d), fields[1]) >>> + code = subprocess.call('groupadd %s' % >>> groupadd_params, shell=True) >>> +} >>> >>> # >>> # A hook function to support read-only-rootfs IMAGE_FEATURES >>> @@ -73,27 +114,6 @@ read_only_rootfs_hook () { >>> ${IMAGE_ROOTFS}/etc/init.d/populate-volatile.sh >>> fi >>> fi >>> - >>> - if ${@bb.utils.contains("DISTRO_FEATURES", "systemd", "true", "false", >>> d)}; then >>> - # Update user database files so that services don't fail for a >>> read-only systemd system >>> - for conffile in ${IMAGE_ROOTFS}/usr/lib/sysusers.d/systemd.conf >>> ${IMAGE_ROOTFS}/usr/lib/sysusers.d/systemd-remote.conf; do >>> - [ -e $conffile ] || continue >>> - grep -v "^#" $conffile | sed -e '/^$/d' | while read type name >>> id comment; do >>> - if [ "$type" = "u" ]; then >>> - useradd_params="" >>> - [ "$id" != "-" ] && useradd_params="$useradd_params >>> --uid $id" >>> - [ "$comment" != "-" ] && >>> useradd_params="$useradd_params --comment $comment" >>> - useradd_params="$useradd_params --system $name" >>> - eval useradd --root ${IMAGE_ROOTFS} $useradd_params || >>> true >>> - elif [ "$type" = "g" ]; then >>> - groupadd_params="" >>> - [ "$id" != "-" ] && groupadd_params="$groupadd_params >>> --gid $id" >>> - groupadd_params="$groupadd_params --system $name" >>> - eval groupadd --root ${IMAGE_ROOTFS} $groupadd_params >>> || true >>> - fi >>> - done >>> - done >>> - fi >>> } >>> >>> # >>> diff --git a/meta/classes/useradd-staticids.bbclass >>> b/meta/classes/useradd-staticids.bbclass >>> index a9b506d..e9dfe69 100644 >>> --- a/meta/classes/useradd-staticids.bbclass >>> +++ b/meta/classes/useradd-staticids.bbclass >>> @@ -1,3 +1,4 @@ >>> +inherit useradd-staticids-list >>> # In order to support a deterministic set of 'dynamic' users/groups, >>> # we need a function to reformat the params based on a static file >>> def update_useradd_static_config(d): >>> @@ -17,35 +18,6 @@ def update_useradd_static_config(d): >>> def error(self, message): >>> raise bb.build.FuncFailed(message) >>> >>> - def list_extend(iterable, length, obj = None): >>> - """Ensure that iterable is the specified length by extending with >>> obj >>> - and return it as a list""" >>> - return list(itertools.islice(itertools.chain(iterable, >>> itertools.repeat(obj)), length)) >>> - >>> - def merge_files(file_list, exp_fields): >>> - """Read each passwd/group file in file_list, split each line and >>> create >>> - a dictionary with the user/group names as keys and the split lines >>> as >>> - values. If the user/group name already exists in the dictionary, >>> then >>> - update any fields in the list with the values from the new list >>> (if they >>> - are set).""" >>> - id_table = dict() >>> - for conf in file_list.split(): >>> - if os.path.exists(conf): >>> - f = open(conf, "r") >>> - for line in f: >>> - if line.startswith('#'): >>> - continue >>> - # Make sure there always are at least exp_fields >>> elements in >>> - # the field list. This allows for leaving out trailing >>> - # colons in the files. >>> - fields = list_extend(line.rstrip().split(":"), >>> exp_fields) >>> - if fields[0] not in id_table: >>> - id_table[fields[0]] = fields >>> - else: >>> - id_table[fields[0]] = list(itertools.imap(lambda >>> x, y: x or y, fields, id_table[fields[0]])) >>> - >>> - return id_table >>> - >>> # We parse and rewrite the useradd components >>> def rewrite_useradd(params): >>> # The following comes from --help on useradd from shadow >>> @@ -73,19 +45,6 @@ def update_useradd_static_config(d): >>> parser.add_argument("-U", "--user-group", help="create a group with >>> the same name as the user", action="store_const", const=True) >>> parser.add_argument("LOGIN", help="Login name of the new user") >>> >>> - # Return a list of configuration files based on either the default >>> - # files/passwd or the contents of USERADD_UID_TABLES >>> - # paths are resolved via BBPATH >>> - def get_passwd_list(d): >>> - str = "" >>> - bbpath = d.getVar('BBPATH', True) >>> - passwd_tables = d.getVar('USERADD_UID_TABLES', True) >>> - if not passwd_tables: >>> - passwd_tables = 'files/passwd' >>> - for conf_file in passwd_tables.split(): >>> - str += " %s" % bb.utils.which(bbpath, conf_file) >>> - return str >>> - >>> newparams = [] >>> users = None >>> for param in re.split('''[ \t]*;[ >>> \t]*(?=(?:[^'"]|'[^']*'|"[^"]*")*$)''', params): >>> @@ -206,19 +165,6 @@ def update_useradd_static_config(d): >>> parser.add_argument("-r", "--system", help="create a system >>> account", action="store_true") >>> parser.add_argument("GROUP", help="Group name of the new group") >>> >>> - # Return a list of configuration files based on either the default >>> - # files/group or the contents of USERADD_GID_TABLES >>> - # paths are resolved via BBPATH >>> - def get_group_list(d): >>> - str = "" >>> - bbpath = d.getVar('BBPATH', True) >>> - group_tables = d.getVar('USERADD_GID_TABLES', True) >>> - if not group_tables: >>> - group_tables = 'files/group' >>> - for conf_file in group_tables.split(): >>> - str += " %s" % bb.utils.which(bbpath, conf_file) >>> - return str >>> - >>> newparams = [] >>> groups = None >>> for param in re.split('''[ \t]*;[ >>> \t]*(?=(?:[^'"]|'[^']*'|"[^"]*")*$)''', params): >>> diff --git a/useradd-staticids-list.bbclass b/useradd-staticids-list.bbclass >>> new file mode 100644 >>> index 0000000..377f748 >>> --- /dev/null >>> +++ b/useradd-staticids-list.bbclass >>> @@ -0,0 +1,56 @@ >>> +# Return a list of configuration files based on either the default >>> +# files/group or the contents of USERADD_GID_TABLES >>> +# paths are resolved via BBPATH >>> +def get_group_list(d): >>> + str = "" >>> + bbpath = d.getVar('BBPATH', True) >>> + group_tables = d.getVar('USERADD_GID_TABLES', True) >>> + if not group_tables: >>> + group_tables = 'files/group' >>> + for conf_file in group_tables.split(): >>> + str += " %s" % bb.utils.which(bbpath, conf_file) >>> + return str >>> + >>> +def list_extend(iterable, length, obj = None): >>> + import itertools >>> + """Ensure that iterable is the specified length by extending with obj >>> + and return it as a list""" >>> + return list(itertools.islice(itertools.chain(iterable, >>> itertools.repeat(obj)), length)) >>> + >>> +def merge_files(file_list, exp_fields): >>> + import itertools >>> + """Read each passwd/group file in file_list, split each line and create >>> + a dictionary with the user/group names as keys and the split lines as >>> + values. If the user/group name already exists in the dictionary, then >>> + update any fields in the list with the values from the new list (if >>> they >>> + are set).""" >>> + id_table = dict() >>> + for conf in file_list.split(): >>> + if os.path.exists(conf): >>> + f = open(conf, "r") >>> + for line in f: >>> + if line.startswith('#'): >>> + continue >>> + # Make sure there always are at least exp_fields elements >>> in >>> + # the field list. This allows for leaving out trailing >>> + # colons in the files. >>> + fields = list_extend(line.rstrip().split(":"), exp_fields) >>> + if fields[0] not in id_table: >>> + id_table[fields[0]] = fields >>> + else: >>> + id_table[fields[0]] = list(itertools.imap(lambda x, y: >>> x or y, fields, id_table[fields[0]])) >>> + >>> + return id_table >>> + >>> +# Return a list of configuration files based on either the default >>> +# files/passwd or the contents of USERADD_UID_TABLES >>> +# paths are resolved via BBPATH >>> +def get_passwd_list(d): >>> + str = "" >>> + bbpath = d.getVar('BBPATH', True) >>> + passwd_tables = d.getVar('USERADD_UID_TABLES', True) >>> + if not passwd_tables: >>> + passwd_tables = 'files/passwd' >>> + for conf_file in passwd_tables.split(): >>> + str += " %s" % bb.utils.which(bbpath, conf_file) >>> + return str >>> -- >>> 2.8.0 >>> >>> -- >>> _______________________________________________ >>> Openembedded-core mailing list >>> [email protected] >>> http://lists.openembedded.org/mailman/listinfo/openembedded-core >> > >
signature.asc
Description: Message signed with OpenPGP using GPGMail
-- _______________________________________________ Openembedded-core mailing list [email protected] http://lists.openembedded.org/mailman/listinfo/openembedded-core
