comparison env/lib/python3.9/site-packages/galaxy/tool_util/deps/docker_util.py @ 0:4f3585e2f14b draft default tip

"planemo upload commit 60cee0fc7c0cda8592644e1aad72851dec82c959"
author shellac
date Mon, 22 Mar 2021 18:12:50 +0000
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:4f3585e2f14b
1 """Utilities for building up Docker commands...
2
3 ...using common defaults and configuration mechanisms.
4 """
5 import os
6 import shlex
7
8 from galaxy.util.commands import argv_to_str
9
10 DEFAULT_DOCKER_COMMAND = "docker"
11 DEFAULT_SUDO = False
12 DEFAULT_SUDO_COMMAND = "sudo"
13 DEFAULT_HOST = None
14 DEFAULT_VOLUME_MOUNT_TYPE = "rw"
15 DEFAULT_WORKING_DIRECTORY = None
16 DEFAULT_NET = None
17 DEFAULT_MEMORY = None
18 DEFAULT_VOLUMES_FROM = None
19 DEFAULT_AUTO_REMOVE = True
20 DEFAULT_SET_USER = "$UID"
21 DEFAULT_RUN_EXTRA_ARGUMENTS = None
22
23
24 def kill_command(
25 container,
26 signal=None,
27 **kwds
28 ):
29 args = (["-s", signal] if signal else []) + [container]
30 return command_list("kill", args, **kwds)
31
32
33 def logs_command(
34 container,
35 **kwds
36 ):
37 return command_list("logs", [container], **kwds)
38
39
40 def build_command(
41 image,
42 docker_build_path,
43 **kwds
44 ):
45 if os.path.isfile(docker_build_path):
46 docker_build_path = os.path.dirname(os.path.abspath(docker_build_path))
47 return command_list("build", ["-t", image, docker_build_path], **kwds)
48
49
50 def build_save_image_command(
51 image,
52 destination,
53 **kwds
54 ):
55 return command_list("save", ["-o", destination, image], **kwds)
56
57
58 def build_pull_command(
59 tag,
60 **kwds
61 ):
62 return command_list("pull", [tag], **kwds)
63
64
65 def build_docker_cache_command(
66 image,
67 **kwds
68 ):
69 inspect_image_command = command_shell("inspect", [image], **kwds)
70 pull_image_command = command_shell("pull", [image], **kwds)
71 cache_command = f"{inspect_image_command} > /dev/null 2>&1\n[ $? -ne 0 ] && {pull_image_command} > /dev/null 2>&1\n"
72 return cache_command
73
74
75 def build_docker_images_command(truncate=True, **kwds):
76 args = ["--no-trunc"] if not truncate else[]
77 return command_shell("images", args, **kwds)
78
79
80 def build_docker_load_command(**kwds):
81 return command_shell("load", [])
82
83
84 def build_docker_simple_command(
85 command,
86 docker_cmd=DEFAULT_DOCKER_COMMAND,
87 sudo=DEFAULT_SUDO,
88 sudo_cmd=DEFAULT_SUDO_COMMAND,
89 container_name=None,
90 **kwd
91 ):
92 command_parts = _docker_prefix(
93 docker_cmd=docker_cmd,
94 sudo=sudo,
95 sudo_cmd=sudo_cmd,
96 )
97 command_parts.append(command)
98 command_parts.append(container_name or '{CONTAINER_NAME}')
99 return " ".join(command_parts)
100
101
102 def build_docker_run_command(
103 container_command,
104 image,
105 interactive=False,
106 terminal=False,
107 tag=None,
108 volumes=None,
109 volumes_from=DEFAULT_VOLUMES_FROM,
110 memory=DEFAULT_MEMORY,
111 env_directives=None,
112 working_directory=DEFAULT_WORKING_DIRECTORY,
113 name=None,
114 net=DEFAULT_NET,
115 run_extra_arguments=DEFAULT_RUN_EXTRA_ARGUMENTS,
116 docker_cmd=DEFAULT_DOCKER_COMMAND,
117 sudo=DEFAULT_SUDO,
118 sudo_cmd=DEFAULT_SUDO_COMMAND,
119 auto_rm=DEFAULT_AUTO_REMOVE,
120 set_user=DEFAULT_SET_USER,
121 host=DEFAULT_HOST,
122 guest_ports=False,
123 container_name=None
124 ):
125 env_directives = env_directives or []
126 volumes = volumes or []
127 command_parts = _docker_prefix(
128 docker_cmd=docker_cmd,
129 sudo=sudo,
130 sudo_cmd=sudo_cmd,
131 host=host
132 )
133 command_parts.append("run")
134 if interactive:
135 command_parts.append("-i")
136 if terminal:
137 command_parts.append("-t")
138 for env_directive in env_directives:
139 # e.g. -e "GALAXY_SLOTS=$GALAXY_SLOTS"
140 # These are environment variable expansions so we don't quote these.
141 command_parts.extend(["-e", env_directive])
142 if guest_ports is True:
143 # When is True, expose all ports
144 command_parts.append("-P")
145 elif guest_ports:
146 if not isinstance(guest_ports, list):
147 guest_ports = [guest_ports]
148 for guest_port in guest_ports:
149 command_parts.extend(["-p", guest_port])
150 if container_name:
151 command_parts.extend(["--name", container_name])
152 for volume in volumes:
153 command_parts.extend(["-v", str(volume)])
154 if volumes_from:
155 command_parts.extend(["--volumes-from", shlex.quote(str(volumes_from))])
156 if memory:
157 command_parts.extend(["-m", shlex.quote(memory)])
158 command_parts.extend(["--cpus", '${GALAXY_SLOTS:-1}'])
159 if name:
160 command_parts.extend(["--name", shlex.quote(name)])
161 if working_directory:
162 command_parts.extend(["-w", shlex.quote(working_directory)])
163 if net:
164 command_parts.extend(["--net", shlex.quote(net)])
165 if auto_rm:
166 command_parts.append("--rm")
167 if run_extra_arguments:
168 command_parts.append(run_extra_arguments)
169 if set_user:
170 user = set_user
171 if set_user == DEFAULT_SET_USER:
172 # If future-us is ever in here and fixing this for docker-machine just
173 # use cwltool.docker_id - it takes care of this default nicely.
174 euid = os.geteuid()
175 egid = os.getgid()
176
177 user = "%d:%d" % (euid, egid)
178 command_parts.extend(["--user", user])
179 full_image = image
180 if tag:
181 full_image = f"{full_image}:{tag}"
182 command_parts.append(shlex.quote(full_image))
183 command_parts.append(container_command)
184 return " ".join(command_parts)
185
186
187 def command_list(command, command_args=None, **kwds):
188 """Return Docker command as an argv list."""
189 command_args = command_args or []
190 command_parts = _docker_prefix(**kwds)
191 command_parts.append(command)
192 command_parts.extend(command_args)
193 return command_parts
194
195
196 def command_shell(command, command_args=None, **kwds):
197 """Return Docker command as a string for a shell or command-list."""
198 command_args = command_args or []
199 cmd = command_list(command, command_args, **kwds)
200 to_str = kwds.get("to_str", True)
201 if to_str:
202 return argv_to_str(cmd)
203 else:
204 return cmd
205
206
207 def _docker_prefix(
208 docker_cmd=DEFAULT_DOCKER_COMMAND,
209 sudo=DEFAULT_SUDO,
210 sudo_cmd=DEFAULT_SUDO_COMMAND,
211 host=DEFAULT_HOST,
212 **kwds
213 ):
214 """Prefix to issue a docker command."""
215 command_parts = []
216 if sudo:
217 command_parts.append(sudo_cmd)
218 command_parts.append(docker_cmd)
219 if host:
220 command_parts.extend(["-H", host])
221 return command_parts
222
223
224 def parse_port_text(port_text):
225 """
226
227 >>> slurm_ports = parse_port_text("8888/tcp -> 0.0.0.0:32769")
228 >>> slurm_ports[8888]['host']
229 '0.0.0.0'
230 """
231 ports = None
232 if port_text is not None:
233 ports = {}
234 for line in port_text.strip().split('\n'):
235 if " -> " not in line:
236 raise Exception("Cannot parse host and port from line [%s]" % line)
237 tool, host = line.split(" -> ", 1)
238 hostname, port = host.split(':')
239 port = int(port)
240 tool_p, tool_prot = tool.split("/")
241 tool_p = int(tool_p)
242 ports[tool_p] = dict(tool_port=tool_p, host=hostname, port=port, protocol=tool_prot)
243 return ports