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:
Toshio Kuratomi 2015-03-09 09:58:06 -07:00
commit e398933210

View file

@ -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)