mirror of
https://github.com/docker/compose.git
synced 2025-07-22 05:04:27 +02:00
Merge pull request #6126 from docker/wfender-2013-expose-config-hash
Add --hash opt for config command
This commit is contained in:
commit
f207d94b3c
1
.gitignore
vendored
1
.gitignore
vendored
@ -13,3 +13,4 @@ compose/GITSHA
|
|||||||
*.swp
|
*.swp
|
||||||
.DS_Store
|
.DS_Store
|
||||||
.cache
|
.cache
|
||||||
|
.idea
|
||||||
|
@ -328,7 +328,9 @@ class TopLevelCommand(object):
|
|||||||
anything.
|
anything.
|
||||||
--services Print the service names, one per line.
|
--services Print the service names, one per line.
|
||||||
--volumes Print the volume names, one per line.
|
--volumes Print the volume names, one per line.
|
||||||
|
--hash="*" Print the service config hash, one per line.
|
||||||
|
Set "service1,service2" for a list of specified services
|
||||||
|
or use the wildcard symbol to display all services
|
||||||
"""
|
"""
|
||||||
|
|
||||||
compose_config = get_config_from_options(self.project_dir, self.toplevel_options)
|
compose_config = get_config_from_options(self.project_dir, self.toplevel_options)
|
||||||
@ -350,6 +352,15 @@ class TopLevelCommand(object):
|
|||||||
print('\n'.join(volume for volume in compose_config.volumes))
|
print('\n'.join(volume for volume in compose_config.volumes))
|
||||||
return
|
return
|
||||||
|
|
||||||
|
if options['--hash'] is not None:
|
||||||
|
h = options['--hash']
|
||||||
|
self.project = project_from_options('.', self.toplevel_options)
|
||||||
|
services = [svc for svc in options['--hash'].split(',')] if h != '*' else None
|
||||||
|
with errors.handle_connection_errors(self.project.client):
|
||||||
|
for service in self.project.get_services(services):
|
||||||
|
print('{} {}'.format(service.name, service.config_hash))
|
||||||
|
return
|
||||||
|
|
||||||
print(serialize_config(compose_config, image_digests))
|
print(serialize_config(compose_config, image_digests))
|
||||||
|
|
||||||
def create(self, options):
|
def create(self, options):
|
||||||
|
@ -323,7 +323,12 @@ def get_networks(service_dict, network_definitions):
|
|||||||
'Service "{}" uses an undefined network "{}"'
|
'Service "{}" uses an undefined network "{}"'
|
||||||
.format(service_dict['name'], name))
|
.format(service_dict['name'], name))
|
||||||
|
|
||||||
return OrderedDict(sorted(
|
if any([v.get('priority') for v in networks.values()]):
|
||||||
networks.items(),
|
return OrderedDict(sorted(
|
||||||
key=lambda t: t[1].get('priority') or 0, reverse=True
|
networks.items(),
|
||||||
))
|
key=lambda t: t[1].get('priority') or 0, reverse=True
|
||||||
|
))
|
||||||
|
else:
|
||||||
|
# Ensure Compose will pick a consistent primary network if no
|
||||||
|
# priority is set
|
||||||
|
return OrderedDict(sorted(networks.items(), key=lambda t: t[0]))
|
||||||
|
@ -656,9 +656,15 @@ class Service(object):
|
|||||||
return json_hash(self.config_dict())
|
return json_hash(self.config_dict())
|
||||||
|
|
||||||
def config_dict(self):
|
def config_dict(self):
|
||||||
|
def image_id():
|
||||||
|
try:
|
||||||
|
return self.image()['Id']
|
||||||
|
except NoSuchImageError:
|
||||||
|
return None
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'options': self.options,
|
'options': self.options,
|
||||||
'image_id': self.image()['Id'],
|
'image_id': image_id(),
|
||||||
'links': self.get_link_names(),
|
'links': self.get_link_names(),
|
||||||
'net': self.network_mode.id,
|
'net': self.network_mode.id,
|
||||||
'networks': self.networks,
|
'networks': self.networks,
|
||||||
|
@ -136,7 +136,7 @@ _docker_compose_bundle() {
|
|||||||
|
|
||||||
|
|
||||||
_docker_compose_config() {
|
_docker_compose_config() {
|
||||||
COMPREPLY=( $( compgen -W "--help --quiet -q --resolve-image-digests --services --volumes" -- "$cur" ) )
|
COMPREPLY=( $( compgen -W "--help --quiet -q --resolve-image-digests --services --volumes --hash" -- "$cur" ) )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -213,7 +213,8 @@ __docker-compose_subcommand() {
|
|||||||
'(--quiet -q)'{--quiet,-q}"[Only validate the configuration, don't print anything.]" \
|
'(--quiet -q)'{--quiet,-q}"[Only validate the configuration, don't print anything.]" \
|
||||||
'--resolve-image-digests[Pin image tags to digests.]' \
|
'--resolve-image-digests[Pin image tags to digests.]' \
|
||||||
'--services[Print the service names, one per line.]' \
|
'--services[Print the service names, one per line.]' \
|
||||||
'--volumes[Print the volume names, one per line.]' && ret=0
|
'--volumes[Print the volume names, one per line.]' \
|
||||||
|
'--hash[Print the service config hash, one per line. Set "service1,service2" for a list of specified services.]' \ && ret=0
|
||||||
;;
|
;;
|
||||||
(create)
|
(create)
|
||||||
_arguments \
|
_arguments \
|
||||||
|
@ -222,6 +222,16 @@ class CLITestCase(DockerClientTestCase):
|
|||||||
self.base_dir = 'tests/fixtures/v2-full'
|
self.base_dir = 'tests/fixtures/v2-full'
|
||||||
assert self.dispatch(['config', '--quiet']).stdout == ''
|
assert self.dispatch(['config', '--quiet']).stdout == ''
|
||||||
|
|
||||||
|
def test_config_with_hash_option(self):
|
||||||
|
self.base_dir = 'tests/fixtures/v2-full'
|
||||||
|
result = self.dispatch(['config', '--hash=*'])
|
||||||
|
for service in self.project.get_services():
|
||||||
|
assert '{} {}\n'.format(service.name, service.config_hash) in result.stdout
|
||||||
|
|
||||||
|
svc = self.project.get_service('other')
|
||||||
|
result = self.dispatch(['config', '--hash=other'])
|
||||||
|
assert result.stdout == '{} {}\n'.format(svc.name, svc.config_hash)
|
||||||
|
|
||||||
def test_config_default(self):
|
def test_config_default(self):
|
||||||
self.base_dir = 'tests/fixtures/v2-full'
|
self.base_dir = 'tests/fixtures/v2-full'
|
||||||
result = self.dispatch(['config'])
|
result = self.dispatch(['config'])
|
||||||
|
@ -701,9 +701,11 @@ class ServiceTest(unittest.TestCase):
|
|||||||
image='example.com/foo',
|
image='example.com/foo',
|
||||||
client=self.mock_client,
|
client=self.mock_client,
|
||||||
network_mode=NetworkMode('bridge'),
|
network_mode=NetworkMode('bridge'),
|
||||||
networks={'bridge': {}},
|
networks={'bridge': {}, 'net2': {}},
|
||||||
links=[(Service('one', client=self.mock_client), 'one')],
|
links=[(Service('one', client=self.mock_client), 'one')],
|
||||||
volumes_from=[VolumeFromSpec(Service('two', client=self.mock_client), 'rw', 'service')]
|
volumes_from=[VolumeFromSpec(Service('two', client=self.mock_client), 'rw', 'service')],
|
||||||
|
volumes=[VolumeSpec('/ext', '/int', 'ro')],
|
||||||
|
build={'context': 'some/random/path'},
|
||||||
)
|
)
|
||||||
config_hash = service.config_hash
|
config_hash = service.config_hash
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user