Change flat network name for nosdn fdio scenario
[apex-tripleo-heat-templates.git] / docker / docker-toool
1 #!/usr/bin/env python
2 #    Licensed under the Apache License, Version 2.0 (the "License"); you may
3 #    not use this file except in compliance with the License. You may obtain
4 #    a copy of the License at
5 #
6 #         http://www.apache.org/licenses/LICENSE-2.0
7 #
8 #    Unless required by applicable law or agreed to in writing, software
9 #    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
10 #    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
11 #    License for the specific language governing permissions and limitations
12 #    under the License.
13
14 import argparse
15 import os
16 import shutil
17 import sys
18 import json
19
20 docker_cmd = '/bin/docker'
21
22 # Tool to start docker containers as configured via
23 # tripleo-heat-templates.
24 #
25 # This tool reads data from a json file generated from heat when the
26 # TripleO stack is run.  All the configuration data used to start the
27 # containerized services is in this file.
28 #
29 # By default this tool lists all the containers that are started and
30 # their start order.
31 #
32 # If you wish to see the command line used to start a given container,
33 # specify it by name using the --container argument.  --run can then be
34 # used with this to actually execute docker to run the container.\n
35 #
36 # Other options listed allow you to modify this command line for
37 # debugging purposes.  For example:
38 #
39 # docker-toool -c swift-proxy -r -e /bin/bash -u root -i -n test
40 #
41 # will run the swift proxy container as user root, executing /bin/bash,
42 #
43 # named 'test', and will run interactively (eg -ti).
44
45
46 def parse_opts(argv):
47     parser = argparse.ArgumentParser("Tool to start docker containers via "
48                                      "TripleO configurations")
49     parser.add_argument('-f', '--config',
50                         help="""File to use as docker startup configuration data.""",
51                         default='/var/lib/docker-container-startup-configs.json')
52     parser.add_argument('-r', '--run',
53                         action='store_true',
54                         help="""Run the container as specified with --container.""",
55                         default=False)
56     parser.add_argument('-e', '--command',
57                         help="""Override the command used to run the container.""",
58                         default='')
59     parser.add_argument('-c', '--container',
60                         help="""Specify a container to run or show the command for.""",
61                         default='')
62     parser.add_argument('-u', '--user',
63                         help="""User to run container as.""",
64                         default='')
65     parser.add_argument('-n', '--name',
66                         help="""Name of container.""",
67                         default='')
68     parser.add_argument('-i', '--interactive',
69                         action='store_true',
70                         help="""Start docker container interactively (-ti).""",
71                         default=False)
72     parser.add_argument('-d', '--detach',
73                         action='store_true',
74                         help="""Start container detached.""",
75                         default=False)
76     opts = parser.parse_args(argv[1:])
77
78     return opts
79
80
81 def docker_arg_map(key, value):
82     value = str(value).encode('ascii', 'ignore')
83     if len(value) == 0:
84         return ''
85
86     return {
87         'environment': "--env=%s" % value,
88         # 'image': value,
89         'net': "--net=%s" % value,
90         'pid': "--pid=%s" % value,
91         'privileged': "--privileged=%s" % value.lower(),
92         'user': "--user=%s" % value,
93         'volumes': "--volume=%s" % value,
94         'volumes_from': "--volumes-from=%s" % value,
95     }.get(key, None)
96
97
98 def run_docker_container(opts, container_name):
99     container_found = False
100
101     with open(opts.config) as f:
102         json_data = json.load(f)
103
104     for step in (json_data or []):
105         if step is None:
106             continue
107         for container in (json_data[step] or []):
108             if container == container_name:
109                 print('container found: %s' % container)
110                 container_found = True
111                 # A few positional arguments:
112                 command = ''
113                 image = ''
114
115                 cmd = [
116                     docker_cmd,
117                     'run',
118                     '--name',
119                     opts.name or container
120                 ]
121                 for container_data in (json_data[step][container] or []):
122                     if container_data == "environment":
123                         for env in (json_data[step][container][container_data] or []):
124                             arg = docker_arg_map("environment", env)
125                             if arg:
126                                 cmd.append(arg)
127                     elif container_data == "volumes":
128                         for volume in (json_data[step][container][container_data] or []):
129                             arg = docker_arg_map("volumes", volume)
130                             if arg:
131                                 cmd.append(arg)
132                     elif container_data == "volumes_from":
133                         for volume in (json_data[step][container][container_data] or []):
134                             arg = docker_arg_map("volumes_from", volume)
135                             if arg:
136                                 cmd.append(arg)
137                     elif container_data == 'command':
138                         command = json_data[step][container][container_data]
139                     elif container_data == 'image':
140                         image = json_data[step][container][container_data]
141                     else:
142                         # Only add a restart if we're not interactive
143                         if container_data == 'restart':
144                             if opts.interactive:
145                                 continue
146                         if container_data == 'user':
147                             if opts.user:
148                                 continue
149                         arg = docker_arg_map(container_data,
150                                              json_data[step][container][container_data])
151                         if arg:
152                             cmd.append(arg)
153
154                 if opts.user:
155                     cmd.append('--user')
156                     cmd.append(opts.user)
157                 if opts.detach:
158                     cmd.append('--detach')
159                 if opts.interactive:
160                     cmd.append('-ti')
161                     # May as well remove it when we're done too
162                     cmd.append('--rm')
163                 cmd.append(image)
164                 if opts.command:
165                     cmd.append(opts.command)
166                 elif command:
167                     cmd.extend(command)
168
169                 print ' '.join(cmd)
170
171                 if opts.run:
172                     os.execl(docker_cmd, *cmd)
173
174     if not container_found:
175         print("Container '%s' not found!" % container_name)
176
177
178 def list_docker_containers(opts):
179     with open(opts.config) as f:
180         json_data = json.load(f)
181
182     for step in (json_data or []):
183         if step is None:
184             continue
185         for container in (json_data[step] or []):
186             print('\tcontainer: %s' % container)
187             for container_data in (json_data[step][container] or []):
188                 if container_data == "start_order":
189                     print('\t\tstart_order: %s' % json_data[step][container][container_data])
190
191 opts = parse_opts(sys.argv)
192
193 if opts.container:
194     run_docker_container(opts, opts.container)
195 else:
196     list_docker_containers(opts)