diff --git a/salt/states/cmd.py b/salt/states/cmd.py index 4d20b5138175..86934f9ffc4b 100644 --- a/salt/states/cmd.py +++ b/salt/states/cmd.py @@ -402,6 +402,7 @@ def wait(name, unless=None, creates=None, cwd=None, + root=None, runas=None, shell=None, env=(), @@ -436,6 +437,10 @@ def wait(name, The current working directory to execute the command in, defaults to /root + root + Path to the root of the jail to use. If this parameter is set, the command + will run inside a chroot + runas The user name to run the command as @@ -674,6 +679,7 @@ def run(name, unless=None, creates=None, cwd=None, + root=None, runas=None, shell=None, env=None, @@ -707,6 +713,10 @@ def run(name, The current working directory to execute the command in, defaults to /root + root + Path to the root of the jail to use. If this parameter is set, the command + will run inside a chroot + runas The user name to run the command as @@ -882,6 +892,7 @@ def run(name, cmd_kwargs = copy.deepcopy(kwargs) cmd_kwargs.update({'cwd': cwd, + 'root': root, 'runas': runas, 'use_vt': use_vt, 'shell': shell or __grains__['shell'], @@ -912,10 +923,11 @@ def run(name, # Wow, we passed the test, run this sucker! try: - cmd_all = __salt__['cmd.run_all']( - name, timeout=timeout, python_shell=True, **cmd_kwargs + run_cmd = 'cmd.run_all' if not root else 'cmd.run_chroot' + cmd_all = __salt__[run_cmd]( + cmd=name, timeout=timeout, python_shell=True, **cmd_kwargs ) - except CommandExecutionError as err: + except Exception as err: ret['comment'] = six.text_type(err) return ret diff --git a/tests/unit/states/test_cmd.py b/tests/unit/states/test_cmd.py index 5c5ddb680427..34056bb7a033 100644 --- a/tests/unit/states/test_cmd.py +++ b/tests/unit/states/test_cmd.py @@ -148,6 +148,29 @@ def test_run(self): 'skip_watch': True}) self.assertDictEqual(cmd.run(name, onlyif=''), ret) + def test_run_root(self): + ''' + Test to run a command with a different root + ''' + name = 'cmd.script' + + ret = {'name': name, + 'result': False, + 'changes': {}, + 'comment': ''} + + with patch.dict(cmd.__grains__, {'shell': 'shell'}): + with patch.dict(cmd.__opts__, {'test': False}): + mock = MagicMock(side_effect=[CommandExecutionError, + {'retcode': 1}]) + with patch.dict(cmd.__salt__, {'cmd.run_chroot': mock}): + ret.update({'comment': '', 'result': False}) + self.assertDictEqual(cmd.run(name, root='/mnt'), ret) + + ret.update({'comment': 'Command "cmd.script" run', + 'result': False, 'changes': {'retcode': 1}}) + self.assertDictEqual(cmd.run(name, root='/mnt'), ret) + # 'script' function tests: 1 def test_script(self):