Add support of labels parameter for dockerng

This commit is contained in:
Nicolas Delaby 2015-10-02 15:39:57 +02:00
parent e47d849af6
commit edf625c8b4
4 changed files with 235 additions and 0 deletions

View File

@ -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**

View File

@ -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

View File

@ -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

View File

@ -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