From 645735a3063921ca5a33695ccbaa569f79e22f6f Mon Sep 17 00:00:00 2001 From: Disassembler Date: Fri, 7 Feb 2020 21:48:53 +0100 Subject: [PATCH] Allow to pass UID/GID to container exec --- usr/bin/spoc-container | 8 +++++--- usr/lib/python3.8/spoc/container.py | 27 +++++++++++++++++---------- 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/usr/bin/spoc-container b/usr/bin/spoc-container index 776cafd..8b74a41 100644 --- a/usr/bin/spoc-container +++ b/usr/bin/spoc-container @@ -94,9 +94,9 @@ def status(container_name): # Prints current running status of the container print(Container(container_name).get_state()) -def execute(container_name, command): +def execute(container_name, command, uid, gid): # Execute a command in container's namespace - Container(container_name).execute(command) + Container(container_name).execute(command, uid, gid) parser = argparse.ArgumentParser(description='SPOC container manager') parser.set_defaults(action=None) @@ -149,6 +149,8 @@ parser_status.add_argument('container') parser_exec = subparsers.add_parser('exec') parser_exec.set_defaults(action=ACTION_EXEC) +parser_exec.add_argument('-u', '--uid', help='Sets the command UID') +parser_exec.add_argument('-g', '--gid', help='Sets the command GID') parser_exec.add_argument('container') parser_exec.add_argument('command', nargs=argparse.REMAINDER) @@ -167,6 +169,6 @@ elif args.action == ACTION_STOP: elif args.action == ACTION_STATUS: status(args.container) elif args.action == ACTION_EXEC: - execute(args.container, args.command) + execute(args.container, args.command, args.uid, args.gid) else: parser.print_usage() diff --git a/usr/lib/python3.8/spoc/container.py b/usr/lib/python3.8/spoc/container.py index 789163b..6d0f514 100644 --- a/usr/lib/python3.8/spoc/container.py +++ b/usr/lib/python3.8/spoc/container.py @@ -173,8 +173,7 @@ class Container: subprocess.Popen(['lxc-stop', '-P', CONTAINERS_DIR, self.name]) self.await_state(STATE_STOPPED) - def execute(self, cmd, **kwargs): - # TODO: Allow to pass UID/GID + def execute(self, cmd, uid=None, gid=None, **kwargs): # If the container is starting or stopping, wait until the operation is finished state = self.get_state() if state == STATE_STARTING: @@ -183,19 +182,27 @@ class Container: elif state == STATE_STOPPING: self.await_state(STATE_STOPPED) state = self.get_state() + # Resolve UID/GID, if they have been given + uidgid_param = [] + uid,gid = self.get_uidgid(uid, gid) + if uid: + uidgid_param.extend(('-u', uid)) + if gid: + uidgid_param.extend(('-g', gid)) # If the container is stopped, use lxc-execute, otherwise use lxc-attach if state == STATE_STOPPED: - return subprocess.run(['lxc-execute', '-P', CONTAINERS_DIR, self.name, '--']+cmd, **kwargs) + return subprocess.run(['lxc-execute', '-P', CONTAINERS_DIR]+uidgid_param+[self.name, '--']+cmd, **kwargs) elif state == STATE_RUNNING: - return subprocess.run(['lxc-attach', '-P', CONTAINERS_DIR, '--clear-env', self.name, '--']+cmd, **kwargs) + return subprocess.run(['lxc-attach', '-P', CONTAINERS_DIR, '--clear-env']+uidgid_param+[self.name, '--']+cmd, **kwargs) else: raise InvalidContainerStateError(self.name, state) - def get_uidgid(self, user, group=None): + def get_uidgid(self, user=None, group=None): # Helper function to get UID/GID of an user/group from the container - uid_entry = self.execute(['/usr/bin/getent', 'passwd', user], capture_output=True, check=True).stdout.decode().split(':') + uid,gid = None,None + if user: + uid_entry = self.execute(['/usr/bin/getent', 'passwd', user], capture_output=True, check=True).stdout.decode().split(':') + uid,gid = uid_entry[2],uid_entry[3] if group: - gid_entry = self.execute(['/usr/bin/getent', 'group', group], capture_output=True, check=True).stdout.decode().split(':') - return (uid_entry[2], gid_entry[2]) - else: - return (uid_entry[2], uid_entry[3]) + gid = self.execute(['/usr/bin/getent', 'group', group], capture_output=True, check=True).stdout.decode().split(':')[2] + return (uid,gid)