Skip to content

Commit

Permalink
Split sub-API classes into separate modules (#28) (#106)
Browse files Browse the repository at this point in the history
* It keeps the API compatibility.
* All future work should base on this structure.
  • Loading branch information
achimnol committed Aug 15, 2017
1 parent 49c3601 commit 6f4f729
Show file tree
Hide file tree
Showing 7 changed files with 479 additions and 444 deletions.
251 changes: 251 additions & 0 deletions aiodocker/containers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,251 @@
import json

from .exceptions import DockerError
from .jsonstream import json_stream_result
from .multiplexed import multiplexed_result
from .utils import identical, parse_result

from .logs import DockerLog


class DockerContainers(object):
def __init__(self, docker):
self.docker = docker

async def list(self, **kwargs):
data = await self.docker._query_json(
"containers/json",
method='GET',
params=kwargs
)
return [DockerContainer(self.docker, **x) for x in data]

async def create_or_replace(self, name, config):
container = None

try:
container = await self.get(name)
if not identical(config, container._container):
running = container._container.get(
"State", {}).get("Running", False)
if running:
await container.stop()
await container.delete()
container = None
except DockerError:
pass

if container is None:
container = await self.create(config, name=name)

return container

async def create(self, config, name=None):
url = "containers/create"

config = json.dumps(config, sort_keys=True).encode('utf-8')
kwargs = {}
if name:
kwargs['name'] = name
data = await self.docker._query_json(
url,
method='POST',
headers={"content-type": "application/json"},
data=config,
params=kwargs
)
return DockerContainer(self.docker, id=data['Id'])

async def run(self, config, name=None):

try:
container = await self.create(config, name)
except DockerError as e:

# image not find, try pull it

if e.status == 404:

if 'Image' in config:
try:
await self.docker.pull(config['Image'])
except DockerError as e:
raise e

container = await self.create(config, name)
else:
raise e
await container.start()
return container

async def get(self, container, **kwargs):
data = await self.docker._query_json(
"containers/{container}/json".format(container=container),
method='GET',
params=kwargs
)
return DockerContainer(self.docker, **data)

def container(self, container_id, **kwargs):
data = {
'id': container_id
}
data.update(kwargs)
return DockerContainer(self.docker, **data)


class DockerContainer:
def __init__(self, docker, **kwargs):
self.docker = docker
self._container = kwargs
self._id = self._container.get("id", self._container.get(
"ID", self._container.get("Id")))
self.logs = DockerLog(docker, self)

async def log(self, stdout=False, stderr=False, follow=False, **kwargs):
if stdout is False and stderr is False:
raise TypeError("Need one of stdout or stderr")

params = {
"stdout": stdout,
"stderr": stderr,
"follow": follow,
}
params.update(kwargs)

inspect_info = await self.show()
is_tty = inspect_info['Config']['Tty']

response = await self.docker._query(
"containers/{self._id}/logs".format(self=self),
method='GET',
params=params,
)
return (await multiplexed_result(response, follow, is_tty=is_tty))

async def copy(self, resource, **kwargs):
# TODO: this is deprecated, use get_archive instead
request = json.dumps({
"Resource": resource,
}, sort_keys=True).encode('utf-8')
data = await self.docker._query(
"containers/{self._id}/copy".format(self=self),
method='POST',
data=request,
headers={"content-type": "application/json"},
params=kwargs
)
return data

async def put_archive(self, path, data):
response = await self.docker._query(
"containers/{self._id}/archive".format(self=self),
method='PUT',
data=data,
headers={"content-type": "application/json"},
params={'path': path}
)
data = await parse_result(response)
return data

async def show(self, **kwargs):
data = await self.docker._query_json(
"containers/{self._id}/json".format(self=self),
method='GET',
params=kwargs
)
self._container = data
return data

async def stop(self, **kwargs):
response = await self.docker._query(
"containers/{self._id}/stop".format(self=self),
method='POST',
params=kwargs
)
await response.release()
return

async def start(self, **kwargs):
response = await self.docker._query(
"containers/{self._id}/start".format(self=self),
method='POST',
headers={"content-type": "application/json"},
data=kwargs
)
await response.release()
return

async def kill(self, **kwargs):
response = await self.docker._query(
"containers/{self._id}/kill".format(self=self),
method='POST',
params=kwargs
)
await response.release()
return

async def wait(self, timeout=None, **kwargs):
data = await self.docker._query_json(
"containers/{self._id}/wait".format(self=self),
method='POST',
params=kwargs,
timeout=timeout,
)
return data

async def delete(self, **kwargs):
response = await self.docker._query(
"containers/{self._id}".format(self=self),
method='DELETE',
params=kwargs
)
await response.release()
return

async def websocket(self, **params):
path = "containers/{self._id}/attach/ws".format(self=self)
ws = await self.docker._websocket(path, **params)
return ws

async def port(self, private_port):
if 'NetworkSettings' not in self._container:
await self.show()

private_port = str(private_port)
h_ports = None

# Port settings is None when the container is running with
# network_mode=host.
port_settings = self._container.get('NetworkSettings', {}).get('Ports')
if port_settings is None:
return None

if '/' in private_port:
return port_settings.get(private_port)

h_ports = port_settings.get(private_port + '/tcp')
if h_ports is None:
h_ports = port_settings.get(private_port + '/udp')

return h_ports

async def stats(self, stream=True):
if stream:
response = await self.docker._query(
"containers/{self._id}/stats".format(self=self),
params={'stream': '1'},
)
return (await json_stream_result(response))
else:
data = await self.docker._query_json(
"containers/{self._id}/stats".format(self=self),
params={'stream': '0'},
)
return data

def __getitem__(self, key):
return self._container[key]

def __hasitem__(self, key):
return key in self._container

0 comments on commit 6f4f729

Please sign in to comment.