Merge pull request #912 from smashwilson/image-exposed-things
[docker] Account for configuration performed in the image for state=reloaded
This commit is contained in:
commit
e398933210
1 changed files with 51 additions and 38 deletions
|
@ -725,16 +725,24 @@ class DockerManager(object):
|
|||
return False
|
||||
|
||||
def get_inspect_image(self):
|
||||
try:
|
||||
return self.client.inspect_image(self.module.params.get('image'))
|
||||
except DockerAPIError as e:
|
||||
if e.response.status_code == 404:
|
||||
return None
|
||||
else:
|
||||
raise e
|
||||
|
||||
def get_image_repo_tags(self):
|
||||
image, tag = get_split_image_tag(self.module.params.get('image'))
|
||||
if tag is None:
|
||||
tag = 'latest'
|
||||
resource = '%s:%s' % (image, tag)
|
||||
|
||||
matching_image = None
|
||||
for image in self.client.images(name=image):
|
||||
if resource in image.get('RepoTags', []):
|
||||
matching_image = image
|
||||
return matching_image
|
||||
return image['RepoTags']
|
||||
return None
|
||||
|
||||
def get_inspect_containers(self, containers):
|
||||
inspect = []
|
||||
|
@ -779,7 +787,7 @@ class DockerManager(object):
|
|||
# will be restarted when new versions of an existing image are
|
||||
# pulled.
|
||||
if container['Image'] != image['Id']:
|
||||
self.reload_reasons.append('image ({} => {})'.format(container['Image'], image['Id']))
|
||||
self.reload_reasons.append('image ({0} => {1})'.format(container['Image'], image['Id']))
|
||||
differing.append(container)
|
||||
continue
|
||||
|
||||
|
@ -791,36 +799,32 @@ class DockerManager(object):
|
|||
actual_command = container["Config"]["Cmd"]
|
||||
|
||||
if actual_command != expected_command:
|
||||
self.reload_reasons.append('command ({} => {})'.format(actual_command, expected_command))
|
||||
self.reload_reasons.append('command ({0} => {1})'.format(actual_command, expected_command))
|
||||
differing.append(container)
|
||||
continue
|
||||
|
||||
# EXPOSED PORTS
|
||||
# Note that ports that are bound at container run are also exposed
|
||||
# implicitly.
|
||||
expected_exposed_ports = set()
|
||||
expected_exposed_ports = set((image['ContainerConfig']['ExposedPorts'] or {}).keys())
|
||||
for p in (self.exposed_ports or []):
|
||||
expected_exposed_ports.add("/".join(p))
|
||||
|
||||
actually_exposed_ports = set((container["Config"]["ExposedPorts"] or {}).keys())
|
||||
|
||||
if actually_exposed_ports != expected_exposed_ports:
|
||||
self.reload_reasons.append('exposed_ports ({} => {})'.format(actually_exposed_ports, expected_exposed_ports))
|
||||
self.reload_reasons.append('exposed_ports ({0} => {1})'.format(actually_exposed_ports, expected_exposed_ports))
|
||||
differing.append(container)
|
||||
continue
|
||||
|
||||
# VOLUMES
|
||||
# not including bind modes.
|
||||
|
||||
expected_volume_keys = set()
|
||||
expected_volume_keys = set((image['ContainerConfig']['Volumes'] or {}).keys())
|
||||
if self.volumes:
|
||||
for key, config in self.volumes.iteritems():
|
||||
if not config and key not in self.binds:
|
||||
expected_volume_keys.add(key)
|
||||
expected_volume_keys.update(self.volumes.keys())
|
||||
|
||||
actual_volume_keys = set((container['Config']['Volumes'] or {}).keys())
|
||||
|
||||
if actual_volume_keys != expected_volume_keys:
|
||||
self.reload_reasons.append('volumes ({} => {})'.format(actual_volume_keys, expected_volume_keys))
|
||||
self.reload_reasons.append('volumes ({0} => {1})'.format(actual_volume_keys, expected_volume_keys))
|
||||
differing.append(container)
|
||||
continue
|
||||
|
||||
|
@ -830,7 +834,7 @@ class DockerManager(object):
|
|||
actual_mem = container['Config']['Memory']
|
||||
|
||||
if expected_mem and actual_mem != expected_mem:
|
||||
self.reload_reasons.append('memory ({} => {})'.format(actual_mem, expected_mem))
|
||||
self.reload_reasons.append('memory ({0} => {1})'.format(actual_mem, expected_mem))
|
||||
differing.append(container)
|
||||
continue
|
||||
|
||||
|
@ -838,13 +842,22 @@ class DockerManager(object):
|
|||
# actual_env is likely to include environment variables injected by
|
||||
# the Dockerfile.
|
||||
|
||||
expected_env = set()
|
||||
expected_env = {}
|
||||
|
||||
for image_env in image['ContainerConfig']['Env'] or []:
|
||||
name, value = image_env.split('=', 1)
|
||||
expected_env[name] = value
|
||||
|
||||
if self.env:
|
||||
for name, value in self.env.iteritems():
|
||||
expected_env.add("{}={}".format(name, value))
|
||||
actual_env = set(container['Config']['Env'] or [])
|
||||
expected_env[name] = value
|
||||
|
||||
if not actual_env.issuperset(expected_env):
|
||||
actual_env = {}
|
||||
for container_env in container['Config']['Env'] or []:
|
||||
name, value = container_env.split('=', 1)
|
||||
actual_env[name] = value
|
||||
|
||||
if actual_env != expected_env:
|
||||
# Don't include the environment difference in the output.
|
||||
self.reload_reasons.append('environment')
|
||||
differing.append(container)
|
||||
|
@ -855,7 +868,7 @@ class DockerManager(object):
|
|||
expected_hostname = self.module.params.get('hostname')
|
||||
actual_hostname = container['Config']['Hostname']
|
||||
if expected_hostname and actual_hostname != expected_hostname:
|
||||
self.reload_reasons.append('hostname ({} => {})'.format(actual_hostname, expected_hostname))
|
||||
self.reload_reasons.append('hostname ({0} => {1})'.format(actual_hostname, expected_hostname))
|
||||
differing.append(container)
|
||||
continue
|
||||
|
||||
|
@ -864,7 +877,7 @@ class DockerManager(object):
|
|||
expected_domainname = self.module.params.get('domainname')
|
||||
actual_domainname = container['Config']['Domainname']
|
||||
if expected_domainname and actual_domainname != expected_domainname:
|
||||
self.reload_reasons.append('domainname ({} => {})'.format(actual_domainname, expected_domainname))
|
||||
self.reload_reasons.append('domainname ({0} => {1})'.format(actual_domainname, expected_domainname))
|
||||
differing.append(container)
|
||||
continue
|
||||
|
||||
|
@ -884,7 +897,7 @@ class DockerManager(object):
|
|||
expected_stdin_open = self.module.params.get('stdin_open')
|
||||
actual_stdin_open = container['Config']['AttachStdin']
|
||||
if actual_stdin_open != expected_stdin_open:
|
||||
self.reload_reasons.append('stdin_open ({} => {})'.format(actual_stdin_open, expected_stdin_open))
|
||||
self.reload_reasons.append('stdin_open ({0} => {1})'.format(actual_stdin_open, expected_stdin_open))
|
||||
differing.append(container)
|
||||
continue
|
||||
|
||||
|
@ -893,7 +906,7 @@ class DockerManager(object):
|
|||
expected_tty = self.module.params.get('tty')
|
||||
actual_tty = container['Config']['Tty']
|
||||
if actual_tty != expected_tty:
|
||||
self.reload_reasons.append('tty ({} => {})'.format(actual_tty, expected_tty))
|
||||
self.reload_reasons.append('tty ({0} => {1})'.format(actual_tty, expected_tty))
|
||||
differing.append(container)
|
||||
continue
|
||||
|
||||
|
@ -905,7 +918,7 @@ class DockerManager(object):
|
|||
expected_lxc = set(self.lxc_conf)
|
||||
actual_lxc = set(container['HostConfig']['LxcConf'] or [])
|
||||
if actual_lxc != expected_lxc:
|
||||
self.reload_reasons.append('lxc_conf ({} => {})'.format(actual_lxc, expected_lxc))
|
||||
self.reload_reasons.append('lxc_conf ({0} => {1})'.format(actual_lxc, expected_lxc))
|
||||
differing.append(container)
|
||||
continue
|
||||
|
||||
|
@ -923,7 +936,7 @@ class DockerManager(object):
|
|||
else:
|
||||
container_path = config
|
||||
mode = 'rw'
|
||||
expected_binds.add("{}:{}:{}".format(host_path, container_path, mode))
|
||||
expected_binds.add("{0}:{1}:{2}".format(host_path, container_path, mode))
|
||||
|
||||
actual_binds = set()
|
||||
for bind in (container['HostConfig']['Binds'] or []):
|
||||
|
@ -933,7 +946,7 @@ class DockerManager(object):
|
|||
actual_binds.add(bind)
|
||||
|
||||
if actual_binds != expected_binds:
|
||||
self.reload_reasons.append('binds ({} => {})'.format(actual_binds, expected_binds))
|
||||
self.reload_reasons.append('binds ({0} => {1})'.format(actual_binds, expected_binds))
|
||||
differing.append(container)
|
||||
continue
|
||||
|
||||
|
@ -943,7 +956,7 @@ class DockerManager(object):
|
|||
if self.port_bindings:
|
||||
for container_port, config in self.port_bindings.iteritems():
|
||||
if isinstance(container_port, int):
|
||||
container_port = "{}/tcp".format(container_port)
|
||||
container_port = "{0}/tcp".format(container_port)
|
||||
bind = {}
|
||||
if len(config) == 1:
|
||||
bind['HostIp'] = "0.0.0.0"
|
||||
|
@ -957,7 +970,7 @@ class DockerManager(object):
|
|||
actual_bound_ports = container['HostConfig']['PortBindings'] or {}
|
||||
|
||||
if actual_bound_ports != expected_bound_ports:
|
||||
self.reload_reasons.append('port bindings ({} => {})'.format(actual_bound_ports, expected_bound_ports))
|
||||
self.reload_reasons.append('port bindings ({0} => {1})'.format(actual_bound_ports, expected_bound_ports))
|
||||
differing.append(container)
|
||||
continue
|
||||
|
||||
|
@ -971,7 +984,7 @@ class DockerManager(object):
|
|||
expected_privileged = self.module.params.get('privileged')
|
||||
actual_privileged = container['HostConfig']['Privileged']
|
||||
if actual_privileged != expected_privileged:
|
||||
self.reload_reasons.append('privileged ({} => {})'.format(actual_privileged, expected_privileged))
|
||||
self.reload_reasons.append('privileged ({0} => {1})'.format(actual_privileged, expected_privileged))
|
||||
differing.append(container)
|
||||
continue
|
||||
|
||||
|
@ -979,11 +992,11 @@ class DockerManager(object):
|
|||
|
||||
expected_links = set()
|
||||
for link, alias in (self.links or {}).iteritems():
|
||||
expected_links.add("/{}:/running/{}".format(link, alias))
|
||||
expected_links.add("/{0}:/running/{1}".format(link, alias))
|
||||
|
||||
actual_links = set(container['HostConfig']['Links'] or [])
|
||||
if actual_links != expected_links:
|
||||
self.reload_reasons.append('links ({} => {})'.format(actual_links, expected_links))
|
||||
self.reload_reasons.append('links ({0} => {1})'.format(actual_links, expected_links))
|
||||
differing.append(container)
|
||||
continue
|
||||
|
||||
|
@ -992,7 +1005,7 @@ class DockerManager(object):
|
|||
expected_netmode = self.module.params.get('net') or ''
|
||||
actual_netmode = container['HostConfig']['NetworkMode']
|
||||
if actual_netmode != expected_netmode:
|
||||
self.reload_reasons.append('net ({} => {})'.format(actual_netmode, expected_netmode))
|
||||
self.reload_reasons.append('net ({0} => {1})'.format(actual_netmode, expected_netmode))
|
||||
differing.append(container)
|
||||
continue
|
||||
|
||||
|
@ -1001,7 +1014,7 @@ class DockerManager(object):
|
|||
expected_dns = set(self.module.params.get('dns') or [])
|
||||
actual_dns = set(container['HostConfig']['Dns'] or [])
|
||||
if actual_dns != expected_dns:
|
||||
self.reload_reasons.append('dns ({} => {})'.format(actual_dns, expected_dns))
|
||||
self.reload_reasons.append('dns ({0} => {1})'.format(actual_dns, expected_dns))
|
||||
differing.append(container)
|
||||
continue
|
||||
|
||||
|
@ -1010,7 +1023,7 @@ class DockerManager(object):
|
|||
expected_volumes_from = set(self.module.params.get('volumes_from') or [])
|
||||
actual_volumes_from = set(container['HostConfig']['VolumesFrom'] or [])
|
||||
if actual_volumes_from != expected_volumes_from:
|
||||
self.reload_reasons.append('volumes_from ({} => {})'.format(actual_volumes_from, expected_volumes_from))
|
||||
self.reload_reasons.append('volumes_from ({0} => {1})'.format(actual_volumes_from, expected_volumes_from))
|
||||
differing.append(container)
|
||||
|
||||
return differing
|
||||
|
@ -1032,10 +1045,10 @@ class DockerManager(object):
|
|||
# that map to the same Docker image.
|
||||
inspected = self.get_inspect_image()
|
||||
if inspected:
|
||||
images = inspected.get('RepoTags', [])
|
||||
repo_tags = self.get_image_repo_tags()
|
||||
else:
|
||||
image, tag = get_split_image_tag(self.module.params.get('image'))
|
||||
images = [':'.join([image, tag])]
|
||||
repo_tags = [':'.join([image, tag])]
|
||||
|
||||
for i in self.client.containers(all=True):
|
||||
running_image = i['Image']
|
||||
|
@ -1045,7 +1058,7 @@ class DockerManager(object):
|
|||
if name:
|
||||
matches = name in i.get('Names', [])
|
||||
else:
|
||||
image_matches = running_image in images
|
||||
image_matches = running_image in repo_tags
|
||||
|
||||
# if a container has an entrypoint, `command` will actually equal
|
||||
# '{} {}'.format(entrypoint, command)
|
||||
|
|
Loading…
Reference in a new issue