Hi, I recently started to fiddle with libcloud, but quickly figured its docker driver wasn't quite as useful as I have hoped. I've been unable to figure the port mapping information as well as the IP of the container; and IIRC libcloud outright failed on some JSON data my docker 0.11 installation returned.
Attached is a patch that helped me get the required information. However, it's far from perfect. Ideally, I think that information should be stored in the Container object. Does the existing version work for anybody? With what version of docker? Do we need to support multiple versions with different interfaces? Is it worth polishing that patch or is somebody else already working on something similar? Kind Regards Markus Wanner
diff --git a/libcloud/container/drivers/docker.py b/libcloud/container/drivers/docker.py index ae360cf..9b4d6c2 100644 --- a/libcloud/container/drivers/docker.py +++ b/libcloud/container/drivers/docker.py @@ -293,7 +293,8 @@ class DockerContainerDriver(ContainerDriver): volumes=None, volumes_from=None, network_disabled=False, entrypoint=None, cpu_shares=None, working_dir='', domainname=None, - memswap_limit=0, port_bindings=None): + memswap_limit=0, port_bindings=None, + host_config=None): """ Deploy an installed container image @@ -345,6 +346,7 @@ class DockerContainerDriver(ContainerDriver): 'MemorySwap': memswap_limit, 'PublishAllPorts': True, 'PortBindings': port_bindings, + 'HostConfig': host_config } data = json.dumps(payload) @@ -467,6 +469,23 @@ class DockerContainerDriver(ContainerDriver): method='DELETE') return result.status in VALID_RESPONSE_CODES + def ex_inspect_container(self, id): + """ + Inspect a container + + :param container: The container to be inspected + :type container: :class:`libcloud.container.base.Container` + + :return: Information about the container. + :rtype: ``dict`` + """ + result = self.connection.request('/containers/%s/json' % id) + if result.status in VALID_RESPONSE_CODES: + return result.parse_body() + else: + raise DockerException(result.status, + 'failed to inspect container') + def ex_list_processes(self, container): """ List processes running inside a container @@ -600,18 +619,19 @@ class DockerContainerDriver(ContainerDriver): if state is not None else None) if 'Exited' in status: state = ContainerState.STOPPED - elif status.startswith('Up '): + elif status.startswith('Up ') or status.startswith('running'): state = ContainerState.RUNNING else: state = ContainerState.STOPPED image = data.get('Image') - ports = data.get('Ports', []) + ports = data.get('NetworkSettings', {}).get('Ports', []) created = data.get('Created') if isinstance(created, float): created = ts_to_str(created) extra = { 'id': data.get('Id'), 'status': data.get('Status'), + 'state': data.get('State'), 'created': created, 'image': image, 'ports': ports, @@ -620,10 +640,14 @@ class DockerContainerDriver(ContainerDriver): 'sizerootfs': data.get('SizeRootFs'), } ips = [] + port_mappings = {} if ports is not None: - for port in ports: - if port.get('IP') is not None: - ips.append(port.get('IP')) + for port, portmappings in ports.iteritems(): + for portmapping in portmappings: + host_ip = portmapping.get('HostIp', None) + host_port = int(portmapping.get('HostPort', None)) + port_mappings[port] = (host_ip, host_port) + extra['port_mappings'] = port_mappings return Container( id=data['Id'], name=name,