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(command=None,
49 network_disabled=False,
59 args_dict = docker_process_args(passed_args_dict, default_args_dict, "docker_create")
61 docker_client.images(name=docker_image_name)
62 docker_uid_dict = docker_client\
63 .create_container(docker_image_name, **args_dict)
64 docker_info = docker_client.inspect_container(docker_uid_dict.get("Id"))
68 def docker_start(docker_name, passed_args_dict=None):
69 """Start docker container.
72 :param docker_name: A string that describes the docker image to use.
73 Either the uid or docker container name must be used.
75 :param passed_args_dict: keyword docker-py start container args. defaults to binds=None,
76 port_bindings=None, lxc_conf=None, publish_all_ports=False,
77 links=None, privileged=False, dns=None, dns_search=None,
78 volumes_from=None, network_mode=None, restart_policy=None,
79 cap_add=None, cap_drop=None, devices=None, extra_hosts=None
81 :returns bool: returns false if container fails to start
84 logger.info("Starting docker %s" % docker_name)
85 logger.info(passed_args_dict)
86 docker_client = docker_get_client()
88 default_args_dict = dict(binds=None,
91 publish_all_ports=False,
104 args_dict = docker_process_args(passed_args_dict, default_args_dict, "docker_start")
106 docker_client.start(docker_name, **args_dict)
108 if "True" in str(docker_client.inspect_container(docker_name)
109 .get("State").get("Running")):
110 logger.info("Started docker %s successfully" % docker_name)
113 logger.info("Starting docker %s failed" % docker_name)
117 def docker_remove(docker_name, passed_args_dict=None):
118 """Remove docker container.
121 :param docker_name: A string that describes the docker image to use
122 example 'socketplane/openvswitch'
124 :param passed_args_dict: keyword docker-py remove container args. defaults to v=False,
125 link=False, force=False
128 :returns bool: True if container was removed false otherwise
130 logger.info("Removing docker %s" % docker_name)
131 logger.info(passed_args_dict)
132 docker_client = docker_get_client()
134 default_args_dict = dict(v=False,
138 args_dict = docker_process_args(passed_args_dict, default_args_dict, "docker_remove")
140 docker_client.remove_container(docker_name, **args_dict)
141 docker_containers = docker_client.containers(all=True)
142 for container in docker_containers:
143 if docker_name in container.get("Id") or docker_name in container.get("Names"):
144 logger.info("Removing docker %s failed" % docker_name)
146 logger.info("Removed docker %s successfully" % docker_name)
150 def docker_stop(docker_name, timeout=10):
151 """Stop docker container.
154 :param docker_name: A string that describes the docker image to use.
155 Either the uid or docker container name must be used.
157 :param timeout: docker-py stop container args. defaults to timeout=10
159 :returns bool: returns false if container fails to stop
162 logger.info("Stopping docker %s with timeout %d" % (docker_name, timeout))
163 docker_client = docker_get_client()
165 docker_client.stop(docker_name, timeout)
167 if "False" in str(docker_client.inspect_container(docker_name)
168 .get("State").get("Running")):
169 logger.info("Stopped docker %s successfully" % docker_name)
172 logger.debug("Stopping docker %s failed" % docker_name)
176 def docker_return_logs(docker_name, passed_args_dict=None):
177 """Return docker container logs.
180 :param docker_name: A string that describes the docker image to use.
181 Either the uid or docker container name must be used.
183 :param passed_args_dict: keyword docker-py logs container args. defaults to
184 stdout=True, stderr=True, stream=False, timestamps=False, tail='all'
186 :returns string: returns a string containing docker logs
188 logger.info("Returning logs for docker %s" % docker_name)
189 logger.info(passed_args_dict)
190 docker_client = docker_get_client()
192 default_args_dict = dict(stdout=True,
198 args_dict = docker_process_args(passed_args_dict, default_args_dict, "docker_return_logs")
200 return docker_client.logs(docker_name, **args_dict)
203 def docker_execute(docker_name, cmd, passed_args_dict=None):
204 """Run a command on a docker container.
207 :param docker_name: A string that describes the docker image to use.
208 Either the uid or docker container name must be used.
210 :param cmd: A string of the command to run
213 :param passed_args_dict: dictionary of key word
214 docker-py exec container args. defaults to detach=False,
215 stdout=True, stderr=True, stream=False, tty=False
217 :returns string: returns string representing the results of the command
219 NOTE: In docker-py version >=1.2 execute will be deprecated in
220 favor of exec_create and exec_start
222 logger.info("Executing command %s on docker %s" % (cmd, docker_name))
223 logger.info(passed_args_dict)
224 docker_client = docker_get_client()
226 default_args_dict = dict(detach=False,
232 args_dict = docker_process_args(passed_args_dict, default_args_dict, "docker_execute")
234 return docker_client.execute(docker_name, cmd, **args_dict)
237 def docker_get_ip4(docker_name):
238 """Inspects a docker container and returns its IP address.
241 :param docker_name: A string that describes the docker image to use.
242 Either the uid or docker container name must be used.
245 :returns string: returns string of IP address
247 logger.info("Getting IP of docker %s" % docker_name)
248 docker_client = docker_get_client()
249 return str(docker_client.inspect_container(docker_name)
250 .get("NetworkSettings")
254 def docker_ping(docker_name, ip, count=3):
255 """Pings from a docker container and returns results.
258 :param docker_name: A string that describes the docker image to use.
259 Either the uid or docker container name must be used.
261 :param ip: A string of the IP address to ping
263 :param count: An integer of the count to ping
266 :returns string: returns string of results
268 logger.info("Pinging from docker %s to %s %d times" % (docker_name, ip, count))
269 ping_cmd = str(ip) + "ping -c " + str(count)
270 return docker_execute(docker_name, ping_cmd)
273 def docker_list_containers(passed_args_dict=None):
274 """Return a list of docker containers.
277 :returns list: returns list of docker
278 containers in following format:
279 [{'Id': u'069a56ec06f965f98efa752467737faa58431ebb471bc51e9b2bd485fcc4916c'},
280 {'Id': u'769aff6170eec78e7c502fea4770cfbb7b7e53a2dc44070566d01e18b6d57c14'}]
282 logger.info("Listing docker containers")
283 logger.info(passed_args_dict)
285 default_args_dict = dict(quiet=True,
295 args_dict = docker_process_args(passed_args_dict, default_args_dict,
296 "docker_list_containers")
298 return docker.Client(
299 base_url='unix://var/run/docker.sock',
301 .containers(**args_dict)
304 def docker_create_host_config(passed_args_dict):
305 """Return a list of docker create host config for port bindings.
308 :param passed_args_dict: dictionary of the keyword values to use.
311 :returns list: returns host config for a container
312 create command in following format:
313 {'PortBindings': {'6640/tcp': [{'HostIp': '', 'HostPort': '6640'}],
314 '6653/tcp': [{'HostIp': '', 'HostPort': '6653'}],
315 '9001/tcp': [{'HostIp': '', 'HostPort': '9001'}]}}
317 logger.info("Creating host config.")
319 default_args_dict = dict(binds=None,
322 publish_all_ports=False,
335 args_dict = docker_process_args(passed_args_dict, default_args_dict,
336 "docker_create_host_config")
338 return docker.utils.create_host_config(**args_dict)
341 def docker_process_args(passed_args_dict, default_args_dict, method_name):
342 """Accepts two dicts and combines them preferring passed
343 args while filling unspecified args with default values.
346 :param passed_args_dict: A dict of the passed keyword args for the method.
348 :param default_args_dict: A dict of the default keyword args for the method.
351 :returns dict: returns dict containing passed args, with
352 defaults for all other keyword args.
354 logger.info("Processing args for %s method" % method_name)
355 logger.info(passed_args_dict)
356 logger.info(default_args_dict)
357 processed_args_dict = {}
359 if passed_args_dict is None:
360 passed_args_dict = {}
363 for key in default_args_dict:
364 if key in passed_args_dict:
365 processed_args_dict[key] = passed_args_dict[key]
367 processed_args_dict[key] = default_args_dict[key]
369 logger.debug("Error: One or both of the passed arguments is not a dictionary")
371 return processed_args_dict
374 def docker_get_client(*passed_args_dict):
375 """Returns docker-py client.
378 :param passed_args_dict: dictionary of the keyword values to use.
381 :returns obj: returns docker-py client object.
383 default_args_dict = dict(base_url="unix://var/run/docker.sock",
387 args_dict = docker_process_args(passed_args_dict, default_args_dict, "docker_get_client")
388 return docker.Client(**args_dict)