From 1c915b2e4cd45ec02c394135e51ae3fdc4c9a624 Mon Sep 17 00:00:00 2001 From: Maksym Naboka Date: Wed, 6 Jul 2016 17:43:11 -0700 Subject: [PATCH] add group to make 3dt read journal[DO NOT MERGE] 3dt needs to read the journal. In order to do that it needs to be in systemd-journal group. The issue is that coreos uses several backends for users and groups. One is a regular /etc/passwd, /etc/groups and the other is located under /usr/share/baselayout. If we try to append dcos_3dt user with flag -G this will not work. (Tested on CoreOS beta (1068.3.0)) This seems to be a long running issue with CoreOS https://github.com/coreos/bugs/issues/312 However if we try to change a user's primary group with -g flag all works as expected. This is not meant to be merged, used for testing at this point. --- packages/3dt/buildinfo.json | 1 + pkgpanda/__init__.py | 38 ++++++++++++++++++++++++++++--------- pkgpanda/build/__init__.py | 12 ++++++++++++ 3 files changed, 42 insertions(+), 9 deletions(-) diff --git a/packages/3dt/buildinfo.json b/packages/3dt/buildinfo.json index 4c99cde929..c72afac960 100644 --- a/packages/3dt/buildinfo.json +++ b/packages/3dt/buildinfo.json @@ -8,5 +8,6 @@ "ref_origin": "master" }, "username": "dcos_3dt", + "group": "systemd-journal", "state_directory": true } diff --git a/pkgpanda/__init__.py b/pkgpanda/__init__.py index cb33852f74..353b80949b 100644 --- a/pkgpanda/__init__.py +++ b/pkgpanda/__init__.py @@ -172,6 +172,10 @@ def state_directory(self): def username(self): return self.__pkginfo.get('username', None) + @property + def group(self): + return self.__pkginfo.get('group', None) + def __repr__(self): return str(self.__id) @@ -442,7 +446,14 @@ def validate_username(username): if not re.match(username_regex, username): raise ValidationError("Username must begin with `dcos_` and only have a-z and underscore after that") - def add_user(self, username): + @staticmethod + def validate_group(group): + try: + check_output(['getent', 'group', group]) + except CalledProcessError as ex: + raise ValidationError("Group {} does not exist on the system".format(group)) + + def add_user(self, username, group): UserManagement.validate_username(username) if not self._manage_users: @@ -463,14 +474,23 @@ def add_user(self, username): "automatic user addition is disabled".format(username)) # Add the user: + add_user_cmd = [ + 'useradd', + '--system', + '--home-dir', '/opt/mesosphere', + '--shell', '/sbin/nologin', + '-c', 'DCOS System User', + ] + + if group is not None: + add_user_cmd += [ + '-g', group + ] + + add_user_cmd += [username] + try: - check_output([ - 'useradd', - '--system', - '--home-dir', '/opt/mesosphere', - '--shell', '/sbin/nologin', - '-c', 'DCOS System User', - username]) + check_output(add_user_cmd) self._users.add(username) except CalledProcessError as ex: raise ValidationError("User {} doesn't exist and couldn't be created because of: {}" @@ -681,7 +701,7 @@ def symlink_all(src, dest): # to something incompatible. We survive the first upgrade because everything goes from # root to specific users, and root can access all user files. if package.username is not None: - sysusers.add_user(package.username) + sysusers.add_user(package.username, package.group) # Ensure the state directory in `/var/lib/dcos` exists # TODO(cmaloney): On upgrade take a snapshot? diff --git a/pkgpanda/build/__init__.py b/pkgpanda/build/__init__.py index 6d4f25892e..219f1fd174 100644 --- a/pkgpanda/build/__init__.py +++ b/pkgpanda/build/__init__.py @@ -858,6 +858,18 @@ def cache_abs(filename): raise BuildError("username in buildinfo.json didn't meet the validation rules. {}".format(ex)) pkginfo['username'] = username + group = None + if builder.has('group'): + group = builder.take('group') + if not isinstance(group, str): + raise BuildError("group in buildinfo.json must be either not set (use default group for this user)" + ", or group must be a string") + try: + pkgpanda.UserManagement.validate_group(group) + except ValidationError as ex: + raise BuildError("groupd in buildinfo.json didn't meet the validation rules. {}".format(ex)) + pkginfo['group'] = group + # Packages need directories inside the fake install root (otherwise docker # will try making the directories on a readonly filesystem), so build the # install root now, and make the package directories in it as we go.