2 Docker library for OpenDaylight project robot system test framework.
3 Authors: Marcus Williams - irc @ mgkwill - Intel Inc.
6 *Copyright (c) 2015 Intel Corp. and others. All rights reserved.
8 * This program and the accompanying materials are made available under the
9 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
10 * and is available at http://www.eclipse.org/legal/epl-v10.html
14 from robot.api import logger
17 def docker_create(docker_image_name, passed_args_dict=None):
20 :param docker_image_name: A string that describes the docker image to use
21 example 'socketplane/openvswitch'
23 :param passed_args_dict: keyword docker-py create container args. defaults to command=None,
24 hostname=None, user=None, detach=False, stdin_open=False, tty=False,
25 mem_limit=0, ports=None, environment=None, dns=None, volumes=None,
26 volumes_from=None, network_disabled=False, name=None, entrypoint=None,
27 cpu_shares=None, working_dir=None, domainname=None, memswap_limit=0,
28 cpuset=None, host_config=None
31 :returns dict: docker-info - identifying info about docker container created
33 logger.info("Creating docker %s" % docker_image_name)
34 logger.info(passed_args_dict)
35 docker_client = docker_get_client()
37 default_args_dict = dict(
50 network_disabled=False,
60 args_dict = docker_process_args(
61 passed_args_dict, default_args_dict, "docker_create"
64 docker_client.images(name=docker_image_name)
65 docker_uid_dict = docker_client.create_container(docker_image_name, **args_dict)
66 docker_info = docker_client.inspect_container(docker_uid_dict.get("Id"))
70 def docker_start(docker_name, passed_args_dict=None):
71 """Start docker container.
74 :param docker_name: A string that describes the docker image to use.
75 Either the uid or docker container name must be used.
77 :param passed_args_dict: keyword docker-py start container args. defaults to binds=None,
78 port_bindings=None, lxc_conf=None, publish_all_ports=False,
79 links=None, privileged=False, dns=None, dns_search=None,
80 volumes_from=None, network_mode=None, restart_policy=None,
81 cap_add=None, cap_drop=None, devices=None, extra_hosts=None
83 :returns bool: returns false if container fails to start
86 logger.info("Starting docker %s" % docker_name)
87 logger.info(passed_args_dict)
88 docker_client = docker_get_client()
90 default_args_dict = dict(
94 publish_all_ports=False,
107 args_dict = docker_process_args(passed_args_dict, default_args_dict, "docker_start")
109 docker_client.start(docker_name, **args_dict)
112 docker_client.inspect_container(docker_name).get("State").get("Running")
114 logger.info("Started docker %s successfully" % docker_name)
117 logger.info("Starting docker %s failed" % docker_name)
121 def docker_remove(docker_name, passed_args_dict=None):
122 """Remove docker container.
125 :param docker_name: A string that describes the docker image to use
126 example 'socketplane/openvswitch'
128 :param passed_args_dict: keyword docker-py remove container args. defaults to v=False,
129 link=False, force=False
132 :returns bool: True if container was removed false otherwise
134 logger.info("Removing docker %s" % docker_name)
135 logger.info(passed_args_dict)
136 docker_client = docker_get_client()
138 default_args_dict = dict(v=False, link=False, force=False)
139 args_dict = docker_process_args(
140 passed_args_dict, default_args_dict, "docker_remove"
143 docker_client.remove_container(docker_name, **args_dict)
144 docker_containers = docker_client.containers(all=True)
145 for container in docker_containers:
146 if docker_name in container.get("Id") or docker_name in container.get("Names"):
147 logger.info("Removing docker %s failed" % docker_name)
149 logger.info("Removed docker %s successfully" % docker_name)
153 def docker_stop(docker_name, timeout=10):
154 """Stop docker container.
157 :param docker_name: A string that describes the docker image to use.
158 Either the uid or docker container name must be used.
160 :param timeout: docker-py stop container args. defaults to timeout=10
162 :returns bool: returns false if container fails to stop
165 logger.info("Stopping docker %s with timeout %d" % (docker_name, timeout))
166 docker_client = docker_get_client()
168 docker_client.stop(docker_name, timeout)
171 docker_client.inspect_container(docker_name).get("State").get("Running")
173 logger.info("Stopped docker %s successfully" % docker_name)
176 logger.debug("Stopping docker %s failed" % docker_name)
180 def docker_return_logs(docker_name, passed_args_dict=None):
181 """Return docker container logs.
184 :param docker_name: A string that describes the docker image to use.
185 Either the uid or docker container name must be used.
187 :param passed_args_dict: keyword docker-py logs container args. defaults to
188 stdout=True, stderr=True, stream=False, timestamps=False, tail='all'
190 :returns string: returns a string containing docker logs
192 logger.info("Returning logs for docker %s" % docker_name)
193 logger.info(passed_args_dict)
194 docker_client = docker_get_client()
196 default_args_dict = dict(
197 stdout=True, stderr=True, stream=False, timestamps=False, tail="all"
199 args_dict = docker_process_args(
200 passed_args_dict, default_args_dict, "docker_return_logs"
203 return docker_client.logs(docker_name, **args_dict)
206 def docker_execute(docker_name, cmd, passed_args_dict=None):
207 """Run a command on a docker container.
210 :param docker_name: A string that describes the docker image to use.
211 Either the uid or docker container name must be used.
213 :param cmd: A string of the command to run
216 :param passed_args_dict: dictionary of key word
217 docker-py exec container args. defaults to detach=False,
218 stdout=True, stderr=True, stream=False, tty=False
220 :returns string: returns string representing the results of the command
222 NOTE: In docker-py version >=1.2 execute will be deprecated in
223 favor of exec_create and exec_start
225 logger.info("Executing command %s on docker %s" % (cmd, docker_name))
226 logger.info(passed_args_dict)
227 docker_client = docker_get_client()
229 default_args_dict = dict(
230 detach=False, stdout=True, stderr=True, stream=False, tty=False
232 args_dict = docker_process_args(
233 passed_args_dict, default_args_dict, "docker_execute"
236 return docker_client.execute(docker_name, cmd, **args_dict)
239 def docker_get_ip4(docker_name):
240 """Inspects a docker container and returns its IP address.
243 :param docker_name: A string that describes the docker image to use.
244 Either the uid or docker container name must be used.
247 :returns string: returns string of IP address
249 logger.info("Getting IP of docker %s" % docker_name)
250 docker_client = docker_get_client()
252 docker_client.inspect_container(docker_name)
253 .get("NetworkSettings")
258 def docker_ping(docker_name, ip, count=3):
259 """Pings from a docker container and returns results.
262 :param docker_name: A string that describes the docker image to use.
263 Either the uid or docker container name must be used.
265 :param ip: A string of the IP address to ping
267 :param count: An integer of the count to ping
270 :returns string: returns string of results
272 logger.info("Pinging from docker %s to %s %d times" % (docker_name, ip, count))
273 ping_cmd = str(ip) + "ping -c " + str(count)
274 return docker_execute(docker_name, ping_cmd)
277 def docker_list_containers(passed_args_dict=None):
278 """Return a list of docker containers.
281 :returns list: returns list of docker
282 containers in following format:
283 [{'Id': u'069a56ec06f965f98efa752467737faa58431ebb471bc51e9b2bd485fcc4916c'},
284 {'Id': u'769aff6170eec78e7c502fea4770cfbb7b7e53a2dc44070566d01e18b6d57c14'}]
286 logger.info("Listing docker containers")
287 logger.info(passed_args_dict)
289 default_args_dict = dict(
300 args_dict = docker_process_args(
301 passed_args_dict, default_args_dict, "docker_list_containers"
304 return docker.Client(base_url="unix://var/run/docker.sock", timeout=10).containers(
309 def docker_create_host_config(passed_args_dict):
310 """Return a list of docker create host config for port bindings.
313 :param passed_args_dict: dictionary of the keyword values to use.
316 :returns list: returns host config for a container
317 create command in following format:
318 {'PortBindings': {'6640/tcp': [{'HostIp': '', 'HostPort': '6640'}],
319 '6653/tcp': [{'HostIp': '', 'HostPort': '6653'}],
320 '9001/tcp': [{'HostIp': '', 'HostPort': '9001'}]}}
322 logger.info("Creating host config.")
324 default_args_dict = dict(
328 publish_all_ports=False,
341 args_dict = docker_process_args(
342 passed_args_dict, default_args_dict, "docker_create_host_config"
345 return docker.utils.create_host_config(**args_dict)
348 def docker_process_args(passed_args_dict, default_args_dict, method_name):
349 """Accepts two dicts and combines them preferring passed
350 args while filling unspecified args with default values.
353 :param passed_args_dict: A dict of the passed keyword args for the method.
355 :param default_args_dict: A dict of the default keyword args for the method.
358 :returns dict: returns dict containing passed args, with
359 defaults for all other keyword args.
361 logger.info("Processing args for %s method" % method_name)
362 logger.info(passed_args_dict)
363 logger.info(default_args_dict)
364 processed_args_dict = {}
366 if passed_args_dict is None:
367 passed_args_dict = {}
370 for key in default_args_dict:
371 if key in passed_args_dict:
372 processed_args_dict[key] = passed_args_dict[key]
374 processed_args_dict[key] = default_args_dict[key]
376 logger.debug("Error: One or both of the passed arguments is not a dictionary")
378 return processed_args_dict
381 def docker_get_client(*passed_args_dict):
382 """Returns docker-py client.
385 :param passed_args_dict: dictionary of the keyword values to use.
388 :returns obj: returns docker-py client object.
390 default_args_dict = dict(
391 base_url="unix://var/run/docker.sock", version=None, timeout=10, tls=False
393 args_dict = docker_process_args(
394 passed_args_dict, default_args_dict, "docker_get_client"
396 return docker.Client(**args_dict)