# Copyright (c) 2013 dotCloud, Inc. # Copyright 2014 IBM Corp. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import functools import inspect from oslo_config import cfg import six from docker import client from docker import tls CONF = cfg.CONF DEFAULT_TIMEOUT_SECONDS = 120 DEFAULT_DOCKER_API_VERSION = '1.19' def filter_data(f): """Decorator that post-processes data returned by Docker. This will avoid any surprises with different versions of Docker. """ @functools.wraps(f, assigned=[]) def wrapper(*args, **kwds): out = f(*args, **kwds) def _filter(obj): if isinstance(obj, list): new_list = [] for o in obj: new_list.append(_filter(o)) obj = new_list if isinstance(obj, dict): for k, v in obj.items(): if isinstance(k, six.string_types): obj[k.lower()] = _filter(v) return obj return _filter(out) return wrapper class DockerHTTPClient(client.Client): def __init__(self, url='unix://var/run/docker.sock'): if (CONF.docker.cert_file or CONF.docker.key_file): client_cert = (CONF.docker.cert_file, CONF.docker.key_file) else: client_cert = None if (CONF.docker.ca_file or CONF.docker.api_insecure or client_cert): ssl_config = tls.TLSConfig( client_cert=client_cert, ca_cert=CONF.docker.ca_file, verify=CONF.docker.api_insecure) else: ssl_config = False super(DockerHTTPClient, self).__init__( base_url=url, version=DEFAULT_DOCKER_API_VERSION, timeout=DEFAULT_TIMEOUT_SECONDS, tls=ssl_config ) self._setup_decorators() def _setup_decorators(self): for name, member in inspect.getmembers(self, inspect.ismethod): if not name.startswith('_'): setattr(self, name, filter_data(member)) def pause(self, container_id): url = self._url("/containers/{0}/pause".format(container_id)) res = self._post(url) return res.status_code == 204 def unpause(self, container_id): url = self._url("/containers/{0}/unpause".format(container_id)) res = self._post(url) return res.status_code == 204 def load_repository_file(self, name, path): with open(path, 'rb') as fh: self.load_image(fh) def get_container_logs(self, container_id): return self.attach(container_id, 1, 1, 0, 1)