Flesh out some more docker container methods
First cut of Docker container creation and start should be working now Tested using the REST API: curl -i -X POST -H 'X-Auth-Token: 1b238d90cd0645a39a626581cf0c9f19' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -d '{"image_id": "cirros", "name": "mycontainer"}' \ http://127.0.0.1:9511/v1/v1/containers curl -i -X PUT -H 'X-Auth-Token: 1b238d90cd0645a39a626581cf0c9f19' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'User-Agent: python-magnumclient' \ http://127.0.0.1:9511/v1/containers/4e19a981-057f-4d55-9aaf-d12c06e6430a/start And the magnum CLI: echo '{"name":"mycontainer", "image_id":"cirros"}' | magnum --debug container-create magnum --debug container-start --id c6d6c759-9875-4dd4-aaa3-619799015c1d Change-Id: Ib7a46d95d2d89cd8479bb0a318a3c9efaf23f187
This commit is contained in:
parent
51d3cb88a6
commit
df4e64186e
|
@ -26,9 +26,13 @@ from magnum.api.controllers import link
|
|||
from magnum.api.controllers.v1 import collection
|
||||
from magnum.api.controllers.v1 import types
|
||||
from magnum.api.controllers.v1 import utils as api_utils
|
||||
from magnum.common import context
|
||||
from magnum.common import exception
|
||||
from magnum.conductor import api
|
||||
from magnum import objects
|
||||
from magnum.openstack.common import log as logging
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class ContainerPatchType(types.JsonPatchType):
|
||||
|
@ -76,6 +80,9 @@ class Container(base.APIBase):
|
|||
name = wtypes.text
|
||||
"""Name of this container"""
|
||||
|
||||
image_id = wtypes.text
|
||||
"""The image name or UUID to use as a base image for this baymodel"""
|
||||
|
||||
links = wsme.wsattr([link.Link], readonly=True)
|
||||
"""A list containing a self link and associated container links"""
|
||||
|
||||
|
@ -103,7 +110,7 @@ class Container(base.APIBase):
|
|||
@staticmethod
|
||||
def _convert_with_links(container, url, expand=True):
|
||||
if not expand:
|
||||
container.unset_fields_except(['uuid', 'name'])
|
||||
container.unset_fields_except(['uuid', 'name', 'image_id'])
|
||||
|
||||
# never expose the container_id attribute
|
||||
container.container_id = wtypes.Unset
|
||||
|
@ -126,6 +133,7 @@ class Container(base.APIBase):
|
|||
def sample(cls, expand=True):
|
||||
sample = cls(uuid='27e3153e-d5bf-4b7e-b517-fb518e17f34c',
|
||||
name='example',
|
||||
image_id='ubuntu',
|
||||
created_at=datetime.datetime.utcnow(),
|
||||
updated_at=datetime.datetime.utcnow())
|
||||
# NOTE(lucasagomes): container_uuid getter() method look at the
|
||||
|
@ -158,52 +166,64 @@ class ContainerCollection(collection.Collection):
|
|||
sample.containers = [Container.sample(expand=False)]
|
||||
return sample
|
||||
|
||||
backend_api = api.API(context=context.RequestContext())
|
||||
|
||||
|
||||
class StartController(object):
|
||||
@wsme_pecan.wsexpose(wtypes.text, wtypes.text)
|
||||
def _default(self, container_uuid):
|
||||
return "Start Container %s" % container_uuid
|
||||
def _default(self, uuid):
|
||||
LOG.debug('Calling backend_api.container_start with %s' % uuid)
|
||||
return backend_api.container_start(uuid)
|
||||
|
||||
|
||||
class StopController(object):
|
||||
@wsme_pecan.wsexpose(wtypes.text, wtypes.text)
|
||||
def _default(self, container_uuid, *remainder):
|
||||
return "Stop Container %s" % container_uuid
|
||||
def _default(self, uuid, *remainder):
|
||||
LOG.debug('Calling backend_api.container_stop with %s' % uuid)
|
||||
return backend_api.container_stop(uuid)
|
||||
|
||||
|
||||
class RebootController(object):
|
||||
@wsme_pecan.wsexpose(wtypes.text, wtypes.text)
|
||||
def _default(self, container_uuid, *remainder):
|
||||
return "Reboot Container %s" % container_uuid
|
||||
def _default(self, uuid, *remainder):
|
||||
LOG.debug('Calling backend_api.container_reboot with %s' % uuid)
|
||||
return backend_api.container_reboot(uuid)
|
||||
|
||||
|
||||
class PauseController(object):
|
||||
@wsme_pecan.wsexpose(wtypes.text, wtypes.text)
|
||||
def _default(self, container_uuid, *remainder):
|
||||
return "Pause Container %s" % container_uuid
|
||||
def _default(self, uuid, *remainder):
|
||||
LOG.debug('Calling backend_api.container_pause with %s' % uuid)
|
||||
return backend_api.container_pause(uuid)
|
||||
|
||||
|
||||
class UnpauseController(object):
|
||||
@wsme_pecan.wsexpose(wtypes.text, wtypes.text)
|
||||
def _default(self, container_uuid, *remainder):
|
||||
return "Unpause Container %s" % container_uuid
|
||||
def _default(self, uuid, *remainder):
|
||||
LOG.debug('Calling backend_api.container_unpause with %s' % uuid)
|
||||
return backend_api.container_unpause(uuid)
|
||||
|
||||
|
||||
class LogsController(object):
|
||||
@wsme_pecan.wsexpose(wtypes.text, wtypes.text)
|
||||
def _default(self, container_uuid, *remainder):
|
||||
return "Logs Container %s" % container_uuid
|
||||
def _default(self, uuid, *remainder):
|
||||
LOG.debug('Calling backend_api.container_logs with %s' % uuid)
|
||||
return backend_api.container_logs(uuid)
|
||||
|
||||
|
||||
class ExecuteController(object):
|
||||
@wsme_pecan.wsexpose(wtypes.text, wtypes.text)
|
||||
def _default(self, container_uuid, *remainder):
|
||||
return "Execute Container %s" % container_uuid
|
||||
def _default(self, uuid, *remainder):
|
||||
LOG.debug('Calling backend_api.container_execute with %s' % uuid)
|
||||
backend_api.container_execute(uuid)
|
||||
|
||||
|
||||
class ContainersController(rest.RestController):
|
||||
"""REST controller for Containers."""
|
||||
|
||||
def __init__(self):
|
||||
super(ContainersController, self).__init__()
|
||||
|
||||
start = StartController()
|
||||
stop = StopController()
|
||||
reboot = RebootController()
|
||||
|
@ -306,10 +326,12 @@ class ContainersController(rest.RestController):
|
|||
new_container = objects.Container(pecan.request.context,
|
||||
**container.as_dict())
|
||||
new_container.create()
|
||||
res_container = backend_api.container_create(new_container.uuid,
|
||||
new_container)
|
||||
# Set the HTTP Location Header
|
||||
pecan.response.location = link.build_url('containers',
|
||||
new_container.uuid)
|
||||
return Container.convert_with_links(new_container)
|
||||
res_container.uuid)
|
||||
return Container.convert_with_links(res_container)
|
||||
|
||||
@wsme.validate(types.uuid, [ContainerPatchType])
|
||||
@wsme_pecan.wsexpose(Container, types.uuid, body=[ContainerPatchType])
|
||||
|
|
|
@ -22,7 +22,7 @@ from oslo.config import cfg
|
|||
|
||||
from magnum.common import rpc_service as service
|
||||
from magnum.conductor.handlers import bay_ironic as bay_ironic
|
||||
from magnum.conductor.handlers import docker as docker_conductor
|
||||
from magnum.conductor.handlers import docker_conductor
|
||||
from magnum.conductor.handlers import kube as k8s_conductor
|
||||
from magnum.openstack.common._i18n import _
|
||||
from magnum.openstack.common import log as logging
|
||||
|
|
|
@ -90,7 +90,7 @@ class API(rpc_service.API):
|
|||
# Container operations
|
||||
|
||||
def container_create(self, uuid, container):
|
||||
return self._call('container_create', container=container)
|
||||
return self._call('container_create', uuid=uuid, container=container)
|
||||
|
||||
def container_list(self, context, limit, marker, sort_key, sort_dir):
|
||||
return objects.Container.list(context, limit, marker, sort_key,
|
||||
|
|
|
@ -1,120 +0,0 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
"""Magnum Docker RPC handler."""
|
||||
|
||||
from docker import Client
|
||||
from docker import tls
|
||||
from oslo.config import cfg
|
||||
|
||||
from magnum.openstack.common import log as logging
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
CONF = cfg.CONF
|
||||
|
||||
docker_opts = [
|
||||
cfg.StrOpt('host_url',
|
||||
help='tcp://host:port to bind/connect to or'
|
||||
'unix://path/to/socker to use'),
|
||||
cfg.BoolOpt('api_secure',
|
||||
default=False,
|
||||
help='If set, ignore any SSL validation issues'),
|
||||
cfg.StrOpt('ca_file',
|
||||
help='Location of CA certificate file for '
|
||||
'securing docker api requests (tlscacert).'),
|
||||
cfg.StrOpt('cert_file',
|
||||
help='Location of TLS certificate file for '
|
||||
'securing docker api requests (tlscert).'),
|
||||
cfg.StrOpt('key_file',
|
||||
help='Location of TLS private key file for '
|
||||
'securing docker api requests (tlskey).'),
|
||||
]
|
||||
|
||||
CONF.register_opts(docker_opts, 'docker')
|
||||
|
||||
# These are the backend operations. They are executed by the backend
|
||||
# service. API calls via AMQP (within the ReST API) trigger the handlers to
|
||||
# be called.
|
||||
|
||||
|
||||
class Handler(object):
|
||||
|
||||
def __init__(self, url):
|
||||
super(Handler, self).__init__()
|
||||
if (CONF.docker.cert_file or
|
||||
CONF.docker.key_file):
|
||||
client_cert = (CONF.docker.cert_file, CONF.docker.key_file)
|
||||
else:
|
||||
client_cert = None
|
||||
if (CONF.docker.ca_file or
|
||||
CONF.docker.api_insecure or
|
||||
client_cert):
|
||||
tls_config = tls.TLSConfig(
|
||||
client_cert=client_cert,
|
||||
ca_Cert=CONF.docker.ca_file,
|
||||
verify=CONF.docker.api_insecure)
|
||||
else:
|
||||
tls_config = None
|
||||
self.client = Client(base_url=url, tls=tls_config)
|
||||
|
||||
def encode_utf8(self, value):
|
||||
return unicode(value).encode('utf-8')
|
||||
|
||||
# Container operations
|
||||
|
||||
def container_create(self, bay_uuid, image_name, command):
|
||||
LOG.debug("container_create %s contents=%s" % (bay_uuid, image_name))
|
||||
self.client.inspect_image(self._encode_utf8(image_name))
|
||||
container_id = self.client.create_container(image_name, command)
|
||||
self.container_start(container_id)
|
||||
|
||||
def container_list(self, bay_uuid):
|
||||
LOG.debug("container_list")
|
||||
container_list = self.client.containers()
|
||||
return container_list
|
||||
# return container list dict
|
||||
|
||||
def container_delete(self, bay_uuid, container_id):
|
||||
LOG.debug("cotainer_delete %s" % bay_uuid)
|
||||
return None
|
||||
|
||||
def container_show(self, bay_uuid, container_id):
|
||||
LOG.debug("container_show %s" % bay_uuid)
|
||||
return None
|
||||
|
||||
def container_reboot(self, bay_uuid, container_id):
|
||||
LOG.debug("container_reboot %s" % bay_uuid)
|
||||
return None
|
||||
|
||||
def container_stop(self, bay_uuid, container_id):
|
||||
LOG.debug("container_stop %s" % bay_uuid)
|
||||
self.client.start(container_id)
|
||||
|
||||
def container_start(self, bay_uuid, container_id):
|
||||
LOG.debug("container_start %s" % bay_uuid)
|
||||
self.client.start(container_id)
|
||||
|
||||
def container_pause(self, bay_uuid, container_id):
|
||||
LOG.debug("container_pause %s" % bay_uuid)
|
||||
return None
|
||||
|
||||
def container_unpause(self, bay_uuid, container_id):
|
||||
LOG.debug("container_unpause %s" % bay_uuid)
|
||||
return None
|
||||
|
||||
def container_logs(self, bay_uuid, container_id):
|
||||
LOG.debug("container_logs %s" % bay_uuid)
|
||||
return None
|
||||
|
||||
def container_execute(self, bay_uuid, container_id):
|
||||
LOG.debug("container_execute %s" % bay_uuid)
|
||||
return None
|
|
@ -0,0 +1,191 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
"""Magnum Docker RPC handler."""
|
||||
|
||||
from docker import client
|
||||
from docker import errors
|
||||
from docker import tls
|
||||
from oslo.config import cfg
|
||||
|
||||
from magnum.openstack.common import log as logging
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
CONF = cfg.CONF
|
||||
|
||||
docker_opts = [
|
||||
cfg.StrOpt('root_directory',
|
||||
default='/var/lib/docker',
|
||||
help='Path to use as the root of the Docker runtime.'),
|
||||
cfg.StrOpt('host_url',
|
||||
default='unix:///var/run/docker.sock',
|
||||
help='tcp://host:port to bind/connect to or '
|
||||
'unix://path/to/socket to use'),
|
||||
cfg.BoolOpt('api_insecure',
|
||||
default=False,
|
||||
help='If set, ignore any SSL validation issues'),
|
||||
cfg.StrOpt('ca_file',
|
||||
help='Location of CA certificates file for '
|
||||
'securing docker api requests (tlscacert).'),
|
||||
cfg.StrOpt('cert_file',
|
||||
help='Location of TLS certificate file for '
|
||||
'securing docker api requests (tlscert).'),
|
||||
cfg.StrOpt('key_file',
|
||||
help='Location of TLS private key file for '
|
||||
'securing docker api requests (tlskey).'),
|
||||
]
|
||||
|
||||
CONF.register_opts(docker_opts, 'docker')
|
||||
|
||||
|
||||
class DockerHTTPClient(client.Client):
|
||||
def __init__(self, url='unix://var/run/docker.sock'):
|
||||
if (CONF.docker.cert_file or
|
||||
CONF.docker.key_file):
|
||||
client_cert = (CONF.docker.cert_file, CONF.docker.key_file)
|
||||
else:
|
||||
client_cert = None
|
||||
if (CONF.docker.ca_file or
|
||||
CONF.docker.api_insecure or
|
||||
client_cert):
|
||||
ssl_config = tls.TLSConfig(
|
||||
client_cert=client_cert,
|
||||
ca_cert=CONF.docker.ca_file,
|
||||
verify=CONF.docker.api_insecure)
|
||||
else:
|
||||
ssl_config = False
|
||||
super(DockerHTTPClient, self).__init__(
|
||||
base_url=url,
|
||||
version='1.13',
|
||||
timeout=10,
|
||||
tls=ssl_config
|
||||
)
|
||||
|
||||
def list_instances(self, inspect=False):
|
||||
res = []
|
||||
for container in self.containers(all=True):
|
||||
info = self.inspect_container(container['Id'])
|
||||
if not info:
|
||||
continue
|
||||
if inspect:
|
||||
res.append(info)
|
||||
else:
|
||||
res.append(info['Config'].get('Hostname'))
|
||||
return res
|
||||
|
||||
def pause(self, container_id):
|
||||
url = self._url("/containers/{0}/pause".format(container_id))
|
||||
res = self._post(url)
|
||||
return res.status_code == 204
|
||||
|
||||
def unpause(self, container_id):
|
||||
url = self._url("/containers/{0}/unpause".format(container_id))
|
||||
res = self._post(url)
|
||||
return res.status_code == 204
|
||||
|
||||
def load_repository_file(self, name, path):
|
||||
with open(path) as fh:
|
||||
self.load_image(fh)
|
||||
|
||||
def get_container_logs(self, container_id):
|
||||
return self.attach(container_id, 1, 1, 0, 1)
|
||||
|
||||
|
||||
# These are the backend operations. They are executed by the backend
|
||||
# service. API calls via AMQP (within the ReST API) trigger the handlers to
|
||||
# be called.
|
||||
|
||||
|
||||
class Handler(object):
|
||||
|
||||
def __init__(self):
|
||||
super(Handler, self).__init__()
|
||||
self._docker = None
|
||||
|
||||
@property
|
||||
def docker(self):
|
||||
if self._docker is None:
|
||||
self._docker = DockerHTTPClient(CONF.docker.host_url)
|
||||
return self._docker
|
||||
|
||||
def _find_container_by_name(self, name):
|
||||
try:
|
||||
for info in self.docker.list_instances(inspect=True):
|
||||
if info['Config'].get('Hostname') == name:
|
||||
return info
|
||||
except errors.APIError as e:
|
||||
if e.response.status_code != 404:
|
||||
raise
|
||||
return {}
|
||||
|
||||
def _encode_utf8(self, value):
|
||||
return unicode(value).encode('utf-8')
|
||||
|
||||
# Container operations
|
||||
|
||||
def container_create(self, ctxt, uuid, container):
|
||||
LOG.debug('Creating container with image %s' % container.image_id)
|
||||
self.docker.inspect_image(self._encode_utf8(container.image_id))
|
||||
self.docker.create_container(container.image_id, name=uuid,
|
||||
hostname=uuid)
|
||||
return container
|
||||
|
||||
def container_list(self, ctxt):
|
||||
LOG.debug("container_list")
|
||||
container_list = self.docker.containers()
|
||||
return container_list
|
||||
|
||||
def container_delete(self, ctxt, uuid):
|
||||
LOG.debug("container_delete %s" % uuid)
|
||||
container_id = self._find_container_by_name(uuid)
|
||||
return self.docker.stop(container_id)
|
||||
|
||||
def container_show(self, ctxt, uuid):
|
||||
LOG.debug("container_show %s" % uuid)
|
||||
container_id = self._find_container_by_name(uuid)
|
||||
return self.docker.inspect_container(container_id)
|
||||
|
||||
def container_reboot(self, ctxt, uuid):
|
||||
LOG.debug("container_reboot %s" % uuid)
|
||||
container_id = self._find_container_by_name(uuid)
|
||||
return self.docker.restart(container_id)
|
||||
|
||||
def container_stop(self, ctxt, uuid):
|
||||
LOG.debug("container_stop %s" % uuid)
|
||||
container_id = self._find_container_by_name(uuid)
|
||||
return self.docker.stop(container_id)
|
||||
|
||||
def container_start(self, ctxt, uuid):
|
||||
LOG.debug("Starting container %s" % uuid)
|
||||
container_id = self._find_container_by_name(uuid)
|
||||
LOG.debug("Found Docker container %s" % container_id)
|
||||
return self.docker.start(container_id)
|
||||
|
||||
def container_pause(self, ctxt, uuid):
|
||||
LOG.debug("container_pause %s" % uuid)
|
||||
container_id = self._find_container_by_name(uuid)
|
||||
return self.docker.pause(container_id)
|
||||
|
||||
def container_unpause(self, ctxt, uuid):
|
||||
LOG.debug("container_unpause %s" % uuid)
|
||||
container_id = self._find_container_by_name(uuid)
|
||||
return self.docker.unpause(container_id)
|
||||
|
||||
def container_logs(self, ctxt, uuid):
|
||||
LOG.debug("container_logs %s" % uuid)
|
||||
container_id = self._find_container_by_name(uuid)
|
||||
return self.docker.get_container_logs(container_id)
|
||||
|
||||
def container_execute(self, ctxt, uuid):
|
||||
LOG.debug("container_execute %s" % uuid)
|
||||
container_id = self._find_container_by_name(uuid)
|
||||
return self.docker.execute(container_id, "ls")
|
|
@ -1,57 +0,0 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import docker
|
||||
|
||||
from magnum import base
|
||||
|
||||
|
||||
class DockerContainerFactory(base.ContainerFactory):
|
||||
def __init__(self, pod_id, client=None):
|
||||
self.docker = client or docker.Client()
|
||||
|
||||
def create(self, *args, **kwargs):
|
||||
self.docker.create_container(**kwargs)
|
||||
self.docker.start(self.container_id)
|
||||
|
||||
def list(self):
|
||||
return self.docker.containers()
|
||||
|
||||
|
||||
class DockerContainer(base.Container):
|
||||
def __init__(self, client, container_id):
|
||||
self.docker = client
|
||||
self.container_id = container_id
|
||||
|
||||
def info(self):
|
||||
self.docker.inspect(self.container_id)
|
||||
|
||||
def reboot(self):
|
||||
self.docker.reboot(self.container_id)
|
||||
|
||||
def kill(self):
|
||||
self.docker.kill(self.container_id)
|
||||
|
||||
def destroy(self):
|
||||
self.docker.destroy(self.container_id)
|
||||
|
||||
def logs(self):
|
||||
return self.docker.logs(self.container_id)
|
||||
|
||||
def pause(self):
|
||||
self.docker.pause(self.container_id)
|
||||
|
||||
def unpause(self):
|
||||
self.docker.unpause(self.container_id)
|
||||
|
||||
def execute(self, cmd):
|
||||
return self.docker.execute(self.container_id, cmd)
|
|
@ -64,6 +64,9 @@ def upgrade():
|
|||
sa.Column('created_at', sa.DateTime(), nullable=True),
|
||||
sa.Column('updated_at', sa.DateTime(), nullable=True),
|
||||
sa.Column('id', sa.Integer(), nullable=False),
|
||||
sa.Column('uuid', sa.String(length=36), nullable=True),
|
||||
sa.Column('name', sa.String(length=255), nullable=True),
|
||||
sa.Column('image_id', sa.String(length=255), nullable=True),
|
||||
sa.PrimaryKeyConstraint('id'),
|
||||
mysql_ENGINE='InnoDB',
|
||||
mysql_DEFAULT_CHARSET='UTF8'
|
||||
|
|
|
@ -155,6 +155,7 @@ class Container(Base):
|
|||
id = Column(Integer, primary_key=True)
|
||||
uuid = Column(String(36))
|
||||
name = Column(String(255))
|
||||
image_id = Column(String(255))
|
||||
|
||||
|
||||
class Node(Base):
|
||||
|
|
|
@ -35,6 +35,7 @@ class Container(base.MagnumObject):
|
|||
'id': int,
|
||||
'uuid': obj_utils.str_or_none,
|
||||
'name': obj_utils.str_or_none,
|
||||
'image_id': obj_utils.str_or_none,
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
|
|
|
@ -252,9 +252,34 @@ class TestPodController(db_base.DbTestCase):
|
|||
|
||||
|
||||
class TestContainerController(db_base.DbTestCase):
|
||||
def test_containers_api(self):
|
||||
@patch('magnum.conductor.api.API.container_create')
|
||||
@patch('magnum.conductor.api.API.container_start')
|
||||
@patch('magnum.conductor.api.API.container_stop')
|
||||
@patch('magnum.conductor.api.API.container_pause')
|
||||
@patch('magnum.conductor.api.API.container_unpause')
|
||||
@patch('magnum.conductor.api.API.container_reboot')
|
||||
@patch('magnum.conductor.api.API.container_logs')
|
||||
@patch('magnum.conductor.api.API.container_execute')
|
||||
def test_containers_api(self,
|
||||
mock_container_execute,
|
||||
mock_container_logs,
|
||||
mock_container_reboot,
|
||||
mock_container_unpause,
|
||||
mock_container_pause,
|
||||
mock_container_stop,
|
||||
mock_container_start,
|
||||
mock_container_create):
|
||||
mock_container_create.side_effect = lambda x, y: y
|
||||
mock_container_start.return_value = None
|
||||
mock_container_stop.return_value = None
|
||||
mock_container_pause.return_value = None
|
||||
mock_container_unpause.return_value = None
|
||||
mock_container_reboot.return_value = None
|
||||
mock_container_logs.return_value = None
|
||||
mock_container_execute.return_value = None
|
||||
|
||||
# Create a container
|
||||
params = '{"name": "My Docker"}'
|
||||
params = '{"name": "My Docker", "image_id": "ubuntu"}'
|
||||
response = self.app.post('/v1/containers',
|
||||
params=params,
|
||||
content_type='application/json')
|
||||
|
|
Loading…
Reference in New Issue