mirror of
https://github.com/valitydev/salt.git
synced 2024-11-07 17:09:03 +00:00
Add support of labels
parameter for dockerng
This commit is contained in:
parent
e47d849af6
commit
edf625c8b4
@ -417,6 +417,9 @@ VALID_CREATE_OPTS = {
|
||||
'cpuset': {
|
||||
'path': 'Config:Cpuset',
|
||||
},
|
||||
'labels': {
|
||||
'path': 'Config:Labels',
|
||||
},
|
||||
}
|
||||
|
||||
VALID_RUNTIME_OPTS = {
|
||||
@ -1110,6 +1113,13 @@ def _validate_input(action,
|
||||
for x in kwargs[key]]):
|
||||
raise SaltInvocationError(key + ' must be a list of strings')
|
||||
|
||||
def _valid_dictlist(key): # pylint: disable=unused-variable
|
||||
'''
|
||||
Ensure the passed value is a list of dictionaries.
|
||||
'''
|
||||
if not salt.utils.is_dictlist(kwargs[key]):
|
||||
raise SaltInvocationError(key + ' must be a list of dictionaries.')
|
||||
|
||||
# Custom validation functions for container creation options
|
||||
def _valid_command(): # pylint: disable=unused-variable
|
||||
'''
|
||||
@ -1644,6 +1654,32 @@ def _validate_input(action,
|
||||
'pid_mode can only be \'host\', if set'
|
||||
)
|
||||
|
||||
def _valid_labels(): # pylint: disable=unused-variable
|
||||
'''
|
||||
Must be a dict or a list of strings
|
||||
'''
|
||||
if kwargs.get('labels') is None:
|
||||
return
|
||||
try:
|
||||
_valid_stringlist('labels')
|
||||
except SaltInvocationError:
|
||||
try:
|
||||
_valid_dictlist('labels')
|
||||
except SaltInvocationError:
|
||||
try:
|
||||
_valid_dict('labels')
|
||||
except SaltInvocationError:
|
||||
raise SaltInvocationError(
|
||||
'labels can only be a list of strings/dict'
|
||||
' or a dict containing strings')
|
||||
else:
|
||||
new_labels = {}
|
||||
for k, v in six.iteritems(kwargs['labels']):
|
||||
new_labels[str(k)] = str(v)
|
||||
kwargs['labels'] = new_labels
|
||||
else:
|
||||
kwargs['labels'] = salt.utils.repack_dictlist(kwargs['labels'])
|
||||
|
||||
# And now, the actual logic to perform the validation
|
||||
if action == 'create':
|
||||
valid_opts = VALID_CREATE_OPTS
|
||||
@ -2640,6 +2676,12 @@ def create(image,
|
||||
|
||||
This is only used if Salt needs to pull the requested image.
|
||||
|
||||
labels
|
||||
Add Metadata to the container. Can be a list of strings/dictionaries
|
||||
or a dictionary of strings (keys and values).
|
||||
|
||||
Example: ``labels=LABEL1,LABEL2``,
|
||||
``labels="{'LABEL1': 'value1', 'LABEL2': 'value2'}"``
|
||||
|
||||
**RETURN DATA**
|
||||
|
||||
|
@ -1349,6 +1349,37 @@ def running(name,
|
||||
|
||||
This option requires Docker 1.5.0 or newer.
|
||||
|
||||
labels
|
||||
Add Metadata to the container. Can be a list of strings/dictionaries
|
||||
or a dictionary of strings (keys and values).
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
foo:
|
||||
dockerng.running:
|
||||
- image: bar/baz:latest
|
||||
- labels:
|
||||
- LABEL1
|
||||
- LABEL2
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
foo:
|
||||
dockerng.running:
|
||||
- image: bar/baz:latest
|
||||
- labels:
|
||||
KEY1: VALUE1
|
||||
KEY2: VALUE2
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
foo:
|
||||
dockerng.running:
|
||||
- image: bar/baz:latest
|
||||
- labels:
|
||||
- KEY1: VALUE1
|
||||
- KEY2: VALUE2
|
||||
|
||||
start : True
|
||||
Set to ``False`` to suppress starting of the container if it exists,
|
||||
matches the desired configuration, but is not running. This is useful
|
||||
|
@ -21,6 +21,7 @@ ensure_in_syspath('../../')
|
||||
|
||||
# Import Salt Libs
|
||||
from salt.modules import dockerng as dockerng_mod
|
||||
from salt.exceptions import SaltInvocationError
|
||||
|
||||
dockerng_mod.__context__ = {'docker.docker_version': ''}
|
||||
dockerng_mod.__salt__ = {}
|
||||
@ -139,6 +140,141 @@ class DockerngTestCase(TestCase):
|
||||
image='image',
|
||||
name='ctn')
|
||||
|
||||
@skipIf(_docker_py_version() < (1, 4, 0),
|
||||
'docker module must be installed to run this test or is too old. >=1.4.0')
|
||||
@patch.object(dockerng_mod, 'images', MagicMock())
|
||||
@patch.object(dockerng_mod, 'inspect_image')
|
||||
@patch.object(dockerng_mod, 'version', Mock(return_value={'ApiVersion': '1.19'}))
|
||||
def test_create_with_labels_dict(self, *args):
|
||||
'''
|
||||
Create container with labels dictionary.
|
||||
'''
|
||||
__salt__ = {
|
||||
'config.get': Mock(),
|
||||
'mine.send': Mock(),
|
||||
}
|
||||
host_config = {}
|
||||
client = Mock()
|
||||
client.api_version = '1.19'
|
||||
client.create_host_config.return_value = host_config
|
||||
client.create_container.return_value = {}
|
||||
with patch.dict(dockerng_mod.__dict__,
|
||||
{'__salt__': __salt__}):
|
||||
with patch.dict(dockerng_mod.__context__,
|
||||
{'docker.client': client}):
|
||||
dockerng_mod.create(
|
||||
'image',
|
||||
name='ctn',
|
||||
labels={'KEY': 'VALUE'},
|
||||
validate_input=True,
|
||||
)
|
||||
client.create_container.assert_called_once_with(
|
||||
labels={'KEY': 'VALUE'},
|
||||
host_config=host_config,
|
||||
image='image',
|
||||
name='ctn',
|
||||
)
|
||||
|
||||
@skipIf(_docker_py_version() < (1, 4, 0),
|
||||
'docker module must be installed to run this test or is too old. >=1.4.0')
|
||||
@patch.object(dockerng_mod, 'images', MagicMock())
|
||||
@patch.object(dockerng_mod, 'inspect_image')
|
||||
@patch.object(dockerng_mod, 'version', Mock(return_value={'ApiVersion': '1.19'}))
|
||||
def test_create_with_labels_list(self, *args):
|
||||
'''
|
||||
Create container with labels list.
|
||||
'''
|
||||
__salt__ = {
|
||||
'config.get': Mock(),
|
||||
'mine.send': Mock(),
|
||||
}
|
||||
host_config = {}
|
||||
client = Mock()
|
||||
client.api_version = '1.19'
|
||||
client.create_host_config.return_value = host_config
|
||||
client.create_container.return_value = {}
|
||||
with patch.dict(dockerng_mod.__dict__,
|
||||
{'__salt__': __salt__}):
|
||||
with patch.dict(dockerng_mod.__context__,
|
||||
{'docker.client': client}):
|
||||
dockerng_mod.create(
|
||||
'image',
|
||||
name='ctn',
|
||||
labels=['KEY1', 'KEY2'],
|
||||
validate_input=True,
|
||||
)
|
||||
client.create_container.assert_called_once_with(
|
||||
labels=['KEY1', 'KEY2'],
|
||||
host_config=host_config,
|
||||
image='image',
|
||||
name='ctn',
|
||||
)
|
||||
|
||||
@skipIf(_docker_py_version() < (1, 4, 0),
|
||||
'docker module must be installed to run this test or is too old. >=1.4.0')
|
||||
@patch.object(dockerng_mod, 'images', MagicMock())
|
||||
@patch.object(dockerng_mod, 'inspect_image')
|
||||
@patch.object(dockerng_mod, 'version', Mock(return_value={'ApiVersion': '1.19'}))
|
||||
def test_create_with_labels_error(self, *args):
|
||||
'''
|
||||
Create container with invalid labels.
|
||||
'''
|
||||
__salt__ = {
|
||||
'config.get': Mock(),
|
||||
'mine.send': Mock(),
|
||||
}
|
||||
host_config = {}
|
||||
client = Mock()
|
||||
client.api_version = '1.19'
|
||||
client.create_host_config.return_value = host_config
|
||||
client.create_container.return_value = {}
|
||||
with patch.dict(dockerng_mod.__dict__,
|
||||
{'__salt__': __salt__}):
|
||||
with patch.dict(dockerng_mod.__context__,
|
||||
{'docker.client': client}):
|
||||
self.assertRaises(SaltInvocationError,
|
||||
dockerng_mod.create,
|
||||
'image',
|
||||
name='ctn',
|
||||
labels=22,
|
||||
validate_input=True,
|
||||
)
|
||||
|
||||
@skipIf(_docker_py_version() < (1, 4, 0),
|
||||
'docker module must be installed to run this test or is too old. >=1.4.0')
|
||||
@patch.object(dockerng_mod, 'images', MagicMock())
|
||||
@patch.object(dockerng_mod, 'inspect_image')
|
||||
@patch.object(dockerng_mod, 'version', Mock(return_value={'ApiVersion': '1.19'}))
|
||||
def test_create_with_labels_dictlist(self, *args):
|
||||
'''
|
||||
Create container with labels dictlist.
|
||||
'''
|
||||
__salt__ = {
|
||||
'config.get': Mock(),
|
||||
'mine.send': Mock(),
|
||||
}
|
||||
host_config = {}
|
||||
client = Mock()
|
||||
client.api_version = '1.19'
|
||||
client.create_host_config.return_value = host_config
|
||||
client.create_container.return_value = {}
|
||||
with patch.dict(dockerng_mod.__dict__,
|
||||
{'__salt__': __salt__}):
|
||||
with patch.dict(dockerng_mod.__context__,
|
||||
{'docker.client': client}):
|
||||
dockerng_mod.create(
|
||||
'image',
|
||||
name='ctn',
|
||||
labels=[{'KEY1': 'VALUE1'}, {'KEY2': 'VALUE2'}],
|
||||
validate_input=True,
|
||||
)
|
||||
client.create_container.assert_called_once_with(
|
||||
labels={'KEY1': 'VALUE1', 'KEY2': 'VALUE2'},
|
||||
host_config=host_config,
|
||||
image='image',
|
||||
name='ctn',
|
||||
)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
from integration import run_tests
|
||||
|
@ -434,6 +434,32 @@ class DockerngTestCase(TestCase):
|
||||
'name': 'cont',
|
||||
'result': False})
|
||||
|
||||
def test_running_with_labels(self):
|
||||
'''
|
||||
Test dockerng.running with labels parameter.
|
||||
'''
|
||||
dockerng_create = Mock()
|
||||
__salt__ = {'dockerng.list_containers': MagicMock(),
|
||||
'dockerng.list_tags': MagicMock(),
|
||||
'dockerng.pull': MagicMock(),
|
||||
'dockerng.state': MagicMock(),
|
||||
'dockerng.inspect_image': MagicMock(),
|
||||
'dockerng.create': dockerng_create,
|
||||
}
|
||||
with patch.dict(dockerng_state.__dict__,
|
||||
{'__salt__': __salt__}):
|
||||
dockerng_state.running(
|
||||
'cont',
|
||||
image='image:latest',
|
||||
labels=['LABEL1', 'LABEL2'],
|
||||
)
|
||||
dockerng_create.assert_called_with(
|
||||
'image:latest',
|
||||
validate_input=False,
|
||||
name='cont',
|
||||
labels=['LABEL1', 'LABEL2'],
|
||||
client_timeout=60)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
from integration import run_tests
|
||||
|
Loading…
Reference in New Issue
Block a user