Write out a json file containing container startup info and create tool to use it.
This adds a bit to the post.yaml for docker to write out a json file containing all the information on how we are start docker containers (thanks Dan!). I've then written a script that parses this that can be used to execute docker run commands in various ways for debugging purposes. Change-Id: I36d66b42d1ac5030db8841820d4fc512a71d1285 Co-Authored-by: Dan Prince <dprince@redhat.com>
This commit is contained in:
parent
5be125e117
commit
27b6188779
189
docker/docker-toool
Executable file
189
docker/docker-toool
Executable file
@ -0,0 +1,189 @@
|
|||||||
|
#!/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)
|
||||||
|
opts = parser.parse_args(argv[1:])
|
||||||
|
|
||||||
|
return opts
|
||||||
|
|
||||||
|
def docker_arg_map(key, value):
|
||||||
|
value = str(value).encode('ascii', 'ignore')
|
||||||
|
return {
|
||||||
|
'environment': "--env=%s" % value,
|
||||||
|
# 'image': value,
|
||||||
|
'net': "--net=%s" % value,
|
||||||
|
'pid': "--pid=%s" % value,
|
||||||
|
'privileged': "--privileged=%s" % value.lower(),
|
||||||
|
#'restart': "--restart=%s" % "false",
|
||||||
|
'user': "--user=%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 == "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.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):
|
||||||
|
print opts
|
||||||
|
with open(opts.config) as f:
|
||||||
|
json_data = json.load(f)
|
||||||
|
|
||||||
|
for step in (json_data or []):
|
||||||
|
if step is None:
|
||||||
|
continue
|
||||||
|
print step
|
||||||
|
for container in (json_data[step] or []):
|
||||||
|
print('\tcontainer: %s' % container)
|
||||||
|
for container_data in (json_data[step][container] or []):
|
||||||
|
#print('\t\tcontainer_data: %s' % container_data)
|
||||||
|
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)
|
||||||
|
|
@ -187,6 +187,24 @@ resources:
|
|||||||
docker_config: {get_param: [role_data, {{role.name}}, docker_config]}
|
docker_config: {get_param: [role_data, {{role.name}}, docker_config]}
|
||||||
docker_image: {get_param: [role_data, {{role.name}}, docker_image]}
|
docker_image: {get_param: [role_data, {{role.name}}, docker_image]}
|
||||||
|
|
||||||
|
# Here we are dumping all the docker container startup configuration data
|
||||||
|
# so that we can have access to how they are started outside of heat
|
||||||
|
# and docker-cmd. This lets us create command line tools to start and
|
||||||
|
# test these containers.
|
||||||
|
{{role.name}}DockerConfigJsonStartupData:
|
||||||
|
type: OS::Heat::StructuredConfig
|
||||||
|
properties:
|
||||||
|
group: json-file
|
||||||
|
config:
|
||||||
|
/var/lib/docker-container-startup-configs.json:
|
||||||
|
{get_attr: [{{role.name}}DockerConfig, value]}
|
||||||
|
|
||||||
|
{{role.name}}DockerConfigJsonStartupDataDeployment:
|
||||||
|
type: OS::Heat::SoftwareDeploymentGroup
|
||||||
|
properties:
|
||||||
|
config: {get_resource: {{role.name}}DockerConfigJsonStartupData}
|
||||||
|
servers: {get_param: [servers, {{role.name}}]}
|
||||||
|
|
||||||
{{role.name}}KollaJsonConfig:
|
{{role.name}}KollaJsonConfig:
|
||||||
type: OS::Heat::StructuredConfig
|
type: OS::Heat::StructuredConfig
|
||||||
properties:
|
properties:
|
||||||
|
Loading…
Reference in New Issue
Block a user