diff options
-rw-r--r-- | docker/api/image.py | 41 | ||||
-rw-r--r-- | docker/api/service.py | 41 | ||||
-rw-r--r-- | docker/auth/auth.py | 20 | ||||
-rw-r--r-- | docker/types/services.py | 5 | ||||
-rw-r--r-- | docs/api.md | 21 | ||||
-rw-r--r-- | tests/integration/service_test.py | 1 |
6 files changed, 91 insertions, 38 deletions
diff --git a/docker/api/image.py b/docker/api/image.py index 2bdbce8..4d6561e 100644 --- a/docker/api/image.py +++ b/docker/api/image.py @@ -166,28 +166,10 @@ class ImageApiMixin(object): headers = {} if utils.compare_version('1.5', self._version) >= 0: - # If we don't have any auth data so far, try reloading the config - # file one more time in case anything showed up in there. if auth_config is None: - log.debug('Looking for auth config') - if not self._auth_configs: - log.debug( - "No auth config in memory - loading from filesystem" - ) - self._auth_configs = auth.load_config() - authcfg = auth.resolve_authconfig(self._auth_configs, registry) - # Do not fail here if no authentication exists for this - # specific registry as we can have a readonly pull. Just - # put the header if we can. - if authcfg: - log.debug('Found auth config') - # auth_config needs to be a dict in the format used by - # auth.py username , password, serveraddress, email - headers['X-Registry-Auth'] = auth.encode_header( - authcfg - ) - else: - log.debug('No auth config found') + header = auth.get_config_header(self, registry) + if header: + headers['X-Registry-Auth'] = header else: log.debug('Sending supplied auth config') headers['X-Registry-Auth'] = auth.encode_header(auth_config) @@ -222,21 +204,10 @@ class ImageApiMixin(object): headers = {} if utils.compare_version('1.5', self._version) >= 0: - # If we don't have any auth data so far, try reloading the config - # file one more time in case anything showed up in there. if auth_config is None: - log.debug('Looking for auth config') - if not self._auth_configs: - log.debug( - "No auth config in memory - loading from filesystem" - ) - self._auth_configs = auth.load_config() - authcfg = auth.resolve_authconfig(self._auth_configs, registry) - # Do not fail here if no authentication exists for this - # specific registry as we can have a readonly pull. Just - # put the header if we can. - if authcfg: - headers['X-Registry-Auth'] = auth.encode_header(authcfg) + header = auth.get_config_header(self, registry) + if header: + headers['X-Registry-Auth'] = header else: log.debug('Sending supplied auth config') headers['X-Registry-Auth'] = auth.encode_header(auth_config) diff --git a/docker/api/service.py b/docker/api/service.py index c62e494..baebbad 100644 --- a/docker/api/service.py +++ b/docker/api/service.py @@ -1,4 +1,6 @@ +from .. import errors from .. import utils +from ..auth import auth class ServiceApiMixin(object): @@ -8,6 +10,16 @@ class ServiceApiMixin(object): update_config=None, networks=None, endpoint_config=None ): url = self._url('/services/create') + headers = {} + image = task_template.get('ContainerSpec', {}).get('Image', None) + if image is None: + raise errors.DockerException( + 'Missing mandatory Image key in ContainerSpec' + ) + registry, repo_name = auth.resolve_repository_name(image) + auth_header = auth.get_config_header(self, registry) + if auth_header: + headers['X-Registry-Auth'] = auth_header data = { 'Name': name, 'Labels': labels, @@ -17,7 +29,9 @@ class ServiceApiMixin(object): 'Networks': networks, 'Endpoint': endpoint_config } - return self._result(self._post_json(url, data=data), True) + return self._result( + self._post_json(url, data=data, headers=headers), True + ) @utils.minimum_version('1.24') @utils.check_resource @@ -27,6 +41,12 @@ class ServiceApiMixin(object): @utils.minimum_version('1.24') @utils.check_resource + def inspect_task(self, task): + url = self._url('/tasks/{0}', task) + return self._result(self._get(url), True) + + @utils.minimum_version('1.24') + @utils.check_resource def remove_service(self, service): url = self._url('/services/{0}', service) resp = self._delete(url) @@ -42,12 +62,21 @@ class ServiceApiMixin(object): return self._result(self._get(url, params=params), True) @utils.minimum_version('1.24') + def tasks(self, filters=None): + params = { + 'filters': utils.convert_filters(filters) if filters else None + } + url = self._url('/tasks') + return self._result(self._get(url, params=params), True) + + @utils.minimum_version('1.24') @utils.check_resource def update_service(self, service, version, task_template=None, name=None, labels=None, mode=None, update_config=None, networks=None, endpoint_config=None): url = self._url('/services/{0}/update', service) data = {} + headers = {} if name is not None: data['Name'] = name if labels is not None: @@ -55,6 +84,12 @@ class ServiceApiMixin(object): if mode is not None: data['Mode'] = mode if task_template is not None: + image = task_template.get('ContainerSpec', {}).get('Image', None) + if image is not None: + registry, repo_name = auth.resolve_repository_name(image) + auth_header = auth.get_config_header(self, registry) + if auth_header: + headers['X-Registry-Auth'] = auth_header data['TaskTemplate'] = task_template if update_config is not None: data['UpdateConfig'] = update_config @@ -63,6 +98,8 @@ class ServiceApiMixin(object): if endpoint_config is not None: data['Endpoint'] = endpoint_config - resp = self._post_json(url, data=data, params={'version': version}) + resp = self._post_json( + url, data=data, params={'version': version}, headers=headers + ) self._raise_for_status(resp) return True diff --git a/docker/auth/auth.py b/docker/auth/auth.py index b61a8d0..7195f56 100644 --- a/docker/auth/auth.py +++ b/docker/auth/auth.py @@ -51,6 +51,26 @@ def resolve_index_name(index_name): return index_name +def get_config_header(client, registry): + log.debug('Looking for auth config') + if not client._auth_configs: + log.debug( + "No auth config in memory - loading from filesystem" + ) + client._auth_configs = load_config() + authcfg = resolve_authconfig(client._auth_configs, registry) + # Do not fail here if no authentication exists for this + # specific registry as we can have a readonly pull. Just + # put the header if we can. + if authcfg: + log.debug('Found auth config') + # auth_config needs to be a dict in the format used by + # auth.py username , password, serveraddress, email + return encode_header(authcfg) + log.debug('No auth config found') + return None + + def split_repo_name(repo_name): parts = repo_name.split('/', 1) if len(parts) == 1 or ( diff --git a/docker/types/services.py b/docker/types/services.py index dcc84f9..2c1a830 100644 --- a/docker/types/services.py +++ b/docker/types/services.py @@ -36,7 +36,12 @@ class TaskTemplate(dict): class ContainerSpec(dict): def __init__(self, image, command=None, args=None, env=None, workdir=None, user=None, labels=None, mounts=None, stop_grace_period=None): + from ..utils import split_command # FIXME: circular import + self['Image'] = image + + if isinstance(command, six.string_types): + command = split_command(command) self['Command'] = command self['Args'] = args diff --git a/docs/api.md b/docs/api.md index 12467ed..5857892 100644 --- a/docs/api.md +++ b/docs/api.md @@ -666,6 +666,16 @@ Create a service, similar to the `docker service create` command. See the Retrieve information about the current Swarm. See the [Swarm documentation](swarm.md#clientinspect_swarm). +## inspect_task + +Retrieve information about a task. + +**Params**: + +* task (str): Task identifier + +**Returns** (dict): Task information dictionary + ## inspect_volume Retrieve volume info by name. @@ -1055,6 +1065,17 @@ Tag an image into a repository. Identical to the `docker tag` command. **Returns** (bool): True if successful +## tasks + +Retrieve a list of tasks. + +**Params**: + +* filters (dict): A map of filters to process on the tasks list. Valid filters: + `id`, `name`, `service`, `node`, `label` and `desired-state`. + +**Returns** (list): List of task dictionaries. + ## top Display the running processes of a container. diff --git a/tests/integration/service_test.py b/tests/integration/service_test.py index 3113df1..2b99316 100644 --- a/tests/integration/service_test.py +++ b/tests/integration/service_test.py @@ -1,7 +1,6 @@ import random import docker -# import pytest from ..base import requires_api_version from .. import helpers |