docker-cmd hook switch to the paunch library
paunch is a library and utility which is now in OpenStack under the TripleO umbrella. It contains the logic currently in the docker-cmd hook exposed as a python library and command utility. This change switches the docker-cmd hook to paunch. Asserting --label arguments has been split out from the other docker run arguments so that paunch can add new --label arguments in future releases without breaking these tests. paunch-1.1.0 has just been release which contains new idempotency behaviour, so the tests have been modified to work with the new docker command behaviour that idempotency requires. Change-Id: I884c38ade06ab0e01432837c43f29b123e65fa3c
This commit is contained in:
parent
3a86f8789c
commit
33241a84c1
|
@ -1,4 +1,5 @@
|
||||||
A hook which uses the `docker` command to deploy containers.
|
A hook which uses the `docker` command via
|
||||||
|
`paunch <https://docs.openstack.org/developer/paunch/>`_ to deploy containers.
|
||||||
|
|
||||||
The hook currently supports specifying containers in the `docker-compose v1
|
The hook currently supports specifying containers in the `docker-compose v1
|
||||||
format <https://docs.docker.com/compose/compose-file/#/version-1>`_. The
|
format <https://docs.docker.com/compose/compose-file/#/version-1>`_. The
|
||||||
|
|
|
@ -12,15 +12,14 @@
|
||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
|
import collections
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
import random
|
|
||||||
import string
|
|
||||||
import subprocess
|
|
||||||
import sys
|
import sys
|
||||||
import yaml
|
|
||||||
|
|
||||||
|
import paunch
|
||||||
|
import yaml
|
||||||
|
|
||||||
DOCKER_CMD = os.environ.get('HEAT_DOCKER_CMD', 'docker')
|
DOCKER_CMD = os.environ.get('HEAT_DOCKER_CMD', 'docker')
|
||||||
|
|
||||||
|
@ -36,135 +35,6 @@ def build_response(deploy_stdout, deploy_stderr, deploy_status_code):
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def docker_run_args(cmd, container, config):
|
|
||||||
cconfig = config[container]
|
|
||||||
if cconfig.get('detach', True):
|
|
||||||
cmd.append('--detach=true')
|
|
||||||
if 'env_file' in cconfig:
|
|
||||||
if isinstance(cconfig['env_file'], list):
|
|
||||||
for f in cconfig.get('env_file', []):
|
|
||||||
if f:
|
|
||||||
cmd.append('--env-file=%s' % f)
|
|
||||||
else:
|
|
||||||
cmd.append('--env-file=%s' % cconfig['env_file'])
|
|
||||||
for v in cconfig.get('environment', []):
|
|
||||||
if v:
|
|
||||||
cmd.append('--env=%s' % v)
|
|
||||||
if 'net' in cconfig:
|
|
||||||
cmd.append('--net=%s' % cconfig['net'])
|
|
||||||
if 'pid' in cconfig:
|
|
||||||
cmd.append('--pid=%s' % cconfig['pid'])
|
|
||||||
if 'privileged' in cconfig:
|
|
||||||
cmd.append('--privileged=%s' % str(cconfig['privileged']).lower())
|
|
||||||
if 'restart' in cconfig:
|
|
||||||
cmd.append('--restart=%s' % cconfig['restart'])
|
|
||||||
if 'user' in cconfig:
|
|
||||||
cmd.append('--user=%s' % cconfig['user'])
|
|
||||||
for v in cconfig.get('volumes', []):
|
|
||||||
if v:
|
|
||||||
cmd.append('--volume=%s' % v)
|
|
||||||
for v in cconfig.get('volumes_from', []):
|
|
||||||
if v:
|
|
||||||
cmd.append('--volumes_from=%s' % v)
|
|
||||||
|
|
||||||
cmd.append(cconfig.get('image', ''))
|
|
||||||
cmd.extend(command_argument(cmd, cconfig.get('command')))
|
|
||||||
|
|
||||||
|
|
||||||
def docker_exec_args(cmd, container, config, cid):
|
|
||||||
cconfig = config[container]
|
|
||||||
if 'privileged' in cconfig:
|
|
||||||
cmd.append('--privileged=%s' % str(cconfig['privileged']).lower())
|
|
||||||
if 'user' in cconfig:
|
|
||||||
cmd.append('--user=%s' % cconfig['user'])
|
|
||||||
command = command_argument(cmd, cconfig.get('command'))
|
|
||||||
# for exec, the first argument is the container name,
|
|
||||||
# make sure the correct one is used
|
|
||||||
command[0] = discover_container_name(command[0], cid)
|
|
||||||
cmd.extend(command)
|
|
||||||
|
|
||||||
|
|
||||||
def command_argument(cmd, command):
|
|
||||||
if not command:
|
|
||||||
return []
|
|
||||||
if not isinstance(command, list):
|
|
||||||
return command.split()
|
|
||||||
return command
|
|
||||||
|
|
||||||
|
|
||||||
def execute(cmd):
|
|
||||||
log.debug(' '.join(cmd))
|
|
||||||
subproc = subprocess.Popen(cmd, stdout=subprocess.PIPE,
|
|
||||||
stderr=subprocess.PIPE)
|
|
||||||
cmd_stdout, cmd_stderr = subproc.communicate()
|
|
||||||
log.debug(cmd_stdout)
|
|
||||||
log.debug(cmd_stderr)
|
|
||||||
return cmd_stdout, cmd_stderr, subproc.returncode
|
|
||||||
|
|
||||||
|
|
||||||
def label_arguments(cmd, container, cid, iv):
|
|
||||||
cmd.extend([
|
|
||||||
'--label',
|
|
||||||
'deploy_stack_id=%s' % iv.get('deploy_stack_id'),
|
|
||||||
'--label',
|
|
||||||
'deploy_resource_name=%s' % iv.get('deploy_resource_name'),
|
|
||||||
'--label',
|
|
||||||
'config_id=%s' % cid,
|
|
||||||
'--label',
|
|
||||||
'container_name=%s' % container,
|
|
||||||
'--label',
|
|
||||||
'managed_by=docker-cmd'
|
|
||||||
])
|
|
||||||
|
|
||||||
|
|
||||||
def inspect(container, format=None):
|
|
||||||
cmd = [DOCKER_CMD, 'inspect']
|
|
||||||
if format:
|
|
||||||
cmd.append('--format')
|
|
||||||
cmd.append(format)
|
|
||||||
cmd.append(container)
|
|
||||||
(cmd_stdout, cmd_stderr, returncode) = execute(cmd)
|
|
||||||
if returncode != 0:
|
|
||||||
return
|
|
||||||
try:
|
|
||||||
if format:
|
|
||||||
return cmd_stdout
|
|
||||||
else:
|
|
||||||
return json.loads(cmd_stdout)[0]
|
|
||||||
except Exception as e:
|
|
||||||
log.error('Problem parsing docker inspect: %s' % e)
|
|
||||||
|
|
||||||
|
|
||||||
def unique_container_name(container):
|
|
||||||
container_name = container
|
|
||||||
while inspect(container_name, format='exists'):
|
|
||||||
suffix = ''.join(random.choice(
|
|
||||||
string.ascii_lowercase + string.digits) for i in range(8))
|
|
||||||
container_name = '%s-%s' % (container, suffix)
|
|
||||||
return container_name
|
|
||||||
|
|
||||||
|
|
||||||
def discover_container_name(container, cid):
|
|
||||||
cmd = [
|
|
||||||
DOCKER_CMD,
|
|
||||||
'ps',
|
|
||||||
'-a',
|
|
||||||
'--filter',
|
|
||||||
'label=container_name=%s' % container,
|
|
||||||
'--filter',
|
|
||||||
'label=config_id=%s' % cid,
|
|
||||||
'--format',
|
|
||||||
'{{.Names}}'
|
|
||||||
]
|
|
||||||
(cmd_stdout, cmd_stderr, returncode) = execute(cmd)
|
|
||||||
if returncode != 0:
|
|
||||||
return container
|
|
||||||
names = cmd_stdout.split()
|
|
||||||
if names:
|
|
||||||
return names[0]
|
|
||||||
return container
|
|
||||||
|
|
||||||
|
|
||||||
def main(argv=sys.argv):
|
def main(argv=sys.argv):
|
||||||
global log
|
global log
|
||||||
log = logging.getLogger('heat-config')
|
log = logging.getLogger('heat-config')
|
||||||
|
@ -200,36 +70,16 @@ def main(argv=sys.argv):
|
||||||
if not isinstance(config, dict):
|
if not isinstance(config, dict):
|
||||||
config = yaml.safe_load(config)
|
config = yaml.safe_load(config)
|
||||||
|
|
||||||
key_fltr = lambda k: config[k].get('start_order', 0)
|
labels = collections.OrderedDict()
|
||||||
for container in sorted(config, key=key_fltr):
|
labels['deploy_stack_id'] = input_values.get('deploy_stack_id')
|
||||||
log.debug("Running container: %s" % container)
|
labels['deploy_resource_name'] = input_values.get('deploy_resource_name')
|
||||||
action = config[container].get('action', 'run')
|
(stdout, stderr, deploy_status_code) = paunch.apply(
|
||||||
exit_codes = config[container].get('exit_codes', [0])
|
cid,
|
||||||
|
config,
|
||||||
if action == 'run':
|
managed_by='docker-cmd',
|
||||||
cmd = [
|
labels=labels,
|
||||||
DOCKER_CMD,
|
docker_cmd=DOCKER_CMD
|
||||||
'run',
|
)
|
||||||
'--name',
|
|
||||||
unique_container_name(container)
|
|
||||||
]
|
|
||||||
label_arguments(cmd, container, cid, input_values)
|
|
||||||
docker_run_args(cmd, container, config)
|
|
||||||
elif action == 'exec':
|
|
||||||
cmd = [DOCKER_CMD, 'exec']
|
|
||||||
docker_exec_args(cmd, container, config, cid)
|
|
||||||
|
|
||||||
(cmd_stdout, cmd_stderr, returncode) = execute(cmd)
|
|
||||||
if cmd_stdout:
|
|
||||||
stdout.append(cmd_stdout)
|
|
||||||
if cmd_stderr:
|
|
||||||
stderr.append(cmd_stderr)
|
|
||||||
|
|
||||||
if returncode not in exit_codes:
|
|
||||||
log.error("Error running %s. [%s]\n" % (cmd, returncode))
|
|
||||||
deploy_status_code = returncode
|
|
||||||
else:
|
|
||||||
log.debug('Completed %s' % cmd)
|
|
||||||
|
|
||||||
json.dump(build_response(
|
json.dump(build_response(
|
||||||
'\n'.join(stdout), '\n'.join(stderr), deploy_status_code), sys.stdout)
|
'\n'.join(stdout), '\n'.join(stderr), deploy_status_code), sys.stdout)
|
||||||
|
|
|
@ -15,9 +15,10 @@
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
import subprocess
|
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
import paunch
|
||||||
|
|
||||||
CONF_FILE = os.environ.get('HEAT_SHELL_CONFIG',
|
CONF_FILE = os.environ.get('HEAT_SHELL_CONFIG',
|
||||||
'/var/run/heat-config/heat-config')
|
'/var/run/heat-config/heat-config')
|
||||||
|
|
||||||
|
@ -49,100 +50,12 @@ def main(argv=sys.argv):
|
||||||
|
|
||||||
cmd_config_ids = [c['id'] for c in configs
|
cmd_config_ids = [c['id'] for c in configs
|
||||||
if c['group'] == 'docker-cmd']
|
if c['group'] == 'docker-cmd']
|
||||||
try:
|
|
||||||
delete_missing_configs(cmd_config_ids)
|
|
||||||
except Exception as e:
|
|
||||||
log.exception(e)
|
|
||||||
try:
|
|
||||||
rename_containers()
|
|
||||||
except Exception as e:
|
|
||||||
log.exception(e)
|
|
||||||
|
|
||||||
|
paunch.cleanup(
|
||||||
def delete_missing_configs(config_ids):
|
cmd_config_ids,
|
||||||
for conf_id in current_config_ids():
|
managed_by='docker-cmd',
|
||||||
if conf_id not in config_ids:
|
docker_cmd=DOCKER_CMD
|
||||||
log.debug('%s no longer exists, deleting containers' % conf_id)
|
)
|
||||||
remove_containers(conf_id)
|
|
||||||
|
|
||||||
|
|
||||||
def execute(cmd):
|
|
||||||
log.debug(' '.join(cmd))
|
|
||||||
subproc = subprocess.Popen(cmd, stdout=subprocess.PIPE,
|
|
||||||
stderr=subprocess.PIPE)
|
|
||||||
cmd_stdout, cmd_stderr = subproc.communicate()
|
|
||||||
return cmd_stdout, cmd_stderr, subproc.returncode
|
|
||||||
|
|
||||||
|
|
||||||
def current_config_ids():
|
|
||||||
# List all config_id labels for containers managed by docker-cmd
|
|
||||||
cmd = [
|
|
||||||
DOCKER_CMD, 'ps', '-a',
|
|
||||||
'--filter', 'label=managed_by=docker-cmd',
|
|
||||||
'--format', '{{.Label "config_id"}}'
|
|
||||||
]
|
|
||||||
cmd_stdout, cmd_stderr, returncode = execute(cmd)
|
|
||||||
if returncode != 0:
|
|
||||||
return set()
|
|
||||||
return set(cmd_stdout.split())
|
|
||||||
|
|
||||||
|
|
||||||
def remove_containers(conf_id):
|
|
||||||
cmd = [
|
|
||||||
DOCKER_CMD, 'ps', '-q', '-a',
|
|
||||||
'--filter', 'label=managed_by=docker-cmd',
|
|
||||||
'--filter', 'label=config_id=%s' % conf_id
|
|
||||||
]
|
|
||||||
cmd_stdout, cmd_stderr, returncode = execute(cmd)
|
|
||||||
if returncode == 0:
|
|
||||||
for container in cmd_stdout.split():
|
|
||||||
remove_container(container)
|
|
||||||
|
|
||||||
|
|
||||||
def remove_container(container):
|
|
||||||
cmd = [DOCKER_CMD, 'rm', '-f', container]
|
|
||||||
cmd_stdout, cmd_stderr, returncode = execute(cmd)
|
|
||||||
if returncode != 0:
|
|
||||||
log.error('Error removing container: %s' % container)
|
|
||||||
log.error(cmd_stderr)
|
|
||||||
|
|
||||||
|
|
||||||
def rename_containers():
|
|
||||||
# list every container name, and its container_name label
|
|
||||||
cmd = [
|
|
||||||
DOCKER_CMD, 'ps', '-a',
|
|
||||||
'--format', '{{.Names}} {{.Label "container_name"}}'
|
|
||||||
]
|
|
||||||
cmd_stdout, cmd_stderr, returncode = execute(cmd)
|
|
||||||
if returncode != 0:
|
|
||||||
return
|
|
||||||
|
|
||||||
lines = cmd_stdout.split("\n")
|
|
||||||
current_containers = []
|
|
||||||
need_renaming = {}
|
|
||||||
for line in lines:
|
|
||||||
entry = line.split()
|
|
||||||
if not entry:
|
|
||||||
continue
|
|
||||||
current_containers.append(entry[0])
|
|
||||||
|
|
||||||
# ignore if container_name label not set
|
|
||||||
if len(entry) < 2:
|
|
||||||
continue
|
|
||||||
|
|
||||||
# ignore if desired name is already actual name
|
|
||||||
if entry[0] == entry[-1]:
|
|
||||||
continue
|
|
||||||
|
|
||||||
need_renaming[entry[0]] = entry[-1]
|
|
||||||
|
|
||||||
for current, desired in sorted(need_renaming.items()):
|
|
||||||
if desired in current_containers:
|
|
||||||
log.info('Cannot rename "%s" since "%s" still exists' % (
|
|
||||||
current, desired))
|
|
||||||
else:
|
|
||||||
cmd = [DOCKER_CMD, 'rename', current, desired]
|
|
||||||
execute(cmd)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
features:
|
||||||
|
- |
|
||||||
|
The logic for the docker-cmd hook is now provided by the paunch library,
|
||||||
|
where further feature work will occur.
|
|
@ -5,6 +5,7 @@ fixtures>=3.0.0 # Apache-2.0/BSD
|
||||||
# Hacking already pins down pep8, pyflakes and flake8
|
# Hacking already pins down pep8, pyflakes and flake8
|
||||||
hacking>=0.12.0,!=0.13.0,<0.14 # Apache-2.0
|
hacking>=0.12.0,!=0.13.0,<0.14 # Apache-2.0
|
||||||
mock>=2.0 # BSD
|
mock>=2.0 # BSD
|
||||||
|
paunch>=1.0.0 # Apache-2.0
|
||||||
requests>=2.10.0,!=2.12.2,!=2.13.0 # Apache-2.0
|
requests>=2.10.0,!=2.12.2,!=2.13.0 # Apache-2.0
|
||||||
requests-mock>=1.1 # Apache-2.0
|
requests-mock>=1.1 # Apache-2.0
|
||||||
salt
|
salt
|
||||||
|
|
|
@ -112,28 +112,54 @@ class HookDockerCmdTest(common.RunScriptTest):
|
||||||
'TEST_STATE_PATH': self.test_state_path,
|
'TEST_STATE_PATH': self.test_state_path,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
def assert_args_and_labels(self, expected_args, expected_labels, observed):
|
||||||
|
'''Assert the labels arguments separately to other arguments.
|
||||||
|
|
||||||
|
Tests that each expected_labels label exists, and remaining
|
||||||
|
expected arguments match exactly.
|
||||||
|
|
||||||
|
This allows paunch to add new label arguments without breaking these
|
||||||
|
tests.
|
||||||
|
'''
|
||||||
|
|
||||||
|
args = []
|
||||||
|
labels = []
|
||||||
|
j = 0
|
||||||
|
while j < len(observed):
|
||||||
|
if observed[j] == '--label':
|
||||||
|
j += 1
|
||||||
|
labels.append(observed[j])
|
||||||
|
else:
|
||||||
|
args.append(observed[j])
|
||||||
|
j += 1
|
||||||
|
|
||||||
|
self.assertEqual(expected_args, args)
|
||||||
|
for label in expected_labels:
|
||||||
|
self.assertIn(label, labels)
|
||||||
|
|
||||||
def test_hook(self):
|
def test_hook(self):
|
||||||
|
|
||||||
self.env.update({
|
self.env.update({
|
||||||
'TEST_RESPONSE': json.dumps([{
|
'TEST_RESPONSE': json.dumps([
|
||||||
'stderr': 'Error: No such image, container or task: db',
|
# ps for delete missing
|
||||||
'returncode': 1
|
{},
|
||||||
}, {
|
# ps for renames
|
||||||
'stdout': '',
|
{},
|
||||||
'stderr': 'Creating db...'
|
# ps for currently running containers
|
||||||
}, {
|
{},
|
||||||
'stderr': 'Error: No such image, container or task: web',
|
# inspect for db unique container name
|
||||||
'returncode': 1
|
{},
|
||||||
}, {
|
# docker run db
|
||||||
'stdout': '',
|
{'stderr': 'Creating db...'},
|
||||||
'stderr': 'Creating web...'
|
# inspect for web unique container name
|
||||||
}, {
|
{},
|
||||||
'stdout': 'web',
|
# docker run web
|
||||||
}, {
|
{'stderr': 'Creating web...'},
|
||||||
|
# name lookup for exec web
|
||||||
'stdout': '',
|
{'stdout': 'web'},
|
||||||
'stderr': 'one.txt\ntwo.txt\nthree.txt'
|
# docker exec web
|
||||||
}])
|
{'stderr': 'one.txt\ntwo.txt\nthree.txt'},
|
||||||
|
])
|
||||||
})
|
})
|
||||||
returncode, stdout, stderr = self.run_cmd(
|
returncode, stdout, stderr = self.run_cmd(
|
||||||
[self.hook_path], self.env, json.dumps(self.data))
|
[self.hook_path], self.env, json.dumps(self.data))
|
||||||
|
@ -148,58 +174,75 @@ class HookDockerCmdTest(common.RunScriptTest):
|
||||||
'deploy_status_code': 0
|
'deploy_status_code': 0
|
||||||
}, json.loads(stdout))
|
}, json.loads(stdout))
|
||||||
|
|
||||||
state = list(self.json_from_files(self.test_state_path, 6))
|
state = list(self.json_from_files(self.test_state_path, 9))
|
||||||
|
self.assertEqual([
|
||||||
|
self.fake_tool_path,
|
||||||
|
'ps',
|
||||||
|
'-a',
|
||||||
|
'--filter',
|
||||||
|
'label=managed_by=docker-cmd',
|
||||||
|
'--filter',
|
||||||
|
'label=config_id=abc123',
|
||||||
|
'--format',
|
||||||
|
'{{.Names}} {{.Label "container_name"}}'
|
||||||
|
], state[0]['args'])
|
||||||
|
self.assertEqual([
|
||||||
|
self.fake_tool_path,
|
||||||
|
'ps',
|
||||||
|
'-a',
|
||||||
|
'--filter',
|
||||||
|
'label=managed_by=docker-cmd',
|
||||||
|
'--format',
|
||||||
|
'{{.Names}} {{.Label "container_name"}}'
|
||||||
|
], state[1]['args'])
|
||||||
|
self.assertEqual([
|
||||||
|
self.fake_tool_path,
|
||||||
|
'ps',
|
||||||
|
'-a',
|
||||||
|
'--filter',
|
||||||
|
'label=managed_by=docker-cmd',
|
||||||
|
'--filter',
|
||||||
|
'label=config_id=abc123',
|
||||||
|
'--format',
|
||||||
|
'{{.Names}} {{.Label "container_name"}}'
|
||||||
|
], state[2]['args'])
|
||||||
self.assertEqual([
|
self.assertEqual([
|
||||||
self.fake_tool_path,
|
self.fake_tool_path,
|
||||||
'inspect',
|
'inspect',
|
||||||
'--format',
|
'--format',
|
||||||
'exists',
|
'exists',
|
||||||
'db',
|
'db'
|
||||||
], state[0]['args'])
|
], state[3]['args'])
|
||||||
self.assertEqual([
|
self.assert_args_and_labels([
|
||||||
self.fake_tool_path,
|
self.fake_tool_path,
|
||||||
'run',
|
'run',
|
||||||
'--name',
|
'--name',
|
||||||
'db',
|
'db',
|
||||||
'--label',
|
|
||||||
'deploy_stack_id=the_stack',
|
|
||||||
'--label',
|
|
||||||
'deploy_resource_name=the_deployment',
|
|
||||||
'--label',
|
|
||||||
'config_id=abc123',
|
|
||||||
'--label',
|
|
||||||
'container_name=db',
|
|
||||||
'--label',
|
|
||||||
'managed_by=docker-cmd',
|
|
||||||
'--detach=true',
|
'--detach=true',
|
||||||
'--env-file=env.file',
|
'--env-file=env.file',
|
||||||
'--env=foo=bar',
|
'--env=foo=bar',
|
||||||
'--privileged=false',
|
'--privileged=false',
|
||||||
'xxx'
|
'xxx'
|
||||||
''
|
''
|
||||||
], state[1]['args'])
|
], [
|
||||||
|
'deploy_stack_id=the_stack',
|
||||||
|
'deploy_resource_name=the_deployment',
|
||||||
|
'config_id=abc123',
|
||||||
|
'container_name=db',
|
||||||
|
'managed_by=docker-cmd',
|
||||||
|
], state[4]['args'])
|
||||||
self.assertEqual([
|
self.assertEqual([
|
||||||
self.fake_tool_path,
|
self.fake_tool_path,
|
||||||
'inspect',
|
'inspect',
|
||||||
'--format',
|
'--format',
|
||||||
'exists',
|
'exists',
|
||||||
'web',
|
'web',
|
||||||
], state[2]['args'])
|
], state[5]['args'])
|
||||||
self.assertEqual([
|
self.assert_args_and_labels([
|
||||||
self.fake_tool_path,
|
self.fake_tool_path,
|
||||||
'run',
|
'run',
|
||||||
'--name',
|
'--name',
|
||||||
'web',
|
'web',
|
||||||
'--label',
|
|
||||||
'deploy_stack_id=the_stack',
|
|
||||||
'--label',
|
|
||||||
'deploy_resource_name=the_deployment',
|
|
||||||
'--label',
|
|
||||||
'config_id=abc123',
|
|
||||||
'--label',
|
|
||||||
'container_name=web',
|
|
||||||
'--label',
|
|
||||||
'managed_by=docker-cmd',
|
|
||||||
'--detach=true',
|
'--detach=true',
|
||||||
'--env-file=foo.env',
|
'--env-file=foo.env',
|
||||||
'--env-file=bar.conf',
|
'--env-file=bar.conf',
|
||||||
|
@ -214,7 +257,13 @@ class HookDockerCmdTest(common.RunScriptTest):
|
||||||
'yyy',
|
'yyy',
|
||||||
'/bin/webserver',
|
'/bin/webserver',
|
||||||
'start'
|
'start'
|
||||||
], state[3]['args'])
|
], [
|
||||||
|
'deploy_stack_id=the_stack',
|
||||||
|
'deploy_resource_name=the_deployment',
|
||||||
|
'config_id=abc123',
|
||||||
|
'container_name=web',
|
||||||
|
'managed_by=docker-cmd',
|
||||||
|
], state[6]['args'])
|
||||||
self.assertEqual([
|
self.assertEqual([
|
||||||
self.fake_tool_path,
|
self.fake_tool_path,
|
||||||
'ps',
|
'ps',
|
||||||
|
@ -225,25 +274,32 @@ class HookDockerCmdTest(common.RunScriptTest):
|
||||||
'label=config_id=abc123',
|
'label=config_id=abc123',
|
||||||
'--format',
|
'--format',
|
||||||
'{{.Names}}',
|
'{{.Names}}',
|
||||||
], state[4]['args'])
|
], state[7]['args'])
|
||||||
self.assertEqual([
|
self.assertEqual([
|
||||||
self.fake_tool_path,
|
self.fake_tool_path,
|
||||||
'exec',
|
'exec',
|
||||||
'web',
|
'web',
|
||||||
'/bin/ls',
|
'/bin/ls',
|
||||||
'-l'
|
'-l'
|
||||||
], state[5]['args'])
|
], state[8]['args'])
|
||||||
|
|
||||||
def test_hook_exit_codes(self):
|
def test_hook_exit_codes(self):
|
||||||
|
|
||||||
self.env.update({
|
self.env.update({
|
||||||
'TEST_RESPONSE': json.dumps([{
|
'TEST_RESPONSE': json.dumps([
|
||||||
'stdout': 'web',
|
# ps for delete missing
|
||||||
}, {
|
{},
|
||||||
'stdout': '',
|
# ps for renames
|
||||||
'stderr': 'Warning: custom exit code',
|
{},
|
||||||
'returncode': 1
|
# ps for currently running containers
|
||||||
}])
|
{},
|
||||||
|
{'stdout': 'web'},
|
||||||
|
{
|
||||||
|
'stdout': '',
|
||||||
|
'stderr': 'Warning: custom exit code',
|
||||||
|
'returncode': 1
|
||||||
|
}
|
||||||
|
])
|
||||||
})
|
})
|
||||||
returncode, stdout, stderr = self.run_cmd(
|
returncode, stdout, stderr = self.run_cmd(
|
||||||
[self.hook_path], self.env, json.dumps(self.data_exit_code))
|
[self.hook_path], self.env, json.dumps(self.data_exit_code))
|
||||||
|
@ -254,7 +310,38 @@ class HookDockerCmdTest(common.RunScriptTest):
|
||||||
'deploy_status_code': 0
|
'deploy_status_code': 0
|
||||||
}, json.loads(stdout))
|
}, json.loads(stdout))
|
||||||
|
|
||||||
state = list(self.json_from_files(self.test_state_path, 2))
|
state = list(self.json_from_files(self.test_state_path, 5))
|
||||||
|
self.assertEqual([
|
||||||
|
self.fake_tool_path,
|
||||||
|
'ps',
|
||||||
|
'-a',
|
||||||
|
'--filter',
|
||||||
|
'label=managed_by=docker-cmd',
|
||||||
|
'--filter',
|
||||||
|
'label=config_id=abc123',
|
||||||
|
'--format',
|
||||||
|
'{{.Names}} {{.Label "container_name"}}'
|
||||||
|
], state[0]['args'])
|
||||||
|
self.assertEqual([
|
||||||
|
self.fake_tool_path,
|
||||||
|
'ps',
|
||||||
|
'-a',
|
||||||
|
'--filter',
|
||||||
|
'label=managed_by=docker-cmd',
|
||||||
|
'--format',
|
||||||
|
'{{.Names}} {{.Label "container_name"}}'
|
||||||
|
], state[1]['args'])
|
||||||
|
self.assertEqual([
|
||||||
|
self.fake_tool_path,
|
||||||
|
'ps',
|
||||||
|
'-a',
|
||||||
|
'--filter',
|
||||||
|
'label=managed_by=docker-cmd',
|
||||||
|
'--filter',
|
||||||
|
'label=config_id=abc123',
|
||||||
|
'--format',
|
||||||
|
'{{.Names}} {{.Label "container_name"}}'
|
||||||
|
], state[2]['args'])
|
||||||
self.assertEqual([
|
self.assertEqual([
|
||||||
self.fake_tool_path,
|
self.fake_tool_path,
|
||||||
'ps',
|
'ps',
|
||||||
|
@ -265,37 +352,42 @@ class HookDockerCmdTest(common.RunScriptTest):
|
||||||
'label=config_id=abc123',
|
'label=config_id=abc123',
|
||||||
'--format',
|
'--format',
|
||||||
'{{.Names}}',
|
'{{.Names}}',
|
||||||
], state[0]['args'])
|
], state[3]['args'])
|
||||||
self.assertEqual([
|
self.assertEqual([
|
||||||
self.fake_tool_path,
|
self.fake_tool_path,
|
||||||
'exec',
|
'exec',
|
||||||
'web',
|
'web',
|
||||||
'/bin/ls',
|
'/bin/ls',
|
||||||
'-l'
|
'-l'
|
||||||
], state[1]['args'])
|
], state[4]['args'])
|
||||||
|
|
||||||
def test_hook_failed(self):
|
def test_hook_failed(self):
|
||||||
|
|
||||||
self.env.update({
|
self.env.update({
|
||||||
'TEST_RESPONSE': json.dumps([{
|
'TEST_RESPONSE': json.dumps([
|
||||||
'stderr': 'Error: No such image, container or task: db',
|
# ps for delete missing
|
||||||
'returncode': 1
|
{},
|
||||||
}, {
|
# ps for renames
|
||||||
'stdout': '',
|
{},
|
||||||
'stderr': 'Creating db...'
|
# ps for currently running containers
|
||||||
}, {
|
{},
|
||||||
'stderr': 'Error: No such image, container or task: web',
|
# inspect for db unique container name
|
||||||
'returncode': 1
|
{},
|
||||||
}, {
|
# docker run db
|
||||||
'stdout': '',
|
{'stderr': 'Creating db...'},
|
||||||
'stderr': 'Creating web...'
|
# inspect for web unique container name
|
||||||
}, {
|
{},
|
||||||
'stdout': 'web',
|
# docker run web
|
||||||
}, {
|
{'stderr': 'Creating web...'},
|
||||||
'stdout': '',
|
# name lookup for exec web
|
||||||
'stderr': 'No such file or directory',
|
{'stdout': 'web'},
|
||||||
'returncode': 2
|
# docker exec web fails
|
||||||
}])
|
{
|
||||||
|
'stdout': '',
|
||||||
|
'stderr': 'No such file or directory',
|
||||||
|
'returncode': 2
|
||||||
|
}
|
||||||
|
])
|
||||||
})
|
})
|
||||||
returncode, stdout, stderr = self.run_cmd(
|
returncode, stdout, stderr = self.run_cmd(
|
||||||
[self.hook_path], self.env, json.dumps(self.data))
|
[self.hook_path], self.env, json.dumps(self.data))
|
||||||
|
@ -308,57 +400,75 @@ class HookDockerCmdTest(common.RunScriptTest):
|
||||||
'deploy_status_code': 2
|
'deploy_status_code': 2
|
||||||
}, json.loads(stdout))
|
}, json.loads(stdout))
|
||||||
|
|
||||||
state = list(self.json_from_files(self.test_state_path, 6))
|
state = list(self.json_from_files(self.test_state_path, 9))
|
||||||
|
self.assertEqual([
|
||||||
|
self.fake_tool_path,
|
||||||
|
'ps',
|
||||||
|
'-a',
|
||||||
|
'--filter',
|
||||||
|
'label=managed_by=docker-cmd',
|
||||||
|
'--filter',
|
||||||
|
'label=config_id=abc123',
|
||||||
|
'--format',
|
||||||
|
'{{.Names}} {{.Label "container_name"}}'
|
||||||
|
], state[0]['args'])
|
||||||
|
self.assertEqual([
|
||||||
|
self.fake_tool_path,
|
||||||
|
'ps',
|
||||||
|
'-a',
|
||||||
|
'--filter',
|
||||||
|
'label=managed_by=docker-cmd',
|
||||||
|
'--format',
|
||||||
|
'{{.Names}} {{.Label "container_name"}}'
|
||||||
|
], state[1]['args'])
|
||||||
|
self.assertEqual([
|
||||||
|
self.fake_tool_path,
|
||||||
|
'ps',
|
||||||
|
'-a',
|
||||||
|
'--filter',
|
||||||
|
'label=managed_by=docker-cmd',
|
||||||
|
'--filter',
|
||||||
|
'label=config_id=abc123',
|
||||||
|
'--format',
|
||||||
|
'{{.Names}} {{.Label "container_name"}}'
|
||||||
|
], state[2]['args'])
|
||||||
self.assertEqual([
|
self.assertEqual([
|
||||||
self.fake_tool_path,
|
self.fake_tool_path,
|
||||||
'inspect',
|
'inspect',
|
||||||
'--format',
|
'--format',
|
||||||
'exists',
|
'exists',
|
||||||
'db',
|
'db'
|
||||||
], state[0]['args'])
|
], state[3]['args'])
|
||||||
self.assertEqual([
|
self.assert_args_and_labels([
|
||||||
self.fake_tool_path,
|
self.fake_tool_path,
|
||||||
'run',
|
'run',
|
||||||
'--name',
|
'--name',
|
||||||
'db',
|
'db',
|
||||||
'--label',
|
|
||||||
'deploy_stack_id=the_stack',
|
|
||||||
'--label',
|
|
||||||
'deploy_resource_name=the_deployment',
|
|
||||||
'--label',
|
|
||||||
'config_id=abc123',
|
|
||||||
'--label',
|
|
||||||
'container_name=db',
|
|
||||||
'--label',
|
|
||||||
'managed_by=docker-cmd',
|
|
||||||
'--detach=true',
|
'--detach=true',
|
||||||
'--env-file=env.file',
|
'--env-file=env.file',
|
||||||
'--env=foo=bar',
|
'--env=foo=bar',
|
||||||
'--privileged=false',
|
'--privileged=false',
|
||||||
'xxx'
|
'xxx'
|
||||||
], state[1]['args'])
|
''
|
||||||
|
], [
|
||||||
|
'deploy_stack_id=the_stack',
|
||||||
|
'deploy_resource_name=the_deployment',
|
||||||
|
'config_id=abc123',
|
||||||
|
'container_name=db',
|
||||||
|
'managed_by=docker-cmd',
|
||||||
|
], state[4]['args'])
|
||||||
self.assertEqual([
|
self.assertEqual([
|
||||||
self.fake_tool_path,
|
self.fake_tool_path,
|
||||||
'inspect',
|
'inspect',
|
||||||
'--format',
|
'--format',
|
||||||
'exists',
|
'exists',
|
||||||
'web',
|
'web',
|
||||||
], state[2]['args'])
|
], state[5]['args'])
|
||||||
self.assertEqual([
|
self.assert_args_and_labels([
|
||||||
self.fake_tool_path,
|
self.fake_tool_path,
|
||||||
'run',
|
'run',
|
||||||
'--name',
|
'--name',
|
||||||
'web',
|
'web',
|
||||||
'--label',
|
|
||||||
'deploy_stack_id=the_stack',
|
|
||||||
'--label',
|
|
||||||
'deploy_resource_name=the_deployment',
|
|
||||||
'--label',
|
|
||||||
'config_id=abc123',
|
|
||||||
'--label',
|
|
||||||
'container_name=web',
|
|
||||||
'--label',
|
|
||||||
'managed_by=docker-cmd',
|
|
||||||
'--detach=true',
|
'--detach=true',
|
||||||
'--env-file=foo.env',
|
'--env-file=foo.env',
|
||||||
'--env-file=bar.conf',
|
'--env-file=bar.conf',
|
||||||
|
@ -373,7 +483,13 @@ class HookDockerCmdTest(common.RunScriptTest):
|
||||||
'yyy',
|
'yyy',
|
||||||
'/bin/webserver',
|
'/bin/webserver',
|
||||||
'start'
|
'start'
|
||||||
], state[3]['args'])
|
], [
|
||||||
|
'deploy_stack_id=the_stack',
|
||||||
|
'deploy_resource_name=the_deployment',
|
||||||
|
'config_id=abc123',
|
||||||
|
'container_name=web',
|
||||||
|
'managed_by=docker-cmd',
|
||||||
|
], state[6]['args'])
|
||||||
self.assertEqual([
|
self.assertEqual([
|
||||||
self.fake_tool_path,
|
self.fake_tool_path,
|
||||||
'ps',
|
'ps',
|
||||||
|
@ -384,43 +500,47 @@ class HookDockerCmdTest(common.RunScriptTest):
|
||||||
'label=config_id=abc123',
|
'label=config_id=abc123',
|
||||||
'--format',
|
'--format',
|
||||||
'{{.Names}}',
|
'{{.Names}}',
|
||||||
], state[4]['args'])
|
], state[7]['args'])
|
||||||
self.assertEqual([
|
self.assertEqual([
|
||||||
self.fake_tool_path,
|
self.fake_tool_path,
|
||||||
'exec',
|
'exec',
|
||||||
'web',
|
'web',
|
||||||
'/bin/ls',
|
'/bin/ls',
|
||||||
'-l'
|
'-l'
|
||||||
], state[5]['args'])
|
], state[8]['args'])
|
||||||
|
|
||||||
def test_hook_unique_names(self):
|
def test_hook_unique_names(self):
|
||||||
|
|
||||||
self.env.update({
|
self.env.update({
|
||||||
'TEST_RESPONSE': json.dumps([{
|
'TEST_RESPONSE': json.dumps([
|
||||||
'stdout': 'exists\n',
|
# ps for delete missing in this config id
|
||||||
'returncode': 0
|
{},
|
||||||
}, {
|
# ps for renames
|
||||||
'stderr': 'Error: No such image, container or task: db-blah',
|
{'stdout': 'web web\ndb db\n'},
|
||||||
'returncode': 1
|
# ps for currently running containers in this config id
|
||||||
}, {
|
{},
|
||||||
'stdout': '',
|
# inspect for db unique container name
|
||||||
'stderr': 'Creating db...'
|
{'stdout': 'exists'},
|
||||||
}, {
|
{
|
||||||
'stdout': 'exists\n',
|
'stderr': 'Error: No such container: db-blah',
|
||||||
'returncode': 0
|
'returncode': 1
|
||||||
}, {
|
},
|
||||||
'stderr': 'Error: No such image, container or task: web-blah',
|
# docker run db
|
||||||
'returncode': 1
|
{'stderr': 'Creating db...'},
|
||||||
}, {
|
# # inspect for web unique container name
|
||||||
'stdout': '',
|
{'stdout': 'exists'},
|
||||||
'stderr': 'Creating web...'
|
{
|
||||||
}, {
|
'stderr': 'Error: No such container: web-blah',
|
||||||
'stdout': 'web-asdf1234',
|
'returncode': 1
|
||||||
}, {
|
},
|
||||||
'stdout': '',
|
# # docker run web
|
||||||
'stderr': 'one.txt\ntwo.txt\nthree.txt'
|
{'stderr': 'Creating web...'},
|
||||||
}])
|
# name lookup for exec web
|
||||||
|
{'stdout': 'web-asdf1234'},
|
||||||
|
# docker exec web-asdf1234
|
||||||
|
{'stderr': 'one.txt\ntwo.txt\nthree.txt'},
|
||||||
|
])
|
||||||
})
|
})
|
||||||
|
|
||||||
returncode, stdout, stderr = self.run_cmd(
|
returncode, stdout, stderr = self.run_cmd(
|
||||||
[self.hook_path], self.env, json.dumps(self.data))
|
[self.hook_path], self.env, json.dumps(self.data))
|
||||||
|
|
||||||
|
@ -434,75 +554,92 @@ class HookDockerCmdTest(common.RunScriptTest):
|
||||||
'deploy_status_code': 0
|
'deploy_status_code': 0
|
||||||
}, json.loads(stdout))
|
}, json.loads(stdout))
|
||||||
|
|
||||||
state = list(self.json_from_files(self.test_state_path, 8))
|
state = list(self.json_from_files(self.test_state_path, 11))
|
||||||
db_container_name = state[1]['args'][4]
|
db_container_name = state[4]['args'][4]
|
||||||
web_container_name = state[4]['args'][4]
|
web_container_name = state[7]['args'][4]
|
||||||
self.assertRegex(db_container_name, 'db-[0-9a-z]{8}')
|
self.assertRegex(db_container_name, 'db-[0-9a-z]{8}')
|
||||||
self.assertRegex(web_container_name, 'web-[0-9a-z]{8}')
|
self.assertRegex(web_container_name, 'web-[0-9a-z]{8}')
|
||||||
self.assertEqual([
|
self.assertEqual([
|
||||||
self.fake_tool_path,
|
self.fake_tool_path,
|
||||||
'inspect',
|
'ps',
|
||||||
|
'-a',
|
||||||
|
'--filter',
|
||||||
|
'label=managed_by=docker-cmd',
|
||||||
|
'--filter',
|
||||||
|
'label=config_id=abc123',
|
||||||
'--format',
|
'--format',
|
||||||
'exists',
|
'{{.Names}} {{.Label "container_name"}}'
|
||||||
'db',
|
|
||||||
], state[0]['args'])
|
], state[0]['args'])
|
||||||
self.assertEqual([
|
self.assertEqual([
|
||||||
self.fake_tool_path,
|
self.fake_tool_path,
|
||||||
'inspect',
|
'ps',
|
||||||
|
'-a',
|
||||||
|
'--filter',
|
||||||
|
'label=managed_by=docker-cmd',
|
||||||
'--format',
|
'--format',
|
||||||
'exists',
|
'{{.Names}} {{.Label "container_name"}}'
|
||||||
db_container_name,
|
|
||||||
], state[1]['args'])
|
], state[1]['args'])
|
||||||
self.assertEqual([
|
self.assertEqual([
|
||||||
self.fake_tool_path,
|
self.fake_tool_path,
|
||||||
'run',
|
'ps',
|
||||||
'--name',
|
'-a',
|
||||||
db_container_name,
|
'--filter',
|
||||||
'--label',
|
'label=managed_by=docker-cmd',
|
||||||
'deploy_stack_id=the_stack',
|
'--filter',
|
||||||
'--label',
|
'label=config_id=abc123',
|
||||||
'deploy_resource_name=the_deployment',
|
'--format',
|
||||||
'--label',
|
'{{.Names}} {{.Label "container_name"}}'
|
||||||
'config_id=abc123',
|
|
||||||
'--label',
|
|
||||||
'container_name=db',
|
|
||||||
'--label',
|
|
||||||
'managed_by=docker-cmd',
|
|
||||||
'--detach=true',
|
|
||||||
'--env-file=env.file',
|
|
||||||
'--env=foo=bar',
|
|
||||||
'--privileged=false',
|
|
||||||
'xxx'
|
|
||||||
], state[2]['args'])
|
], state[2]['args'])
|
||||||
self.assertEqual([
|
self.assertEqual([
|
||||||
self.fake_tool_path,
|
self.fake_tool_path,
|
||||||
'inspect',
|
'inspect',
|
||||||
'--format',
|
'--format',
|
||||||
'exists',
|
'exists',
|
||||||
'web',
|
'db'
|
||||||
], state[3]['args'])
|
], state[3]['args'])
|
||||||
self.assertEqual([
|
self.assertEqual([
|
||||||
self.fake_tool_path,
|
self.fake_tool_path,
|
||||||
'inspect',
|
'inspect',
|
||||||
'--format',
|
'--format',
|
||||||
'exists',
|
'exists',
|
||||||
web_container_name,
|
db_container_name,
|
||||||
], state[4]['args'])
|
], state[4]['args'])
|
||||||
|
self.assert_args_and_labels([
|
||||||
|
self.fake_tool_path,
|
||||||
|
'run',
|
||||||
|
'--name',
|
||||||
|
db_container_name,
|
||||||
|
'--detach=true',
|
||||||
|
'--env-file=env.file',
|
||||||
|
'--env=foo=bar',
|
||||||
|
'--privileged=false',
|
||||||
|
'xxx'
|
||||||
|
], [
|
||||||
|
'deploy_stack_id=the_stack',
|
||||||
|
'deploy_resource_name=the_deployment',
|
||||||
|
'config_id=abc123',
|
||||||
|
'container_name=db',
|
||||||
|
'managed_by=docker-cmd',
|
||||||
|
], state[5]['args'])
|
||||||
self.assertEqual([
|
self.assertEqual([
|
||||||
|
self.fake_tool_path,
|
||||||
|
'inspect',
|
||||||
|
'--format',
|
||||||
|
'exists',
|
||||||
|
'web',
|
||||||
|
], state[6]['args'])
|
||||||
|
self.assertEqual([
|
||||||
|
self.fake_tool_path,
|
||||||
|
'inspect',
|
||||||
|
'--format',
|
||||||
|
'exists',
|
||||||
|
web_container_name,
|
||||||
|
], state[7]['args'])
|
||||||
|
self.assert_args_and_labels([
|
||||||
self.fake_tool_path,
|
self.fake_tool_path,
|
||||||
'run',
|
'run',
|
||||||
'--name',
|
'--name',
|
||||||
web_container_name,
|
web_container_name,
|
||||||
'--label',
|
|
||||||
'deploy_stack_id=the_stack',
|
|
||||||
'--label',
|
|
||||||
'deploy_resource_name=the_deployment',
|
|
||||||
'--label',
|
|
||||||
'config_id=abc123',
|
|
||||||
'--label',
|
|
||||||
'container_name=web',
|
|
||||||
'--label',
|
|
||||||
'managed_by=docker-cmd',
|
|
||||||
'--detach=true',
|
'--detach=true',
|
||||||
'--env-file=foo.env',
|
'--env-file=foo.env',
|
||||||
'--env-file=bar.conf',
|
'--env-file=bar.conf',
|
||||||
|
@ -517,7 +654,13 @@ class HookDockerCmdTest(common.RunScriptTest):
|
||||||
'yyy',
|
'yyy',
|
||||||
'/bin/webserver',
|
'/bin/webserver',
|
||||||
'start'
|
'start'
|
||||||
], state[5]['args'])
|
], [
|
||||||
|
'deploy_stack_id=the_stack',
|
||||||
|
'deploy_resource_name=the_deployment',
|
||||||
|
'config_id=abc123',
|
||||||
|
'container_name=web',
|
||||||
|
'managed_by=docker-cmd',
|
||||||
|
], state[8]['args'])
|
||||||
self.assertEqual([
|
self.assertEqual([
|
||||||
self.fake_tool_path,
|
self.fake_tool_path,
|
||||||
'ps',
|
'ps',
|
||||||
|
@ -528,14 +671,14 @@ class HookDockerCmdTest(common.RunScriptTest):
|
||||||
'label=config_id=abc123',
|
'label=config_id=abc123',
|
||||||
'--format',
|
'--format',
|
||||||
'{{.Names}}',
|
'{{.Names}}',
|
||||||
], state[6]['args'])
|
], state[9]['args'])
|
||||||
self.assertEqual([
|
self.assertEqual([
|
||||||
self.fake_tool_path,
|
self.fake_tool_path,
|
||||||
'exec',
|
'exec',
|
||||||
'web-asdf1234',
|
'web-asdf1234',
|
||||||
'/bin/ls',
|
'/bin/ls',
|
||||||
'-l'
|
'-l'
|
||||||
], state[7]['args'])
|
], state[10]['args'])
|
||||||
|
|
||||||
def test_cleanup_deleted(self):
|
def test_cleanup_deleted(self):
|
||||||
self.env.update({
|
self.env.update({
|
||||||
|
@ -571,6 +714,8 @@ class HookDockerCmdTest(common.RunScriptTest):
|
||||||
self.fake_tool_path,
|
self.fake_tool_path,
|
||||||
'ps',
|
'ps',
|
||||||
'-a',
|
'-a',
|
||||||
|
'--filter',
|
||||||
|
'label=managed_by=docker-cmd',
|
||||||
'--format',
|
'--format',
|
||||||
'{{.Names}} {{.Label "container_name"}}'
|
'{{.Names}} {{.Label "container_name"}}'
|
||||||
], state[1]['args'])
|
], state[1]['args'])
|
||||||
|
@ -647,6 +792,8 @@ class HookDockerCmdTest(common.RunScriptTest):
|
||||||
self.fake_tool_path,
|
self.fake_tool_path,
|
||||||
'ps',
|
'ps',
|
||||||
'-a',
|
'-a',
|
||||||
|
'--filter',
|
||||||
|
'label=managed_by=docker-cmd',
|
||||||
'--format',
|
'--format',
|
||||||
'{{.Names}} {{.Label "container_name"}}'
|
'{{.Names}} {{.Label "container_name"}}'
|
||||||
], state[5]['args'])
|
], state[5]['args'])
|
||||||
|
@ -687,6 +834,8 @@ class HookDockerCmdTest(common.RunScriptTest):
|
||||||
self.fake_tool_path,
|
self.fake_tool_path,
|
||||||
'ps',
|
'ps',
|
||||||
'-a',
|
'-a',
|
||||||
|
'--filter',
|
||||||
|
'label=managed_by=docker-cmd',
|
||||||
'--format',
|
'--format',
|
||||||
'{{.Names}} {{.Label "container_name"}}'
|
'{{.Names}} {{.Label "container_name"}}'
|
||||||
], state[1]['args'])
|
], state[1]['args'])
|
||||||
|
@ -765,6 +914,8 @@ class HookDockerCmdTest(common.RunScriptTest):
|
||||||
self.fake_tool_path,
|
self.fake_tool_path,
|
||||||
'ps',
|
'ps',
|
||||||
'-a',
|
'-a',
|
||||||
|
'--filter',
|
||||||
|
'label=managed_by=docker-cmd',
|
||||||
'--format',
|
'--format',
|
||||||
'{{.Names}} {{.Label "container_name"}}'
|
'{{.Names}} {{.Label "container_name"}}'
|
||||||
], state[5]['args'])
|
], state[5]['args'])
|
||||||
|
@ -805,6 +956,8 @@ class HookDockerCmdTest(common.RunScriptTest):
|
||||||
self.fake_tool_path,
|
self.fake_tool_path,
|
||||||
'ps',
|
'ps',
|
||||||
'-a',
|
'-a',
|
||||||
|
'--filter',
|
||||||
|
'label=managed_by=docker-cmd',
|
||||||
'--format',
|
'--format',
|
||||||
'{{.Names}} {{.Label "container_name"}}'
|
'{{.Names}} {{.Label "container_name"}}'
|
||||||
], state[1]['args'])
|
], state[1]['args'])
|
||||||
|
|
Loading…
Reference in New Issue