Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docker/api/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@
from .daemon import DaemonApiMixin
from .exec_api import ExecApiMixin
from .image import ImageApiMixin
from .volume import VolumeApiMixin
4 changes: 2 additions & 2 deletions docker/api/build.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@

from .. import constants
from .. import errors
from ..auth import auth
from ..utils import utils
from .. import auth
from .. import utils


log = logging.getLogger(__name__)
Expand Down
54 changes: 24 additions & 30 deletions docker/api/container.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
import warnings

from .. import errors
from ..utils import utils, check_resource
from .. import utils


class ContainerApiMixin(object):
@check_resource
@utils.check_resource
def attach(self, container, stdout=True, stderr=True,
stream=False, logs=False):
params = {
Expand All @@ -20,7 +20,7 @@ def attach(self, container, stdout=True, stderr=True,

return self._get_result(container, stream, response)

@check_resource
@utils.check_resource
def attach_socket(self, container, params=None, ws=False):
if params is None:
params = {
Expand All @@ -36,7 +36,7 @@ def attach_socket(self, container, params=None, ws=False):
return self._get_raw_response_socket(self.post(
u, None, params=self._attach_params(params), stream=True))

@check_resource
@utils.check_resource
def commit(self, container, repository=None, tag=None, message=None,
author=None, conf=None):
params = {
Expand Down Expand Up @@ -73,7 +73,7 @@ def containers(self, quiet=False, all=False, trunc=False, latest=False,
x['Id'] = x['Id'][:12]
return res

@check_resource
@utils.check_resource
def copy(self, container, resource):
res = self._post_json(
self._url("/containers/{0}/copy".format(container)),
Expand Down Expand Up @@ -131,27 +131,27 @@ def create_host_config(self, *args, **kwargs):
kwargs['version'] = self._version
return utils.create_host_config(*args, **kwargs)

@check_resource
@utils.check_resource
def diff(self, container):
return self._result(
self._get(self._url("/containers/{0}/changes", container)), True
)

@check_resource
@utils.check_resource
def export(self, container):
res = self._get(
self._url("/containers/{0}/export", container), stream=True
)
self._raise_for_status(res)
return res.raw

@check_resource
@utils.check_resource
def inspect_container(self, container):
return self._result(
self._get(self._url("/containers/{0}/json", container)), True
)

@check_resource
@utils.check_resource
def kill(self, container, signal=None):
url = self._url("/containers/{0}/kill", container)
params = {}
Expand All @@ -161,7 +161,7 @@ def kill(self, container, signal=None):

self._raise_for_status(res)

@check_resource
@utils.check_resource
def logs(self, container, stdout=True, stderr=True, stream=False,
timestamps=False, tail='all'):
if utils.compare_version('1.11', self._version) >= 0:
Expand All @@ -185,13 +185,13 @@ def logs(self, container, stdout=True, stderr=True, stream=False,
logs=True
)

@check_resource
@utils.check_resource
def pause(self, container):
url = self._url('/containers/{0}/pause', container)
res = self._post(url)
self._raise_for_status(res)

@check_resource
@utils.check_resource
def port(self, container, private_port):
res = self._get(self._url("/containers/{0}/json", container))
self._raise_for_status(res)
Expand All @@ -211,40 +211,37 @@ def port(self, container, private_port):

return h_ports

@check_resource
@utils.check_resource
def remove_container(self, container, v=False, link=False, force=False):
params = {'v': v, 'link': link, 'force': force}
res = self._delete(
self._url("/containers/{0}", container), params=params
)
self._raise_for_status(res)

@check_resource
@utils.minimum_version('1.17')
@utils.check_resource
def rename(self, container, name):
if utils.compare_version('1.17', self._version) < 0:
raise errors.InvalidVersion(
'rename was only introduced in API version 1.17'
)
url = self._url("/containers/{0}/rename", container)
params = {'name': name}
res = self._post(url, params=params)
self._raise_for_status(res)

@check_resource
@utils.check_resource
def resize(self, container, height, width):
params = {'h': height, 'w': width}
url = self._url("/containers/{0}/resize", container)
res = self._post(url, params=params)
self._raise_for_status(res)

@check_resource
@utils.check_resource
def restart(self, container, timeout=10):
params = {'t': timeout}
url = self._url("/containers/{0}/restart", container)
res = self._post(url, params=params)
self._raise_for_status(res)

@check_resource
@utils.check_resource
def start(self, container, binds=None, port_bindings=None, lxc_conf=None,
publish_all_ports=None, links=None, privileged=None,
dns=None, dns_search=None, volumes_from=None, network_mode=None,
Expand Down Expand Up @@ -312,16 +309,13 @@ def start(self, container, binds=None, port_bindings=None, lxc_conf=None,
res = self._post_json(url, data=start_config)
self._raise_for_status(res)

@check_resource
@utils.minimum_version('1.17')
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This new decorator is great!

@utils.check_resource
def stats(self, container, decode=None):
if utils.compare_version('1.17', self._version) < 0:
raise errors.InvalidVersion(
'Stats retrieval is not supported in API < 1.17!')

url = self._url("/containers/{0}/stats", container)
return self._stream_helper(self._get(url, stream=True), decode=decode)

@check_resource
@utils.check_resource
def stop(self, container, timeout=10):
params = {'t': timeout}
url = self._url("/containers/{0}/stop", container)
Expand All @@ -330,18 +324,18 @@ def stop(self, container, timeout=10):
timeout=(timeout + (self.timeout or 0)))
self._raise_for_status(res)

@check_resource
@utils.check_resource
def top(self, container):
u = self._url("/containers/{0}/top", container)
return self._result(self._get(u), True)

@check_resource
@utils.check_resource
def unpause(self, container):
url = self._url('/containers/{0}/unpause', container)
res = self._post(url)
self._raise_for_status(res)

@check_resource
@utils.check_resource
def wait(self, container, timeout=None):
url = self._url("/containers/{0}/wait", container)
res = self._post(url, timeout=timeout)
Expand Down
18 changes: 6 additions & 12 deletions docker/api/exec_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,14 @@
import six

from .. import errors
from ..utils import utils, check_resource
from .. import utils


class ExecApiMixin(object):
@check_resource
@utils.minimum_version('1.15')
@utils.check_resource
def exec_create(self, container, cmd, stdout=True, stderr=True, tty=False,
privileged=False, user=''):
if utils.compare_version('1.15', self._version) < 0:
raise errors.InvalidVersion('Exec is not supported in API < 1.15')
if privileged and utils.compare_version('1.19', self._version) < 0:
raise errors.InvalidVersion(
'Privileged exec is not supported in API < 1.19'
Expand All @@ -38,19 +37,15 @@ def exec_create(self, container, cmd, stdout=True, stderr=True, tty=False,
res = self._post_json(url, data=data)
return self._result(res, True)

@utils.minimum_version('1.16')
def exec_inspect(self, exec_id):
if utils.compare_version('1.16', self._version) < 0:
raise errors.InvalidVersion(
'exec_inspect is not supported in API < 1.16'
)
if isinstance(exec_id, dict):
exec_id = exec_id.get('Id')
res = self._get(self._url("/exec/{0}/json", exec_id))
return self._result(res, True)

@utils.minimum_version('1.15')
def exec_resize(self, exec_id, height=None, width=None):
if utils.compare_version('1.15', self._version) < 0:
raise errors.InvalidVersion('Exec is not supported in API < 1.15')
if isinstance(exec_id, dict):
exec_id = exec_id.get('Id')

Expand All @@ -59,9 +54,8 @@ def exec_resize(self, exec_id, height=None, width=None):
res = self._post(url, params=params)
self._raise_for_status(res)

@utils.minimum_version('1.15')
def exec_start(self, exec_id, detach=False, tty=False, stream=False):
if utils.compare_version('1.15', self._version) < 0:
raise errors.InvalidVersion('Exec is not supported in API < 1.15')
if isinstance(exec_id, dict):
exec_id = exec_id.get('Id')

Expand Down
14 changes: 7 additions & 7 deletions docker/api/image.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,21 @@

from ..auth import auth
from ..constants import INSECURE_REGISTRY_DEPRECATION_WARNING
from ..utils import utils, check_resource
from .. import utils
from .. import errors

log = logging.getLogger(__name__)


class ImageApiMixin(object):

@check_resource
@utils.check_resource
def get_image(self, image):
res = self._get(self._url("/images/{0}/get", image), stream=True)
self._raise_for_status(res)
return res.raw

@check_resource
@utils.check_resource
def history(self, image):
res = self._get(self._url("/images/{0}/history", image))
return self._result(res, True)
Expand Down Expand Up @@ -124,7 +124,7 @@ def import_image_from_image(self, image, repository=None, tag=None):
return self._result(
self._post(u, data=None, params=params))

@check_resource
@utils.check_resource
def insert(self, image, url, path):
if utils.compare_version('1.12', self._version) >= 0:
raise errors.DeprecatedMethod(
Expand All @@ -137,7 +137,7 @@ def insert(self, image, url, path):
}
return self._result(self._post(api_url, params=params))

@check_resource
@utils.check_resource
def inspect_image(self, image):
return self._result(
self._get(self._url("/images/{0}/json", image)), True
Expand Down Expand Up @@ -246,7 +246,7 @@ def push(self, repository, tag=None, stream=False,

return self._result(response)

@check_resource
@utils.check_resource
def remove_image(self, image, force=False, noprune=False):
params = {'force': force, 'noprune': noprune}
res = self._delete(self._url("/images/{0}", image), params=params)
Expand All @@ -258,7 +258,7 @@ def search(self, term):
True
)

@check_resource
@utils.check_resource
def tag(self, image, repository, tag=None, force=False):
params = {
'tag': tag,
Expand Down
36 changes: 36 additions & 0 deletions docker/api/volume.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
from .. import utils


class VolumeApiMixin(object):
@utils.minimum_version('1.21')
def volumes(self, filters=None):
params = {
'filter': utils.convert_filters(filters) if filters else None
}
url = self._url('/volumes')
return self._result(self._get(url, params=params), True)

@utils.minimum_version('1.21')
def create_volume(self, name, driver=None, driver_opts=None):
url = self._url('/volumes')
if driver_opts is not None and not isinstance(driver_opts, dict):
raise TypeError('driver_opts must be a dictionary')

data = {
'Name': name,
'Driver': driver,
'DriverOpts': driver_opts,
}
return self._result(self._post_json(url, data=data), True)

@utils.minimum_version('1.21')
def inspect_volume(self, name):
url = self._url('/volumes/{0}', name)
return self._result(self._get(url), True)

@utils.minimum_version('1.21')
def remove_volume(self, name):
url = self._url('/volumes/{0}', name)
resp = self._delete(url)
self._raise_for_status(resp)
return True
3 changes: 2 additions & 1 deletion docker/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ class Client(
api.ContainerApiMixin,
api.DaemonApiMixin,
api.ExecApiMixin,
api.ImageApiMixin):
api.ImageApiMixin,
api.VolumeApiMixin):
def __init__(self, base_url=None, version=None,
timeout=constants.DEFAULT_TIMEOUT_SECONDS, tls=False):
super(Client, self).__init__()
Expand Down
5 changes: 3 additions & 2 deletions docker/utils/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@
compare_version, convert_port_bindings, convert_volume_binds,
mkbuildcontext, tar, exclude_paths, parse_repository_tag, parse_host,
kwargs_from_env, convert_filters, create_host_config,
create_container_config, parse_bytes, ping_registry, parse_env_file
create_container_config, parse_bytes, ping_registry, parse_env_file,
version_lt, version_gte
) # flake8: noqa

from .types import Ulimit, LogConfig # flake8: noqa
from .decorators import check_resource #flake8: noqa
from .decorators import check_resource, minimum_version #flake8: noqa
Loading