From 6a5a2565092e26769ebd490a8e3bbe18d82fade9 Mon Sep 17 00:00:00 2001 From: Stephen Newey Date: Tue, 30 Jun 2015 13:23:42 +0100 Subject: [PATCH 1/4] Add support for user on exec_create. --- docker/client.py | 11 +++++++++-- tests/integration_test.py | 17 +++++++++++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/docker/client.py b/docker/client.py index 998ebacb..274359bf 100644 --- a/docker/client.py +++ b/docker/client.py @@ -521,19 +521,26 @@ class Client(requests.Session): return self.exec_start(create_res, detach, tty, stream) def exec_create(self, container, cmd, stdout=True, stderr=True, tty=False, - privileged=False): + user=None, privileged=False): if utils.compare_version('1.15', self._version) < 0: raise errors.InvalidVersion('Exec is not supported in API < 1.15') if privileged and utils.compare_version('1.19', self._version) < 0: raise errors.InvalidVersion( 'Privileged exec is not supported in API < 1.19' ) + if user and utils.compare_version('1.19', self._version) < 0: + raise errors.InvalidVersion( + 'User-specific exec is not supported in API < 1.19' + ) if isinstance(cmd, six.string_types): cmd = shlex.split(str(cmd)) + if user is None: + user = '' + data = { 'Container': container, - 'User': '', + 'User': user, 'Privileged': privileged, 'Tty': tty, 'AttachStdin': False, diff --git a/tests/integration_test.py b/tests/integration_test.py index 4b9869e2..f0064fa2 100644 --- a/tests/integration_test.py +++ b/tests/integration_test.py @@ -829,6 +829,23 @@ class TestExecuteCommandString(BaseTestCase): self.assertEqual(exec_log, expected) +@unittest.skipIf(not EXEC_DRIVER_IS_NATIVE, 'Exec driver not native') +class TestExecuteCommandStringAsUser(BaseTestCase): + def runTest(self): + container = self.client.create_container('busybox', 'cat', + detach=True, stdin_open=True) + id = container['Id'] + self.client.start(id) + self.tmp_containers.append(id) + + res = self.client.exec_create(id, 'whoami', user='default') + self.assertIn('Id', res) + + exec_log = self.client.exec_start(res) + expected = b'default' if six.PY3 else 'default\n' + self.assertEqual(exec_log, expected) + + @unittest.skipIf(not EXEC_DRIVER_IS_NATIVE, 'Exec driver not native') class TestExecuteCommandStreaming(BaseTestCase): def runTest(self): From a12818a8a864846c4bcc7c0d3eab1d8ae038b2d3 Mon Sep 17 00:00:00 2001 From: Stephen Newey Date: Tue, 30 Jun 2015 13:41:22 +0100 Subject: [PATCH 2/4] Add user argument to exec_create documentation. --- docker/client.py | 2 +- docs/api.md | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/docker/client.py b/docker/client.py index 274359bf..7bdb464a 100644 --- a/docker/client.py +++ b/docker/client.py @@ -521,7 +521,7 @@ class Client(requests.Session): return self.exec_start(create_res, detach, tty, stream) def exec_create(self, container, cmd, stdout=True, stderr=True, tty=False, - user=None, privileged=False): + privileged=False, user=None): if utils.compare_version('1.15', self._version) < 0: raise errors.InvalidVersion('Exec is not supported in API < 1.15') if privileged and utils.compare_version('1.19', self._version) < 0: diff --git a/docs/api.md b/docs/api.md index 4b641471..9f580a07 100644 --- a/docs/api.md +++ b/docs/api.md @@ -282,6 +282,7 @@ Sets up an exec instance in a running container. * stdout (bool): Attach to stdout of the exec command if true. Default: True * stderr (bool): Attach to stderr of the exec command if true. Default: True * tty (bool): Allocate a pseudo-TTY. Default: False +* user (str): User to execute command as. Default: root **Returns** (dict): A dictionary with an exec 'Id' key. From 7bbec93f64b36bb055ebbe1a6c40c2ba1ca3b8cf Mon Sep 17 00:00:00 2001 From: Stephen Newey Date: Thu, 2 Jul 2015 13:24:51 +0100 Subject: [PATCH 3/4] Add test for root user as default exec_create behaviour --- tests/integration_test.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/tests/integration_test.py b/tests/integration_test.py index f0064fa2..9ce3e3ec 100644 --- a/tests/integration_test.py +++ b/tests/integration_test.py @@ -846,6 +846,23 @@ class TestExecuteCommandStringAsUser(BaseTestCase): self.assertEqual(exec_log, expected) +@unittest.skipIf(not EXEC_DRIVER_IS_NATIVE, 'Exec driver not native') +class TestExecuteCommandStringAsRoot(BaseTestCase): + def runTest(self): + container = self.client.create_container('busybox', 'cat', + detach=True, stdin_open=True) + id = container['Id'] + self.client.start(id) + self.tmp_containers.append(id) + + res = self.client.exec_create(id, 'whoami') + self.assertIn('Id', res) + + exec_log = self.client.exec_start(res) + expected = b'root' if six.PY3 else 'root\n' + self.assertEqual(exec_log, expected) + + @unittest.skipIf(not EXEC_DRIVER_IS_NATIVE, 'Exec driver not native') class TestExecuteCommandStreaming(BaseTestCase): def runTest(self): From 2febf104a02e5d7c17ba321cf179848f4c9a7945 Mon Sep 17 00:00:00 2001 From: Stephen Newey Date: Wed, 12 Aug 2015 18:08:12 +0100 Subject: [PATCH 4/4] Change unnecessary user=None in args to empty string and remove check. --- docker/client.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/docker/client.py b/docker/client.py index 7bdb464a..74c33a2c 100644 --- a/docker/client.py +++ b/docker/client.py @@ -521,7 +521,7 @@ class Client(requests.Session): return self.exec_start(create_res, detach, tty, stream) def exec_create(self, container, cmd, stdout=True, stderr=True, tty=False, - privileged=False, user=None): + privileged=False, user=''): if utils.compare_version('1.15', self._version) < 0: raise errors.InvalidVersion('Exec is not supported in API < 1.15') if privileged and utils.compare_version('1.19', self._version) < 0: @@ -535,9 +535,6 @@ class Client(requests.Session): if isinstance(cmd, six.string_types): cmd = shlex.split(str(cmd)) - if user is None: - user = '' - data = { 'Container': container, 'User': user,