tripleo-heat-templates/docker/docker-toool

203 lines
7.7 KiB
Python
Executable File

#!/usr/bin/env python
# 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 argparse
import os
import shutil
import sys
import json
docker_cmd = '/bin/docker'
# Tool to start docker containers as configured via
# tripleo-heat-templates.
#
# This tool reads data from a json file generated from heat when the
# TripleO stack is run. All the configuration data used to start the
# containerized services is in this file.
#
# By default this tool lists all the containers that are started and
# their start order.
#
# If you wish to see the command line used to start a given container,
# specify it by name using the --container argument. --run can then be
# used with this to actually execute docker to run the container.\n
#
# Other options listed allow you to modify this command line for
# debugging purposes. For example:
#
# docker-toool -c swift-proxy -r -e /bin/bash -u root -i -n test
#
# will run the swift proxy container as user root, executing /bin/bash,
#
# named 'test', and will run interactively (eg -ti).
def parse_opts(argv):
parser = argparse.ArgumentParser("Tool to start docker containers via "
"TripleO configurations")
parser.add_argument('-f', '--config',
help="""File to use as docker startup configuration data.""",
default='/var/lib/docker-container-startup-configs.json')
parser.add_argument('-r', '--run',
action='store_true',
help="""Run the container as specified with --container.""",
default=False)
parser.add_argument('-e', '--command',
help="""Override the command used to run the container.""",
default='')
parser.add_argument('-c', '--container',
help="""Specify a container to run or show the command for.""",
default='')
parser.add_argument('-u', '--user',
help="""User to run container as.""",
default='')
parser.add_argument('-n', '--name',
help="""Name of container.""",
default='')
parser.add_argument('-i', '--interactive',
action='store_true',
help="""Start docker container interactively (-ti).""",
default=False)
parser.add_argument('-d', '--detach',
action='store_true',
help="""Start container detached.""",
default=False)
opts = parser.parse_args(argv[1:])
return opts
def docker_arg_map(key, value):
value = str(value).encode('ascii', 'ignore')
if len(value) == 0:
return ''
return {
'environment': "--env=%s" % value,
# 'image': value,
'net': "--net=%s" % value,
'pid': "--pid=%s" % value,
'privileged': "--privileged=%s" % value.lower(),
'user': "--user=%s" % value,
'ulimit': "--ulimit=%s" % value,
'volumes': "--volume=%s" % value,
'volumes_from': "--volumes-from=%s" % value,
}.get(key, None)
def run_docker_container(opts, container_name):
container_found = False
with open(opts.config) as f:
json_data = json.load(f)
for step in (json_data or []):
if step is None:
continue
for container in (json_data[step] or []):
if container == container_name:
print('container found: %s' % container)
container_found = True
# A few positional arguments:
command = ''
image = ''
cmd = [
docker_cmd,
'run',
'--name',
opts.name or container
]
for container_data in (json_data[step][container] or []):
if container_data == "environment":
for env in (json_data[step][container][container_data] or []):
arg = docker_arg_map("environment", env)
if arg:
cmd.append(arg)
elif container_data == "ulimit":
for limit in (json_data[step][container][container_data] or []):
arg = docker_arg_map("ulimit", limit)
if arg:
cmd.append(arg)
elif container_data == "volumes":
for volume in (json_data[step][container][container_data] or []):
arg = docker_arg_map("volumes", volume)
if arg:
cmd.append(arg)
elif container_data == "volumes_from":
for volume in (json_data[step][container][container_data] or []):
arg = docker_arg_map("volumes_from", volume)
if arg:
cmd.append(arg)
elif container_data == 'command':
command = json_data[step][container][container_data]
elif container_data == 'image':
image = json_data[step][container][container_data]
else:
# Only add a restart if we're not interactive
if container_data == 'restart':
if opts.interactive:
continue
if container_data == 'user':
if opts.user:
continue
arg = docker_arg_map(container_data,
json_data[step][container][container_data])
if arg:
cmd.append(arg)
if opts.user:
cmd.append('--user')
cmd.append(opts.user)
if opts.detach:
cmd.append('--detach')
if opts.interactive:
cmd.append('-ti')
# May as well remove it when we're done too
cmd.append('--rm')
cmd.append(image)
if opts.command:
cmd.append(opts.command)
elif command:
cmd.extend(command)
print ' '.join(cmd)
if opts.run:
os.execl(docker_cmd, *cmd)
if not container_found:
print("Container '%s' not found!" % container_name)
def list_docker_containers(opts):
with open(opts.config) as f:
json_data = json.load(f)
for step in (json_data or []):
if step is None:
continue
for container in (json_data[step] or []):
print('\tcontainer: %s' % container)
for container_data in (json_data[step][container] or []):
if container_data == "start_order":
print('\t\tstart_order: %s' % json_data[step][container][container_data])
opts = parse_opts(sys.argv)
if opts.container:
run_docker_container(opts, opts.container)
else:
list_docker_containers(opts)