summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docker/api/image.py41
-rw-r--r--docker/api/service.py41
-rw-r--r--docker/auth/auth.py20
-rw-r--r--docker/types/services.py5
-rw-r--r--docs/api.md21
-rw-r--r--tests/integration/service_test.py1
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