From ec727bbd931c8536b4f3cb1bf3f599432c063b3e Mon Sep 17 00:00:00 2001 From: Michael Calmer Date: Thu, 9 Feb 2017 12:44:43 +0100 Subject: [PATCH] support dryrun for dockerng.sls_build provide the possibility to put extra modules into the thin added unit test for dockerng.sls_build dryrun option --- salt/modules/dockerng.py | 29 +++++++++++-- tests/unit/modules/dockerng_test.py | 82 +++++++++++++++++++++++++++++++++++++ 2 files changed, 108 insertions(+), 3 deletions(-) diff --git a/salt/modules/dockerng.py b/salt/modules/dockerng.py index cbf2a6b397..bd0a208cac 100644 --- a/salt/modules/dockerng.py +++ b/salt/modules/dockerng.py @@ -5757,7 +5757,9 @@ def call(name, function, *args, **kwargs): raise CommandExecutionError('Missing function parameter') # move salt into the container - thin_path = salt.utils.thin.gen_thin(__opts__['cachedir']) + thin_path = salt.utils.thin.gen_thin(__opts__['cachedir'], + extra_mods=__salt__['config.option']("thin_extra_mods", ''), + so_mods=__salt__['config.option']("thin_so_mods", '')) with io.open(thin_path, 'rb') as file: _client_wrapper('put_archive', name, thin_dest_path, file) try: @@ -5867,7 +5869,7 @@ def sls(name, mods=None, saltenv='base', **kwargs): def sls_build(name, base='opensuse/python', mods=None, saltenv='base', - **kwargs): + dryrun=False, **kwargs): ''' Build a docker image using the specified sls modules and base image. @@ -5875,6 +5877,24 @@ def sls_build(name, base='opensuse/python', mods=None, saltenv='base', can build a docker image inside myminion that results of applying those states by doing: + base + the base image + + mods + the state modules to execute during build + + saltenv + the salt environment to use + + dryrun: False + when set to True the container will not be commited at the end of + the build. The dryrun succeed also when the state contains errors. + + **RETURN DATA** + + A dictionary with the ID of the new container. In case of a dryrun, + the state result is returned and the container gets removed. + CLI Example: .. code-block:: bash @@ -5907,9 +5927,12 @@ def sls_build(name, base='opensuse/python', mods=None, saltenv='base', # Now execute the state into the container ret = __salt__['dockerng.sls'](id_, mods, saltenv, **kwargs) # fail if the state was not successful - if not salt.utils.check_state_result(ret): + if not dryrun and not salt.utils.check_state_result(ret): raise CommandExecutionError(ret) finally: __salt__['dockerng.stop'](id_) + if dryrun: + __salt__['dockerng.rm'](id_) + return ret return __salt__['dockerng.commit'](id_, name) diff --git a/tests/unit/modules/dockerng_test.py b/tests/unit/modules/dockerng_test.py index ec4901e275..546635577a 100644 --- a/tests/unit/modules/dockerng_test.py +++ b/tests/unit/modules/dockerng_test.py @@ -680,6 +680,84 @@ class DockerngTestCase(TestCase): self.assertEqual( {'Id': 'ID2', 'Image': 'foo', 'Time_Elapsed': 42}, ret) + def test_sls_build_dryrun(self, *args): + ''' + test build sls image in dryrun mode. + ''' + docker_start_mock = MagicMock( + return_value={}) + docker_create_mock = MagicMock( + return_value={'Id': 'ID', 'Name': 'NAME'}) + docker_stop_mock = MagicMock( + return_value={'state': {'old': 'running', 'new': 'stopped'}, + 'result': True}) + docker_rm_mock = MagicMock( + return_value={}) + + docker_sls_mock = MagicMock( + return_value={ + "file_|-/etc/test.sh_|-/etc/test.sh_|-managed": { + "comment": "File /etc/test.sh is in the correct state", + "name": "/etc/test.sh", + "start_time": "07:04:26.834792", + "result": True, + "duration": 13.492, + "__run_num__": 0, + "changes": {} + }, + "test_|-always-passes_|-foo_|-succeed_without_changes": { + "comment": "Success!", + "name": "foo", + "start_time": "07:04:26.848915", + "result": True, + "duration": 0.363, + "__run_num__": 1, + "changes": {} + } + }) + + ret = None + with patch.dict(dockerng_mod.__salt__, { + 'dockerng.start': docker_start_mock, + 'dockerng.create': docker_create_mock, + 'dockerng.stop': docker_stop_mock, + 'dockerng.rm': docker_rm_mock, + 'dockerng.sls': docker_sls_mock}): + ret = dockerng_mod.sls_build( + 'foo', + mods='foo', + dryrun=True + ) + docker_create_mock.assert_called_once_with( + cmd='sleep infinity', + image='opensuse/python', interactive=True, name='foo', tty=True) + docker_start_mock.assert_called_once_with('ID') + docker_sls_mock.assert_called_once_with('ID', 'foo', 'base') + docker_stop_mock.assert_called_once_with('ID') + docker_rm_mock.assert_called_once_with('ID') + self.assertEqual( + { + "file_|-/etc/test.sh_|-/etc/test.sh_|-managed": { + "comment": "File /etc/test.sh is in the correct state", + "name": "/etc/test.sh", + "start_time": "07:04:26.834792", + "result": True, + "duration": 13.492, + "__run_num__": 0, + "changes": {} + }, + "test_|-always-passes_|-foo_|-succeed_without_changes": { + "comment": "Success!", + "name": "foo", + "start_time": "07:04:26.848915", + "result": True, + "duration": 0.363, + "__run_num__": 1, + "changes": {} + } + }, + ret) + def test_call_success(self): ''' test module calling inside containers @@ -694,6 +772,9 @@ class DockerngTestCase(TestCase): return_value={ 'retcode': 0 }) + docker_config_mock = MagicMock( + return_value='' + ) client = Mock() client.put_archive = Mock() @@ -704,6 +785,7 @@ class DockerngTestCase(TestCase): dockerng_mod.__salt__, { 'dockerng.run_all': docker_run_all_mock, 'dockerng.copy_to': docker_copy_to_mock, + 'config.option': docker_config_mock }), patch.dict( dockerng_mod.__context__, { -- 2.11.0