Merge "Make start/stop/pause/unpause/restart/kill action async"
This commit is contained in:
commit
62482a6acc
@ -14,6 +14,7 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
from oslo_log import log as logging
|
from oslo_log import log as logging
|
||||||
|
from oslo_utils import strutils
|
||||||
from oslo_utils import timeutils
|
from oslo_utils import timeutils
|
||||||
import pecan
|
import pecan
|
||||||
from pecan import rest
|
from pecan import rest
|
||||||
@ -28,6 +29,7 @@ from zun.common import exception
|
|||||||
from zun.common.i18n import _LE
|
from zun.common.i18n import _LE
|
||||||
from zun.common import name_generator
|
from zun.common import name_generator
|
||||||
from zun.common import policy
|
from zun.common import policy
|
||||||
|
from zun.common import utils
|
||||||
from zun.common import validation
|
from zun.common import validation
|
||||||
from zun import objects
|
from zun import objects
|
||||||
from zun.objects import fields
|
from zun.objects import fields
|
||||||
@ -330,6 +332,9 @@ class ContainersController(rest.RestController):
|
|||||||
"""
|
"""
|
||||||
container = _get_container(container_id)
|
container = _get_container(container_id)
|
||||||
check_policy_on_container(container.as_dict(), "container:delete")
|
check_policy_on_container(container.as_dict(), "container:delete")
|
||||||
|
force = strutils.bool_from_string(force, strict=True)
|
||||||
|
if not force:
|
||||||
|
utils.validate_container_state(container, 'delete')
|
||||||
context = pecan.request.context
|
context = pecan.request.context
|
||||||
pecan.request.rpcapi.container_delete(context, container, force)
|
pecan.request.rpcapi.container_delete(context, container, force)
|
||||||
container.destroy()
|
container.destroy()
|
||||||
@ -340,57 +345,60 @@ class ContainersController(rest.RestController):
|
|||||||
def start(self, container_id, **kw):
|
def start(self, container_id, **kw):
|
||||||
container = _get_container(container_id)
|
container = _get_container(container_id)
|
||||||
check_policy_on_container(container.as_dict(), "container:start")
|
check_policy_on_container(container.as_dict(), "container:start")
|
||||||
|
utils.validate_container_state(container, 'start')
|
||||||
LOG.debug('Calling compute.container_start with %s',
|
LOG.debug('Calling compute.container_start with %s',
|
||||||
container.uuid)
|
container.uuid)
|
||||||
context = pecan.request.context
|
context = pecan.request.context
|
||||||
container = pecan.request.rpcapi.container_start(context, container)
|
pecan.request.rpcapi.container_start(context, container)
|
||||||
return Container.convert_with_links(container.as_dict())
|
pecan.response.status = 202
|
||||||
|
|
||||||
@pecan.expose('json')
|
@pecan.expose('json')
|
||||||
@exception.wrap_pecan_controller_exception
|
@exception.wrap_pecan_controller_exception
|
||||||
def stop(self, container_id, timeout=None, **kw):
|
def stop(self, container_id, timeout=None, **kw):
|
||||||
container = _get_container(container_id)
|
container = _get_container(container_id)
|
||||||
check_policy_on_container(container.as_dict(), "container:stop")
|
check_policy_on_container(container.as_dict(), "container:stop")
|
||||||
|
utils.validate_container_state(container, 'stop')
|
||||||
LOG.debug('Calling compute.container_stop with %s' %
|
LOG.debug('Calling compute.container_stop with %s' %
|
||||||
container.uuid)
|
container.uuid)
|
||||||
context = pecan.request.context
|
context = pecan.request.context
|
||||||
container = pecan.request.rpcapi.container_stop(context, container,
|
pecan.request.rpcapi.container_stop(context, container, timeout)
|
||||||
timeout)
|
pecan.response.status = 202
|
||||||
return Container.convert_with_links(container.as_dict())
|
|
||||||
|
|
||||||
@pecan.expose('json')
|
@pecan.expose('json')
|
||||||
@exception.wrap_pecan_controller_exception
|
@exception.wrap_pecan_controller_exception
|
||||||
def reboot(self, container_id, timeout=None, **kw):
|
def reboot(self, container_id, timeout=None, **kw):
|
||||||
container = _get_container(container_id)
|
container = _get_container(container_id)
|
||||||
check_policy_on_container(container.as_dict(), "container:reboot")
|
check_policy_on_container(container.as_dict(), "container:reboot")
|
||||||
|
utils.validate_container_state(container, 'reboot')
|
||||||
LOG.debug('Calling compute.container_reboot with %s' %
|
LOG.debug('Calling compute.container_reboot with %s' %
|
||||||
container.uuid)
|
container.uuid)
|
||||||
context = pecan.request.context
|
context = pecan.request.context
|
||||||
container = pecan.request.rpcapi.container_reboot(context, container,
|
pecan.request.rpcapi.container_reboot(context, container, timeout)
|
||||||
timeout)
|
pecan.response.status = 202
|
||||||
return Container.convert_with_links(container.as_dict())
|
|
||||||
|
|
||||||
@pecan.expose('json')
|
@pecan.expose('json')
|
||||||
@exception.wrap_pecan_controller_exception
|
@exception.wrap_pecan_controller_exception
|
||||||
def pause(self, container_id, **kw):
|
def pause(self, container_id, **kw):
|
||||||
container = _get_container(container_id)
|
container = _get_container(container_id)
|
||||||
check_policy_on_container(container.as_dict(), "container:pause")
|
check_policy_on_container(container.as_dict(), "container:pause")
|
||||||
|
utils.validate_container_state(container, 'pause')
|
||||||
LOG.debug('Calling compute.container_pause with %s' %
|
LOG.debug('Calling compute.container_pause with %s' %
|
||||||
container.uuid)
|
container.uuid)
|
||||||
context = pecan.request.context
|
context = pecan.request.context
|
||||||
container = pecan.request.rpcapi.container_pause(context, container)
|
pecan.request.rpcapi.container_pause(context, container)
|
||||||
return Container.convert_with_links(container.as_dict())
|
pecan.response.status = 202
|
||||||
|
|
||||||
@pecan.expose('json')
|
@pecan.expose('json')
|
||||||
@exception.wrap_pecan_controller_exception
|
@exception.wrap_pecan_controller_exception
|
||||||
def unpause(self, container_id, **kw):
|
def unpause(self, container_id, **kw):
|
||||||
container = _get_container(container_id)
|
container = _get_container(container_id)
|
||||||
check_policy_on_container(container.as_dict(), "container:unpause")
|
check_policy_on_container(container.as_dict(), "container:unpause")
|
||||||
|
utils.validate_container_state(container, 'unpause')
|
||||||
LOG.debug('Calling compute.container_unpause with %s' %
|
LOG.debug('Calling compute.container_unpause with %s' %
|
||||||
container.uuid)
|
container.uuid)
|
||||||
context = pecan.request.context
|
context = pecan.request.context
|
||||||
container = pecan.request.rpcapi.container_unpause(context, container)
|
pecan.request.rpcapi.container_unpause(context, container)
|
||||||
return Container.convert_with_links(container.as_dict())
|
pecan.response.status = 202
|
||||||
|
|
||||||
@pecan.expose('json')
|
@pecan.expose('json')
|
||||||
@exception.wrap_pecan_controller_exception
|
@exception.wrap_pecan_controller_exception
|
||||||
@ -407,6 +415,7 @@ class ContainersController(rest.RestController):
|
|||||||
def execute(self, container_id, **kw):
|
def execute(self, container_id, **kw):
|
||||||
container = _get_container(container_id)
|
container = _get_container(container_id)
|
||||||
check_policy_on_container(container.as_dict(), "container:execute")
|
check_policy_on_container(container.as_dict(), "container:execute")
|
||||||
|
utils.validate_container_state(container, 'execute')
|
||||||
LOG.debug('Calling compute.container_exec with %s command %s'
|
LOG.debug('Calling compute.container_exec with %s command %s'
|
||||||
% (container.uuid, kw['command']))
|
% (container.uuid, kw['command']))
|
||||||
context = pecan.request.context
|
context = pecan.request.context
|
||||||
@ -418,9 +427,10 @@ class ContainersController(rest.RestController):
|
|||||||
def kill(self, container_id, **kw):
|
def kill(self, container_id, **kw):
|
||||||
container = _get_container(container_id)
|
container = _get_container(container_id)
|
||||||
check_policy_on_container(container.as_dict(), "container:kill")
|
check_policy_on_container(container.as_dict(), "container:kill")
|
||||||
|
utils.validate_container_state(container, 'kill')
|
||||||
LOG.debug('Calling compute.container_kill with %s signal %s'
|
LOG.debug('Calling compute.container_kill with %s signal %s'
|
||||||
% (container.uuid, kw.get('signal', kw.get('signal'))))
|
% (container.uuid, kw.get('signal', kw.get('signal'))))
|
||||||
context = pecan.request.context
|
context = pecan.request.context
|
||||||
container = pecan.request.rpcapi.container_kill(context, container,
|
pecan.request.rpcapi.container_kill(context, container,
|
||||||
kw.get('signal'))
|
kw.get('signal', None))
|
||||||
return Container.convert_with_links(container.as_dict())
|
pecan.response.status = 202
|
||||||
|
@ -35,6 +35,26 @@ from zun.common.i18n import _LW
|
|||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
VALID_STATES = {
|
||||||
|
'delete': ['Stopped', 'Error'],
|
||||||
|
'start': ['Stopped'],
|
||||||
|
'stop': ['Running'],
|
||||||
|
'reboot': ['Running', 'Stopped'],
|
||||||
|
'pause': ['Running'],
|
||||||
|
'unpause': ['Paused'],
|
||||||
|
'kill': ['Running'],
|
||||||
|
'execute': ['Running'],
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def validate_container_state(container, action):
|
||||||
|
if container.status not in VALID_STATES[action]:
|
||||||
|
raise exception.InvalidStateException(
|
||||||
|
id=container.uuid,
|
||||||
|
action=action,
|
||||||
|
actual_state=container.status)
|
||||||
|
|
||||||
|
|
||||||
def safe_rstrip(value, chars=None):
|
def safe_rstrip(value, chars=None):
|
||||||
"""Removes trailing characters from a string if that does not make it empty
|
"""Removes trailing characters from a string if that does not make it empty
|
||||||
|
|
||||||
|
@ -16,7 +16,6 @@ import six
|
|||||||
|
|
||||||
from oslo_log import log as logging
|
from oslo_log import log as logging
|
||||||
from oslo_utils import excutils
|
from oslo_utils import excutils
|
||||||
from oslo_utils import strutils
|
|
||||||
|
|
||||||
from zun.common import exception
|
from zun.common import exception
|
||||||
from zun.common.i18n import _LE
|
from zun.common.i18n import _LE
|
||||||
@ -29,17 +28,6 @@ from zun.objects import fields
|
|||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
VALID_STATES = {
|
|
||||||
'delete': ['Stopped', 'Error'],
|
|
||||||
'start': ['Stopped'],
|
|
||||||
'stop': ['Running'],
|
|
||||||
'reboot': ['Running', 'Stopped'],
|
|
||||||
'pause': ['Running'],
|
|
||||||
'unpause': ['Paused'],
|
|
||||||
'kill': ['Running'],
|
|
||||||
'exec': ['Running'],
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class Manager(object):
|
class Manager(object):
|
||||||
'''Manages the running containers.'''
|
'''Manages the running containers.'''
|
||||||
@ -54,17 +42,9 @@ class Manager(object):
|
|||||||
container.task_state = None
|
container.task_state = None
|
||||||
container.save()
|
container.save()
|
||||||
|
|
||||||
def _validate_container_state(self, container, action):
|
|
||||||
if container.status not in VALID_STATES[action]:
|
|
||||||
raise exception.InvalidStateException(
|
|
||||||
id=container.uuid,
|
|
||||||
action=action,
|
|
||||||
actual_state=container.status)
|
|
||||||
|
|
||||||
def container_create(self, context, container):
|
def container_create(self, context, container):
|
||||||
utils.spawn_n(self._do_container_create, context, container)
|
utils.spawn_n(self._do_container_create, context, container)
|
||||||
|
|
||||||
@translate_exception
|
|
||||||
def container_run(self, context, container):
|
def container_run(self, context, container):
|
||||||
utils.spawn_n(self._do_container_run, context, container)
|
utils.spawn_n(self._do_container_run, context, container)
|
||||||
|
|
||||||
@ -156,32 +136,28 @@ class Manager(object):
|
|||||||
self._fail_container(container, six.text_type(e))
|
self._fail_container(container, six.text_type(e))
|
||||||
return
|
return
|
||||||
|
|
||||||
def _do_container_start(self, context, container):
|
def _do_container_start(self, context, container, reraise=False):
|
||||||
LOG.debug('Starting container: %s', container.uuid)
|
LOG.debug('Starting container: %s', container.uuid)
|
||||||
try:
|
try:
|
||||||
# Although we dont need this validation, but i still
|
|
||||||
# keep it for extra surity
|
|
||||||
self._validate_container_state(container, 'start')
|
|
||||||
container = self.driver.start(container)
|
container = self.driver.start(container)
|
||||||
container.save()
|
container.save()
|
||||||
return container
|
return container
|
||||||
except exception.DockerError as e:
|
except exception.DockerError as e:
|
||||||
LOG.error(_LE("Error occurred while calling Docker start API: %s"),
|
with excutils.save_and_reraise_exception(reraise=reraise):
|
||||||
six.text_type(e))
|
LOG.error(_LE(
|
||||||
self._fail_container(container, six.text_type(e))
|
"Error occurred while calling Docker start API: %s"),
|
||||||
raise
|
six.text_type(e))
|
||||||
|
self._fail_container(container, six.text_type(e))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
LOG.exception(_LE("Unexpected exception: %s"), six.text_type(e))
|
with excutils.save_and_reraise_exception(reraise=reraise):
|
||||||
self._fail_container(container, six.text_type(e))
|
LOG.exception(_LE("Unexpected exception: %s"),
|
||||||
raise
|
six.text_type(e))
|
||||||
|
self._fail_container(container, six.text_type(e))
|
||||||
|
|
||||||
@translate_exception
|
@translate_exception
|
||||||
def container_delete(self, context, container, force):
|
def container_delete(self, context, container, force):
|
||||||
LOG.debug('Deleting container: %s', container.uuid)
|
LOG.debug('Deleting container: %s', container.uuid)
|
||||||
try:
|
try:
|
||||||
force = strutils.bool_from_string(force, strict=True)
|
|
||||||
if not force:
|
|
||||||
self._validate_container_state(container, 'delete')
|
|
||||||
self.driver.delete(container, force)
|
self.driver.delete(container, force)
|
||||||
except exception.DockerError as e:
|
except exception.DockerError as e:
|
||||||
LOG.error(_LE("Error occurred while calling Docker "
|
LOG.error(_LE("Error occurred while calling Docker "
|
||||||
@ -230,74 +206,83 @@ class Manager(object):
|
|||||||
LOG.exception(_LE("Unexpected exception: %s"), six.text_type(e))
|
LOG.exception(_LE("Unexpected exception: %s"), six.text_type(e))
|
||||||
raise
|
raise
|
||||||
|
|
||||||
@translate_exception
|
def _do_container_reboot(self, context, container, timeout, reraise=False):
|
||||||
def container_reboot(self, context, container, timeout):
|
|
||||||
LOG.debug('Rebooting container: %s', container.uuid)
|
LOG.debug('Rebooting container: %s', container.uuid)
|
||||||
try:
|
try:
|
||||||
self._validate_container_state(container, 'reboot')
|
|
||||||
container = self.driver.reboot(container, timeout)
|
container = self.driver.reboot(container, timeout)
|
||||||
container.save()
|
container.save()
|
||||||
return container
|
return container
|
||||||
except exception.DockerError as e:
|
except exception.DockerError as e:
|
||||||
LOG.error(_LE("Error occurred while calling Docker reboot "
|
with excutils.save_and_reraise_exception(reraise=reraise):
|
||||||
"API: %s"), six.text_type(e))
|
LOG.error(_LE("Error occurred while calling Docker reboot "
|
||||||
raise
|
"API: %s"), six.text_type(e))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
LOG.exception(_LE("Unexpected exception: %s"), six.text_type(e))
|
with excutils.save_and_reraise_exception(reraise=reraise):
|
||||||
raise
|
LOG.exception(_LE("Unexpected exception: %s"),
|
||||||
|
six.text_type(e))
|
||||||
|
|
||||||
@translate_exception
|
def container_reboot(self, context, container, timeout):
|
||||||
def container_stop(self, context, container, timeout):
|
utils.spawn_n(self._do_container_reboot, context, container, timeout)
|
||||||
|
|
||||||
|
def _do_container_stop(self, context, container, timeout, reraise=False):
|
||||||
LOG.debug('Stopping container: %s', container.uuid)
|
LOG.debug('Stopping container: %s', container.uuid)
|
||||||
try:
|
try:
|
||||||
self._validate_container_state(container, 'stop')
|
|
||||||
container = self.driver.stop(container, timeout)
|
container = self.driver.stop(container, timeout)
|
||||||
container.save()
|
container.save()
|
||||||
return container
|
return container
|
||||||
except exception.DockerError as e:
|
except exception.DockerError as e:
|
||||||
LOG.error(_LE("Error occurred while calling Docker stop API: %s"),
|
with excutils.save_and_reraise_exception(reraise=reraise):
|
||||||
six.text_type(e))
|
LOG.error(_LE(
|
||||||
raise
|
"Error occurred while calling Docker stop API: %s"),
|
||||||
|
six.text_type(e))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
LOG.exception(_LE("Unexpected exception: %s"), six.text_type(e))
|
with excutils.save_and_reraise_exception(reraise=reraise):
|
||||||
raise
|
LOG.exception(_LE("Unexpected exception: %s"),
|
||||||
|
six.text_type(e))
|
||||||
|
|
||||||
|
def container_stop(self, context, container, timeout):
|
||||||
|
utils.spawn_n(self._do_container_stop, context, container, timeout)
|
||||||
|
|
||||||
@translate_exception
|
|
||||||
def container_start(self, context, container):
|
def container_start(self, context, container):
|
||||||
return self._do_container_start(context, container)
|
utils.spawn_n(self._do_container_start, context, container)
|
||||||
|
|
||||||
@translate_exception
|
def _do_container_pause(self, context, container, reraise=False):
|
||||||
def container_pause(self, context, container):
|
|
||||||
LOG.debug('Pausing container: %s', container.uuid)
|
LOG.debug('Pausing container: %s', container.uuid)
|
||||||
try:
|
try:
|
||||||
self._validate_container_state(container, 'pause')
|
|
||||||
container = self.driver.pause(container)
|
container = self.driver.pause(container)
|
||||||
container.save()
|
container.save()
|
||||||
return container
|
return container
|
||||||
except exception.DockerError as e:
|
except exception.DockerError as e:
|
||||||
LOG.error(_LE("Error occurred while calling Docker pause API: %s"),
|
with excutils.save_and_reraise_exception(reraise=reraise):
|
||||||
six.text_type(e))
|
LOG.error(_LE(
|
||||||
raise
|
"Error occurred while calling Docker pause API: %s"),
|
||||||
|
six.text_type(e))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
LOG.exception(_LE("Unexpected exception: %s,"), six.text_type(e))
|
with excutils.save_and_reraise_exception(reraise=reraise):
|
||||||
raise
|
LOG.exception(_LE("Unexpected exception: %s,"),
|
||||||
|
six.text_type(e))
|
||||||
|
|
||||||
@translate_exception
|
def container_pause(self, context, container):
|
||||||
def container_unpause(self, context, container):
|
utils.spawn_n(self._do_container_pause, context, container)
|
||||||
|
|
||||||
|
def _do_container_unpause(self, context, container, reraise=False):
|
||||||
LOG.debug('Unpausing container: %s', container.uuid)
|
LOG.debug('Unpausing container: %s', container.uuid)
|
||||||
try:
|
try:
|
||||||
self._validate_container_state(container, 'unpause')
|
|
||||||
container = self.driver.unpause(container)
|
container = self.driver.unpause(container)
|
||||||
container.save()
|
container.save()
|
||||||
return container
|
return container
|
||||||
except exception.DockerError as e:
|
except exception.DockerError as e:
|
||||||
LOG.error(_LE("Error occurred while calling Docker unpause "
|
with excutils.save_and_reraise_exception(reraise=reraise):
|
||||||
"API: %s"),
|
LOG.error(_LE(
|
||||||
six.text_type(e))
|
"Error occurred while calling Docker unpause API: %s"),
|
||||||
raise
|
six.text_type(e))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
LOG.exception(_LE("Unexpected exception: %s"), six.text_type(e))
|
with excutils.save_and_reraise_exception(reraise=reraise):
|
||||||
raise
|
LOG.exception(_LE("Unexpected exception: %s"),
|
||||||
|
six.text_type(e))
|
||||||
|
|
||||||
|
def container_unpause(self, context, container):
|
||||||
|
utils.spawn_n(self._do_container_unpause, context, container)
|
||||||
|
|
||||||
@translate_exception
|
@translate_exception
|
||||||
def container_logs(self, context, container):
|
def container_logs(self, context, container):
|
||||||
@ -317,7 +302,6 @@ class Manager(object):
|
|||||||
# TODO(hongbin): support exec command interactively
|
# TODO(hongbin): support exec command interactively
|
||||||
LOG.debug('Executing command in container: %s', container.uuid)
|
LOG.debug('Executing command in container: %s', container.uuid)
|
||||||
try:
|
try:
|
||||||
self._validate_container_state(container, 'exec')
|
|
||||||
return self.driver.execute(container, command)
|
return self.driver.execute(container, command)
|
||||||
except exception.DockerError as e:
|
except exception.DockerError as e:
|
||||||
LOG.error(_LE("Error occurred while calling Docker exec API: %s"),
|
LOG.error(_LE("Error occurred while calling Docker exec API: %s"),
|
||||||
@ -327,18 +311,20 @@ class Manager(object):
|
|||||||
LOG.exception(_LE("Unexpected exception: %s"), six.text_type(e))
|
LOG.exception(_LE("Unexpected exception: %s"), six.text_type(e))
|
||||||
raise
|
raise
|
||||||
|
|
||||||
@translate_exception
|
def _do_container_kill(self, context, container, signal, reraise=False):
|
||||||
def container_kill(self, context, container, signal):
|
|
||||||
LOG.debug('kill signal to container: %s', container.uuid)
|
LOG.debug('kill signal to container: %s', container.uuid)
|
||||||
try:
|
try:
|
||||||
self._validate_container_state(container, 'kill')
|
|
||||||
container = self.driver.kill(container, signal)
|
container = self.driver.kill(container, signal)
|
||||||
container.save()
|
container.save()
|
||||||
return container
|
return container
|
||||||
except exception.DockerError as e:
|
except exception.DockerError as e:
|
||||||
LOG.error(_LE("Error occurred while calling Docker kill API: %s"),
|
with excutils.save_and_reraise_exception(reraise=reraise):
|
||||||
six.text_type(e))
|
LOG.error(_LE(
|
||||||
raise
|
"Error occurred while calling Docker kill API: %s"),
|
||||||
|
six.text_type(e))
|
||||||
|
|
||||||
|
def container_kill(self, context, container, signal):
|
||||||
|
utils.spawn_n(self._do_container_kill, context, container, signal)
|
||||||
|
|
||||||
def image_pull(self, context, image):
|
def image_pull(self, context, image):
|
||||||
utils.spawn_n(self._do_image_pull, context, image)
|
utils.spawn_n(self._do_image_pull, context, image)
|
||||||
|
@ -47,21 +47,21 @@ class API(rpc_service.API):
|
|||||||
return self._call('container_show', container=container)
|
return self._call('container_show', container=container)
|
||||||
|
|
||||||
def container_reboot(self, context, container, timeout):
|
def container_reboot(self, context, container, timeout):
|
||||||
return self._call('container_reboot', container=container,
|
return self._cast('container_reboot', container=container,
|
||||||
timeout=timeout)
|
timeout=timeout)
|
||||||
|
|
||||||
def container_stop(self, context, container, timeout):
|
def container_stop(self, context, container, timeout):
|
||||||
return self._call('container_stop', container=container,
|
return self._cast('container_stop', container=container,
|
||||||
timeout=timeout)
|
timeout=timeout)
|
||||||
|
|
||||||
def container_start(self, context, container):
|
def container_start(self, context, container):
|
||||||
return self._call('container_start', container=container)
|
return self._cast('container_start', container=container)
|
||||||
|
|
||||||
def container_pause(self, context, container):
|
def container_pause(self, context, container):
|
||||||
return self._call('container_pause', container=container)
|
return self._cast('container_pause', container=container)
|
||||||
|
|
||||||
def container_unpause(self, context, container):
|
def container_unpause(self, context, container):
|
||||||
return self._call('container_unpause', container=container)
|
return self._cast('container_unpause', container=container)
|
||||||
|
|
||||||
def container_logs(self, context, container):
|
def container_logs(self, context, container):
|
||||||
return self._call('container_logs', container=container)
|
return self._call('container_logs', container=container)
|
||||||
@ -71,7 +71,7 @@ class API(rpc_service.API):
|
|||||||
command=command)
|
command=command)
|
||||||
|
|
||||||
def container_kill(self, context, container, signal):
|
def container_kill(self, context, container, signal):
|
||||||
return self._call('container_kill', container=container,
|
return self._cast('container_kill', container=container,
|
||||||
signal=signal)
|
signal=signal)
|
||||||
|
|
||||||
def image_show(self, context, image):
|
def image_show(self, context, image):
|
||||||
|
@ -123,34 +123,28 @@ class ZunClient(rest_client.RestClient):
|
|||||||
self.container_uri(container_id, params=params), **kwargs)
|
self.container_uri(container_id, params=params), **kwargs)
|
||||||
|
|
||||||
def start_container(self, container_id, **kwargs):
|
def start_container(self, container_id, **kwargs):
|
||||||
resp, body = self.post(
|
return self.post(
|
||||||
self.container_uri(container_id, action='start'), None, **kwargs)
|
self.container_uri(container_id, action='start'), None, **kwargs)
|
||||||
return self.deserialize(resp, body, container_model.ContainerEntity)
|
|
||||||
|
|
||||||
def stop_container(self, container_id, **kwargs):
|
def stop_container(self, container_id, **kwargs):
|
||||||
resp, body = self.post(
|
return self.post(
|
||||||
self.container_uri(container_id, action='stop'), None, *kwargs)
|
self.container_uri(container_id, action='stop'), None, *kwargs)
|
||||||
return self.deserialize(resp, body, container_model.ContainerEntity)
|
|
||||||
|
|
||||||
def pause_container(self, container_id, **kwargs):
|
def pause_container(self, container_id, **kwargs):
|
||||||
resp, body = self.post(
|
return self.post(
|
||||||
self.container_uri(container_id, action='pause'), None, **kwargs)
|
self.container_uri(container_id, action='pause'), None, **kwargs)
|
||||||
return self.deserialize(resp, body, container_model.ContainerEntity)
|
|
||||||
|
|
||||||
def unpause_container(self, container_id, **kwargs):
|
def unpause_container(self, container_id, **kwargs):
|
||||||
resp, body = self.post(
|
return self.post(
|
||||||
self.container_uri(container_id, action='unpause'), None, **kwargs)
|
self.container_uri(container_id, action='unpause'), None, **kwargs)
|
||||||
return self.deserialize(resp, body, container_model.ContainerEntity)
|
|
||||||
|
|
||||||
def kill_container(self, container_id, **kwargs):
|
def kill_container(self, container_id, **kwargs):
|
||||||
resp, body = self.post(
|
return self.post(
|
||||||
self.container_uri(container_id, action='kill'), None, **kwargs)
|
self.container_uri(container_id, action='kill'), None, **kwargs)
|
||||||
return self.deserialize(resp, body, container_model.ContainerEntity)
|
|
||||||
|
|
||||||
def reboot_container(self, container_id, **kwargs):
|
def reboot_container(self, container_id, **kwargs):
|
||||||
resp, body = self.post(
|
return self.post(
|
||||||
self.container_uri(container_id, action='reboot'), None, **kwargs)
|
self.container_uri(container_id, action='reboot'), None, **kwargs)
|
||||||
return self.deserialize(resp, body, container_model.ContainerEntity)
|
|
||||||
|
|
||||||
def exec_container(self, container_id, command, **kwargs):
|
def exec_container(self, container_id, command, **kwargs):
|
||||||
return self.post(
|
return self.post(
|
||||||
@ -166,25 +160,14 @@ class ZunClient(rest_client.RestClient):
|
|||||||
return self.deserialize(resp, body,
|
return self.deserialize(resp, body,
|
||||||
service_model.ServiceCollection)
|
service_model.ServiceCollection)
|
||||||
|
|
||||||
def ensure_container_created(self, container_id):
|
def ensure_container_in_desired_state(self, container_id, status):
|
||||||
def container_created():
|
def is_container_in_desired_state():
|
||||||
_, container = self.get_container(container_id)
|
_, container = self.get_container(container_id)
|
||||||
if container.status == 'Creating':
|
if container.status == status:
|
||||||
return False
|
|
||||||
else:
|
|
||||||
return True
|
|
||||||
|
|
||||||
utils.wait_for_condition(container_created)
|
|
||||||
|
|
||||||
def ensure_container_started(self, container_id):
|
|
||||||
def container_started():
|
|
||||||
_, container = self.get_container(container_id)
|
|
||||||
if container.status == 'Running':
|
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
utils.wait_for_condition(is_container_in_desired_state)
|
||||||
utils.wait_for_condition(container_started)
|
|
||||||
|
|
||||||
|
|
||||||
class DockerClient(object):
|
class DockerClient(object):
|
||||||
@ -195,3 +178,13 @@ class DockerClient(object):
|
|||||||
if container_id in info['Name']:
|
if container_id in info['Name']:
|
||||||
return info
|
return info
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
def ensure_container_pid_changed(self, container_id, pid):
|
||||||
|
def is_pid_changed():
|
||||||
|
container = self.get_container(container_id)
|
||||||
|
new_pid = container.get('State').get('Pid')
|
||||||
|
if pid != new_pid:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
utils.wait_for_condition(is_pid_changed)
|
||||||
|
@ -81,37 +81,42 @@ class TestContainer(base.BaseZunTest):
|
|||||||
def test_start_stop_container(self):
|
def test_start_stop_container(self):
|
||||||
_, model = self._run_container()
|
_, model = self._run_container()
|
||||||
|
|
||||||
resp, model = self.container_client.stop_container(model.uuid)
|
resp, _ = self.container_client.stop_container(model.uuid)
|
||||||
self.assertEqual(200, resp.status)
|
self.assertEqual(202, resp.status)
|
||||||
self.assertEqual('Stopped', model.status)
|
self.container_client.ensure_container_in_desired_state(
|
||||||
|
model.uuid, 'Stopped')
|
||||||
self.assertEqual('Stopped', self._get_container_state(model.uuid))
|
self.assertEqual('Stopped', self._get_container_state(model.uuid))
|
||||||
|
|
||||||
resp, model = self.container_client.start_container(model.uuid)
|
resp, _ = self.container_client.start_container(model.uuid)
|
||||||
self.assertEqual(200, resp.status)
|
self.assertEqual(202, resp.status)
|
||||||
self.assertEqual('Running', model.status)
|
self.container_client.ensure_container_in_desired_state(
|
||||||
|
model.uuid, 'Running')
|
||||||
self.assertEqual('Running', self._get_container_state(model.uuid))
|
self.assertEqual('Running', self._get_container_state(model.uuid))
|
||||||
|
|
||||||
@decorators.idempotent_id('b5f39756-8898-4e0e-a48b-dda0a06b66b6')
|
@decorators.idempotent_id('b5f39756-8898-4e0e-a48b-dda0a06b66b6')
|
||||||
def test_pause_unpause_container(self):
|
def test_pause_unpause_container(self):
|
||||||
_, model = self._run_container()
|
_, model = self._run_container()
|
||||||
|
|
||||||
resp, model = self.container_client.pause_container(model.uuid)
|
resp, _ = self.container_client.pause_container(model.uuid)
|
||||||
self.assertEqual(200, resp.status)
|
self.assertEqual(202, resp.status)
|
||||||
self.assertEqual('Paused', model.status)
|
self.container_client.ensure_container_in_desired_state(
|
||||||
|
model.uuid, 'Paused')
|
||||||
self.assertEqual('Paused', self._get_container_state(model.uuid))
|
self.assertEqual('Paused', self._get_container_state(model.uuid))
|
||||||
|
|
||||||
resp, model = self.container_client.unpause_container(model.uuid)
|
resp, _ = self.container_client.unpause_container(model.uuid)
|
||||||
self.assertEqual(200, resp.status)
|
self.assertEqual(202, resp.status)
|
||||||
self.assertEqual('Running', model.status)
|
self.container_client.ensure_container_in_desired_state(
|
||||||
|
model.uuid, 'Running')
|
||||||
self.assertEqual('Running', self._get_container_state(model.uuid))
|
self.assertEqual('Running', self._get_container_state(model.uuid))
|
||||||
|
|
||||||
@decorators.idempotent_id('6179a588-3d48-4372-9599-f228411d1449')
|
@decorators.idempotent_id('6179a588-3d48-4372-9599-f228411d1449')
|
||||||
def test_kill_container(self):
|
def test_kill_container(self):
|
||||||
_, model = self._run_container()
|
_, model = self._run_container()
|
||||||
|
|
||||||
resp, model = self.container_client.kill_container(model.uuid)
|
resp, _ = self.container_client.kill_container(model.uuid)
|
||||||
self.assertEqual(200, resp.status)
|
self.assertEqual(202, resp.status)
|
||||||
self.assertEqual('Stopped', model.status)
|
self.container_client.ensure_container_in_desired_state(
|
||||||
|
model.uuid, 'Stopped')
|
||||||
self.assertEqual('Stopped', self._get_container_state(model.uuid))
|
self.assertEqual('Stopped', self._get_container_state(model.uuid))
|
||||||
|
|
||||||
@decorators.idempotent_id('c2e54321-0a70-4331-ba62-9dcaa75ac250')
|
@decorators.idempotent_id('c2e54321-0a70-4331-ba62-9dcaa75ac250')
|
||||||
@ -120,9 +125,9 @@ class TestContainer(base.BaseZunTest):
|
|||||||
container = self.docker_client.get_container(model.uuid)
|
container = self.docker_client.get_container(model.uuid)
|
||||||
pid = container.get('State').get('Pid')
|
pid = container.get('State').get('Pid')
|
||||||
|
|
||||||
resp, model = self.container_client.reboot_container(model.uuid)
|
resp, _ = self.container_client.reboot_container(model.uuid)
|
||||||
self.assertEqual(200, resp.status)
|
self.assertEqual(202, resp.status)
|
||||||
self.assertEqual('Running', model.status)
|
self.docker_client.ensure_container_pid_changed(model.uuid, pid)
|
||||||
self.assertEqual('Running', self._get_container_state(model.uuid))
|
self.assertEqual('Running', self._get_container_state(model.uuid))
|
||||||
# assert pid is changed
|
# assert pid is changed
|
||||||
container = self.docker_client.get_container(model.uuid)
|
container = self.docker_client.get_container(model.uuid)
|
||||||
@ -149,7 +154,8 @@ class TestContainer(base.BaseZunTest):
|
|||||||
resp, model = self.container_client.post_container(gen_model)
|
resp, model = self.container_client.post_container(gen_model)
|
||||||
self.assertEqual(202, resp.status)
|
self.assertEqual(202, resp.status)
|
||||||
# Wait for container to finish creation
|
# Wait for container to finish creation
|
||||||
self.container_client.ensure_container_created(model.uuid)
|
self.container_client.ensure_container_in_desired_state(
|
||||||
|
model.uuid, 'Stopped')
|
||||||
|
|
||||||
# Assert the container is created
|
# Assert the container is created
|
||||||
resp, model = self.container_client.get_container(model.uuid)
|
resp, model = self.container_client.get_container(model.uuid)
|
||||||
@ -163,13 +169,13 @@ class TestContainer(base.BaseZunTest):
|
|||||||
resp, model = self.container_client.run_container(gen_model)
|
resp, model = self.container_client.run_container(gen_model)
|
||||||
self.assertEqual(202, resp.status)
|
self.assertEqual(202, resp.status)
|
||||||
# Wait for container to started
|
# Wait for container to started
|
||||||
self.container_client.ensure_container_started(model.uuid)
|
self.container_client.ensure_container_in_desired_state(
|
||||||
|
model.uuid, 'Running')
|
||||||
|
|
||||||
# Assert the container is started
|
# Assert the container is started
|
||||||
resp, model = self.container_client.get_container(model.uuid)
|
resp, model = self.container_client.get_container(model.uuid)
|
||||||
self.assertTrue(model.status in ['Running', 'Stopped'])
|
self.assertEqual('Running', model.status)
|
||||||
self.assertTrue(self._get_container_state(model.uuid) in
|
self.assertEqual('Running', self._get_container_state(model.uuid))
|
||||||
['Running', 'Stopped'])
|
|
||||||
return resp, model
|
return resp, model
|
||||||
|
|
||||||
def _delete_container(self, container_id):
|
def _delete_container(self, container_id):
|
||||||
|
@ -146,7 +146,8 @@ class TestContainerController(api_base.FunctionalTest):
|
|||||||
self.assertEqual({"key1": "val1", "key2": "val2"},
|
self.assertEqual({"key1": "val1", "key2": "val2"},
|
||||||
c.get('environment'))
|
c.get('environment'))
|
||||||
# Delete the container we created
|
# Delete the container we created
|
||||||
response = self.app.delete('/v1/containers/%s/' % c.get('uuid'))
|
response = self.app.delete(
|
||||||
|
'/v1/containers/%s?force=True' % c.get('uuid'))
|
||||||
self.assertEqual(204, response.status_int)
|
self.assertEqual(204, response.status_int)
|
||||||
|
|
||||||
response = self.app.get('/v1/containers/')
|
response = self.app.get('/v1/containers/')
|
||||||
@ -415,7 +416,7 @@ class TestContainerController(api_base.FunctionalTest):
|
|||||||
self.assertEqual('new_name', test_container_obj.name)
|
self.assertEqual('new_name', test_container_obj.name)
|
||||||
|
|
||||||
def _action_test(self, container, action, ident_field,
|
def _action_test(self, container, action, ident_field,
|
||||||
mock_container_action, query_param=''):
|
mock_container_action, status_code, query_param=''):
|
||||||
test_container_obj = objects.Container(self.context, **container)
|
test_container_obj = objects.Container(self.context, **container)
|
||||||
ident = container.get(ident_field)
|
ident = container.get(ident_field)
|
||||||
get_by_ident_loc = 'zun.objects.Container.get_by_%s' % ident_field
|
get_by_ident_loc = 'zun.objects.Container.get_by_%s' % ident_field
|
||||||
@ -423,7 +424,7 @@ class TestContainerController(api_base.FunctionalTest):
|
|||||||
mock_get_by_indent.return_value = test_container_obj
|
mock_get_by_indent.return_value = test_container_obj
|
||||||
response = self.app.post('/v1/containers/%s/%s/?%s' %
|
response = self.app.post('/v1/containers/%s/%s/?%s' %
|
||||||
(ident, action, query_param))
|
(ident, action, query_param))
|
||||||
self.assertEqual(200, response.status_int)
|
self.assertEqual(status_code, response.status_int)
|
||||||
|
|
||||||
# Only PUT should work, others like GET should fail
|
# Only PUT should work, others like GET should fail
|
||||||
self.assertRaises(AppError, self.app.get,
|
self.assertRaises(AppError, self.app.get,
|
||||||
@ -437,98 +438,154 @@ class TestContainerController(api_base.FunctionalTest):
|
|||||||
mock_container_action.assert_called_once_with(
|
mock_container_action.assert_called_once_with(
|
||||||
mock.ANY, test_container_obj)
|
mock.ANY, test_container_obj)
|
||||||
|
|
||||||
|
@patch('zun.common.utils.validate_container_state')
|
||||||
@patch('zun.compute.rpcapi.API.container_start')
|
@patch('zun.compute.rpcapi.API.container_start')
|
||||||
def test_start_by_uuid(self, mock_container_start):
|
def test_start_by_uuid(self, mock_container_start, mock_validate):
|
||||||
test_container_obj = objects.Container(self.context,
|
test_container_obj = objects.Container(self.context,
|
||||||
**utils.get_test_container())
|
**utils.get_test_container())
|
||||||
mock_container_start.return_value = test_container_obj
|
mock_container_start.return_value = test_container_obj
|
||||||
test_container = utils.get_test_container()
|
test_container = utils.get_test_container()
|
||||||
self._action_test(test_container, 'start', 'uuid',
|
self._action_test(test_container, 'start', 'uuid',
|
||||||
mock_container_start)
|
mock_container_start, 202)
|
||||||
|
|
||||||
|
def test_start_by_uuid_invalid_state(self):
|
||||||
|
uuid = uuidutils.generate_uuid()
|
||||||
|
test_object = utils.create_test_container(context=self.context,
|
||||||
|
uuid=uuid, status='Running')
|
||||||
|
with self.assertRaisesRegexp(
|
||||||
|
AppError, "Cannot start container %s in Running state" % uuid):
|
||||||
|
self.app.post('/v1/containers/%s/%s/' % (test_object.uuid,
|
||||||
|
'start'))
|
||||||
|
|
||||||
|
@patch('zun.common.utils.validate_container_state')
|
||||||
@patch('zun.compute.rpcapi.API.container_start')
|
@patch('zun.compute.rpcapi.API.container_start')
|
||||||
def test_start_by_name(self, mock_container_start):
|
def test_start_by_name(self, mock_container_start, mock_validate):
|
||||||
test_container_obj = objects.Container(self.context,
|
test_container_obj = objects.Container(self.context,
|
||||||
**utils.get_test_container())
|
**utils.get_test_container())
|
||||||
mock_container_start.return_value = test_container_obj
|
mock_container_start.return_value = test_container_obj
|
||||||
test_container = utils.get_test_container()
|
test_container = utils.get_test_container()
|
||||||
self._action_test(test_container, 'start', 'name',
|
self._action_test(test_container, 'start', 'name',
|
||||||
mock_container_start)
|
mock_container_start, 202)
|
||||||
|
|
||||||
|
@patch('zun.common.utils.validate_container_state')
|
||||||
@patch('zun.compute.rpcapi.API.container_stop')
|
@patch('zun.compute.rpcapi.API.container_stop')
|
||||||
def test_stop_by_uuid(self, mock_container_stop):
|
def test_stop_by_uuid(self, mock_container_stop, mock_validate):
|
||||||
test_container_obj = objects.Container(self.context,
|
test_container_obj = objects.Container(self.context,
|
||||||
**utils.get_test_container())
|
**utils.get_test_container())
|
||||||
mock_container_stop.return_value = test_container_obj
|
mock_container_stop.return_value = test_container_obj
|
||||||
test_container = utils.get_test_container()
|
test_container = utils.get_test_container()
|
||||||
self._action_test(test_container, 'stop', 'uuid',
|
self._action_test(test_container, 'stop', 'uuid',
|
||||||
mock_container_stop,
|
mock_container_stop, 202,
|
||||||
query_param='timeout=10')
|
query_param='timeout=10')
|
||||||
|
|
||||||
|
@patch('zun.common.utils.validate_container_state')
|
||||||
@patch('zun.compute.rpcapi.API.container_stop')
|
@patch('zun.compute.rpcapi.API.container_stop')
|
||||||
def test_stop_by_name(self, mock_container_stop):
|
def test_stop_by_name(self, mock_container_stop, mock_validate):
|
||||||
test_container_obj = objects.Container(self.context,
|
test_container_obj = objects.Container(self.context,
|
||||||
**utils.get_test_container())
|
**utils.get_test_container())
|
||||||
mock_container_stop.return_value = test_container_obj
|
mock_container_stop.return_value = test_container_obj
|
||||||
test_container = utils.get_test_container()
|
test_container = utils.get_test_container()
|
||||||
self._action_test(test_container, 'stop', 'name',
|
self._action_test(test_container, 'stop', 'name',
|
||||||
mock_container_stop,
|
mock_container_stop, 202,
|
||||||
query_param='timeout=10')
|
query_param='timeout=10')
|
||||||
|
|
||||||
|
def test_stop_by_uuid_invalid_state(self):
|
||||||
|
uuid = uuidutils.generate_uuid()
|
||||||
|
test_object = utils.create_test_container(context=self.context,
|
||||||
|
uuid=uuid, status='Stopped')
|
||||||
|
with self.assertRaisesRegexp(
|
||||||
|
AppError, "Cannot stop container %s in Stopped state" % uuid):
|
||||||
|
self.app.post('/v1/containers/%s/%s/' % (test_object.uuid,
|
||||||
|
'stop'))
|
||||||
|
|
||||||
|
@patch('zun.common.utils.validate_container_state')
|
||||||
@patch('zun.compute.rpcapi.API.container_pause')
|
@patch('zun.compute.rpcapi.API.container_pause')
|
||||||
def test_pause_by_uuid(self, mock_container_pause):
|
def test_pause_by_uuid(self, mock_container_pause, mock_validate):
|
||||||
test_container_obj = objects.Container(self.context,
|
test_container_obj = objects.Container(self.context,
|
||||||
**utils.get_test_container())
|
**utils.get_test_container())
|
||||||
mock_container_pause.return_value = test_container_obj
|
mock_container_pause.return_value = test_container_obj
|
||||||
test_container = utils.get_test_container()
|
test_container = utils.get_test_container()
|
||||||
self._action_test(test_container, 'pause', 'uuid',
|
self._action_test(test_container, 'pause', 'uuid',
|
||||||
mock_container_pause)
|
mock_container_pause, 202)
|
||||||
|
|
||||||
|
def test_pause_by_uuid_invalid_state(self):
|
||||||
|
uuid = uuidutils.generate_uuid()
|
||||||
|
test_object = utils.create_test_container(context=self.context,
|
||||||
|
uuid=uuid, status='Stopped')
|
||||||
|
with self.assertRaisesRegexp(
|
||||||
|
AppError, "Cannot pause container %s in Stopped state" % uuid):
|
||||||
|
self.app.post('/v1/containers/%s/%s/' % (test_object.uuid,
|
||||||
|
'pause'))
|
||||||
|
|
||||||
|
@patch('zun.common.utils.validate_container_state')
|
||||||
@patch('zun.compute.rpcapi.API.container_pause')
|
@patch('zun.compute.rpcapi.API.container_pause')
|
||||||
def test_pause_by_name(self, mock_container_pause):
|
def test_pause_by_name(self, mock_container_pause, mock_validate):
|
||||||
test_container_obj = objects.Container(self.context,
|
test_container_obj = objects.Container(self.context,
|
||||||
**utils.get_test_container())
|
**utils.get_test_container())
|
||||||
mock_container_pause.return_value = test_container_obj
|
mock_container_pause.return_value = test_container_obj
|
||||||
test_container = utils.get_test_container()
|
test_container = utils.get_test_container()
|
||||||
self._action_test(test_container, 'pause', 'name',
|
self._action_test(test_container, 'pause', 'name',
|
||||||
mock_container_pause)
|
mock_container_pause, 202)
|
||||||
|
|
||||||
|
@patch('zun.common.utils.validate_container_state')
|
||||||
@patch('zun.compute.rpcapi.API.container_unpause')
|
@patch('zun.compute.rpcapi.API.container_unpause')
|
||||||
def test_unpause_by_uuid(self, mock_container_unpause):
|
def test_unpause_by_uuid(self, mock_container_unpause, mock_validate):
|
||||||
test_container_obj = objects.Container(self.context,
|
test_container_obj = objects.Container(self.context,
|
||||||
**utils.get_test_container())
|
**utils.get_test_container())
|
||||||
mock_container_unpause.return_value = test_container_obj
|
mock_container_unpause.return_value = test_container_obj
|
||||||
test_container = utils.get_test_container()
|
test_container = utils.get_test_container()
|
||||||
self._action_test(test_container, 'unpause', 'uuid',
|
self._action_test(test_container, 'unpause', 'uuid',
|
||||||
mock_container_unpause)
|
mock_container_unpause, 202)
|
||||||
|
|
||||||
|
def test_unpause_by_uuid_invalid_state(self):
|
||||||
|
uuid = uuidutils.generate_uuid()
|
||||||
|
test_object = utils.create_test_container(context=self.context,
|
||||||
|
uuid=uuid, status='Running')
|
||||||
|
with self.assertRaisesRegexp(
|
||||||
|
AppError,
|
||||||
|
"Cannot unpause container %s in Running state" % uuid):
|
||||||
|
self.app.post('/v1/containers/%s/%s/' % (test_object.uuid,
|
||||||
|
'unpause'))
|
||||||
|
|
||||||
|
@patch('zun.common.utils.validate_container_state')
|
||||||
@patch('zun.compute.rpcapi.API.container_unpause')
|
@patch('zun.compute.rpcapi.API.container_unpause')
|
||||||
def test_unpause_by_name(self, mock_container_unpause):
|
def test_unpause_by_name(self, mock_container_unpause, mock_validate):
|
||||||
test_container_obj = objects.Container(self.context,
|
test_container_obj = objects.Container(self.context,
|
||||||
**utils.get_test_container())
|
**utils.get_test_container())
|
||||||
mock_container_unpause.return_value = test_container_obj
|
mock_container_unpause.return_value = test_container_obj
|
||||||
test_container = utils.get_test_container()
|
test_container = utils.get_test_container()
|
||||||
self._action_test(test_container, 'unpause', 'name',
|
self._action_test(test_container, 'unpause', 'name',
|
||||||
mock_container_unpause)
|
mock_container_unpause, 202)
|
||||||
|
|
||||||
|
@patch('zun.common.utils.validate_container_state')
|
||||||
@patch('zun.compute.rpcapi.API.container_reboot')
|
@patch('zun.compute.rpcapi.API.container_reboot')
|
||||||
def test_reboot_by_uuid(self, mock_container_reboot):
|
def test_reboot_by_uuid(self, mock_container_reboot, mock_validate):
|
||||||
test_container_obj = objects.Container(self.context,
|
test_container_obj = objects.Container(self.context,
|
||||||
**utils.get_test_container())
|
**utils.get_test_container())
|
||||||
mock_container_reboot.return_value = test_container_obj
|
mock_container_reboot.return_value = test_container_obj
|
||||||
test_container = utils.get_test_container()
|
test_container = utils.get_test_container()
|
||||||
self._action_test(test_container, 'reboot', 'uuid',
|
self._action_test(test_container, 'reboot', 'uuid',
|
||||||
mock_container_reboot,
|
mock_container_reboot, 202,
|
||||||
query_param='timeout=10')
|
query_param='timeout=10')
|
||||||
|
|
||||||
|
def test_reboot_by_uuid_invalid_state(self):
|
||||||
|
uuid = uuidutils.generate_uuid()
|
||||||
|
test_object = utils.create_test_container(context=self.context,
|
||||||
|
uuid=uuid, status='Paused')
|
||||||
|
with self.assertRaisesRegexp(
|
||||||
|
AppError, "Cannot reboot container %s in Paused state" % uuid):
|
||||||
|
self.app.post('/v1/containers/%s/%s/' % (test_object.uuid,
|
||||||
|
'reboot'))
|
||||||
|
|
||||||
|
@patch('zun.common.utils.validate_container_state')
|
||||||
@patch('zun.compute.rpcapi.API.container_reboot')
|
@patch('zun.compute.rpcapi.API.container_reboot')
|
||||||
def test_reboot_by_name(self, mock_container_reboot):
|
def test_reboot_by_name(self, mock_container_reboot, mock_validate):
|
||||||
test_container_obj = objects.Container(self.context,
|
test_container_obj = objects.Container(self.context,
|
||||||
**utils.get_test_container())
|
**utils.get_test_container())
|
||||||
mock_container_reboot.return_value = test_container_obj
|
mock_container_reboot.return_value = test_container_obj
|
||||||
test_container = utils.get_test_container()
|
test_container = utils.get_test_container()
|
||||||
self._action_test(test_container, 'reboot', 'name',
|
self._action_test(test_container, 'reboot', 'name',
|
||||||
mock_container_reboot,
|
mock_container_reboot, 202,
|
||||||
query_param='timeout=10')
|
query_param='timeout=10')
|
||||||
|
|
||||||
@patch('zun.compute.rpcapi.API.container_logs')
|
@patch('zun.compute.rpcapi.API.container_logs')
|
||||||
@ -573,10 +630,11 @@ class TestContainerController(api_base.FunctionalTest):
|
|||||||
'/v1/containers/%s/logs/' % container_uuid)
|
'/v1/containers/%s/logs/' % container_uuid)
|
||||||
self.assertFalse(mock_container_logs.called)
|
self.assertFalse(mock_container_logs.called)
|
||||||
|
|
||||||
|
@patch('zun.common.utils.validate_container_state')
|
||||||
@patch('zun.compute.rpcapi.API.container_exec')
|
@patch('zun.compute.rpcapi.API.container_exec')
|
||||||
@patch('zun.objects.Container.get_by_uuid')
|
@patch('zun.objects.Container.get_by_uuid')
|
||||||
def test_execute_command_by_uuid(self, mock_get_by_uuid,
|
def test_execute_command_by_uuid(self, mock_get_by_uuid,
|
||||||
mock_container_exec):
|
mock_container_exec, mock_validate):
|
||||||
mock_container_exec.return_value = ""
|
mock_container_exec.return_value = ""
|
||||||
test_container = utils.get_test_container()
|
test_container = utils.get_test_container()
|
||||||
test_container_obj = objects.Container(self.context, **test_container)
|
test_container_obj = objects.Container(self.context, **test_container)
|
||||||
@ -590,10 +648,22 @@ class TestContainerController(api_base.FunctionalTest):
|
|||||||
mock_container_exec.assert_called_once_with(
|
mock_container_exec.assert_called_once_with(
|
||||||
mock.ANY, test_container_obj, cmd['command'])
|
mock.ANY, test_container_obj, cmd['command'])
|
||||||
|
|
||||||
|
def test_exec_command_by_uuid_invalid_state(self):
|
||||||
|
uuid = uuidutils.generate_uuid()
|
||||||
|
test_object = utils.create_test_container(context=self.context,
|
||||||
|
uuid=uuid, status='Stopped')
|
||||||
|
cmd = {'command': 'ls'}
|
||||||
|
with self.assertRaisesRegexp(
|
||||||
|
AppError,
|
||||||
|
"Cannot execute container %s in Stopped state" % uuid):
|
||||||
|
self.app.post('/v1/containers/%s/%s/' % (test_object.uuid,
|
||||||
|
'execute'), cmd)
|
||||||
|
|
||||||
|
@patch('zun.common.utils.validate_container_state')
|
||||||
@patch('zun.compute.rpcapi.API.container_exec')
|
@patch('zun.compute.rpcapi.API.container_exec')
|
||||||
@patch('zun.objects.Container.get_by_name')
|
@patch('zun.objects.Container.get_by_name')
|
||||||
def test_execute_command_by_name(self, mock_get_by_name,
|
def test_execute_command_by_name(self, mock_get_by_name,
|
||||||
mock_container_exec):
|
mock_container_exec, mock_validate):
|
||||||
mock_container_exec.return_value = ""
|
mock_container_exec.return_value = ""
|
||||||
test_container = utils.get_test_container()
|
test_container = utils.get_test_container()
|
||||||
test_container_obj = objects.Container(self.context, **test_container)
|
test_container_obj = objects.Container(self.context, **test_container)
|
||||||
@ -607,10 +677,11 @@ class TestContainerController(api_base.FunctionalTest):
|
|||||||
mock_container_exec.assert_called_once_with(
|
mock_container_exec.assert_called_once_with(
|
||||||
mock.ANY, test_container_obj, cmd['command'])
|
mock.ANY, test_container_obj, cmd['command'])
|
||||||
|
|
||||||
|
@patch('zun.common.utils.validate_container_state')
|
||||||
@patch('zun.compute.rpcapi.API.container_delete')
|
@patch('zun.compute.rpcapi.API.container_delete')
|
||||||
@patch('zun.objects.Container.get_by_uuid')
|
@patch('zun.objects.Container.get_by_uuid')
|
||||||
def test_delete_container_by_uuid(self, mock_get_by_uuid,
|
def test_delete_container_by_uuid(self, mock_get_by_uuid,
|
||||||
mock_container_delete):
|
mock_container_delete, mock_validate):
|
||||||
test_container = utils.get_test_container()
|
test_container = utils.get_test_container()
|
||||||
test_container_obj = objects.Container(self.context, **test_container)
|
test_container_obj = objects.Container(self.context, **test_container)
|
||||||
mock_get_by_uuid.return_value = test_container_obj
|
mock_get_by_uuid.return_value = test_container_obj
|
||||||
@ -624,10 +695,29 @@ class TestContainerController(api_base.FunctionalTest):
|
|||||||
mock.ANY, test_container_obj, False)
|
mock.ANY, test_container_obj, False)
|
||||||
mock_destroy.assert_called_once_with()
|
mock_destroy.assert_called_once_with()
|
||||||
|
|
||||||
|
def test_delete_by_uuid_invalid_state(self):
|
||||||
|
uuid = uuidutils.generate_uuid()
|
||||||
|
test_object = utils.create_test_container(context=self.context,
|
||||||
|
uuid=uuid, status='Running')
|
||||||
|
with self.assertRaisesRegexp(
|
||||||
|
AppError,
|
||||||
|
"Cannot delete container %s in Running state" % uuid):
|
||||||
|
self.app.delete('/v1/containers/%s' % (test_object.uuid))
|
||||||
|
|
||||||
|
@patch('zun.compute.rpcapi.API.container_delete')
|
||||||
|
def test_delete_by_uuid_invalid_state_force_true(self, mock_delete):
|
||||||
|
uuid = uuidutils.generate_uuid()
|
||||||
|
test_object = utils.create_test_container(context=self.context,
|
||||||
|
uuid=uuid, status='Running')
|
||||||
|
response = self.app.delete('/v1/containers/%s?force=True' % (
|
||||||
|
test_object.uuid))
|
||||||
|
self.assertEqual(204, response.status_int)
|
||||||
|
|
||||||
|
@patch('zun.common.utils.validate_container_state')
|
||||||
@patch('zun.compute.rpcapi.API.container_delete')
|
@patch('zun.compute.rpcapi.API.container_delete')
|
||||||
@patch('zun.objects.Container.get_by_name')
|
@patch('zun.objects.Container.get_by_name')
|
||||||
def test_delete_container_by_name(self, mock_get_by_name,
|
def test_delete_container_by_name(self, mock_get_by_name,
|
||||||
mock_container_delete):
|
mock_container_delete, mock_validate):
|
||||||
test_container = utils.get_test_container()
|
test_container = utils.get_test_container()
|
||||||
test_container_obj = objects.Container(self.context, **test_container)
|
test_container_obj = objects.Container(self.context, **test_container)
|
||||||
mock_get_by_name.return_value = test_container_obj
|
mock_get_by_name.return_value = test_container_obj
|
||||||
@ -641,10 +731,12 @@ class TestContainerController(api_base.FunctionalTest):
|
|||||||
mock.ANY, test_container_obj, False)
|
mock.ANY, test_container_obj, False)
|
||||||
mock_destroy.assert_called_once_with()
|
mock_destroy.assert_called_once_with()
|
||||||
|
|
||||||
|
@patch('zun.common.utils.validate_container_state')
|
||||||
@patch('zun.compute.rpcapi.API.container_kill')
|
@patch('zun.compute.rpcapi.API.container_kill')
|
||||||
@patch('zun.objects.Container.get_by_uuid')
|
@patch('zun.objects.Container.get_by_uuid')
|
||||||
def test_kill_container_by_uuid(self,
|
def test_kill_container_by_uuid(self,
|
||||||
mock_get_by_uuid, mock_container_kill):
|
mock_get_by_uuid, mock_container_kill,
|
||||||
|
mock_validate):
|
||||||
test_container_obj = objects.Container(self.context,
|
test_container_obj = objects.Container(self.context,
|
||||||
**utils.get_test_container())
|
**utils.get_test_container())
|
||||||
mock_container_kill.return_value = test_container_obj
|
mock_container_kill.return_value = test_container_obj
|
||||||
@ -656,14 +748,26 @@ class TestContainerController(api_base.FunctionalTest):
|
|||||||
url = '/v1/containers/%s/%s/' % (container_uuid, 'kill')
|
url = '/v1/containers/%s/%s/' % (container_uuid, 'kill')
|
||||||
cmd = {'signal': '9'}
|
cmd = {'signal': '9'}
|
||||||
response = self.app.post(url, cmd)
|
response = self.app.post(url, cmd)
|
||||||
self.assertEqual(200, response.status_int)
|
self.assertEqual(202, response.status_int)
|
||||||
mock_container_kill.assert_called_once_with(
|
mock_container_kill.assert_called_once_with(
|
||||||
mock.ANY, test_container_obj, cmd['signal'])
|
mock.ANY, test_container_obj, cmd['signal'])
|
||||||
|
|
||||||
|
def test_kill_by_uuid_invalid_state(self):
|
||||||
|
uuid = uuidutils.generate_uuid()
|
||||||
|
test_object = utils.create_test_container(context=self.context,
|
||||||
|
uuid=uuid, status='Stopped')
|
||||||
|
body = {'signal': 9}
|
||||||
|
with self.assertRaisesRegexp(
|
||||||
|
AppError, "Cannot kill container %s in Stopped state" % uuid):
|
||||||
|
self.app.post('/v1/containers/%s/%s/' % (test_object.uuid,
|
||||||
|
'kill'), body)
|
||||||
|
|
||||||
|
@patch('zun.common.utils.validate_container_state')
|
||||||
@patch('zun.compute.rpcapi.API.container_kill')
|
@patch('zun.compute.rpcapi.API.container_kill')
|
||||||
@patch('zun.objects.Container.get_by_name')
|
@patch('zun.objects.Container.get_by_name')
|
||||||
def test_kill_container_by_name(self,
|
def test_kill_container_by_name(self,
|
||||||
mock_get_by_name, mock_container_kill):
|
mock_get_by_name, mock_container_kill,
|
||||||
|
mock_validate):
|
||||||
test_container_obj = objects.Container(self.context,
|
test_container_obj = objects.Container(self.context,
|
||||||
**utils.get_test_container())
|
**utils.get_test_container())
|
||||||
mock_container_kill.return_value = test_container_obj
|
mock_container_kill.return_value = test_container_obj
|
||||||
@ -675,15 +779,17 @@ class TestContainerController(api_base.FunctionalTest):
|
|||||||
url = '/v1/containers/%s/%s/' % (container_name, 'kill')
|
url = '/v1/containers/%s/%s/' % (container_name, 'kill')
|
||||||
cmd = {'signal': '9'}
|
cmd = {'signal': '9'}
|
||||||
response = self.app.post(url, cmd)
|
response = self.app.post(url, cmd)
|
||||||
self.assertEqual(200, response.status_int)
|
self.assertEqual(202, response.status_int)
|
||||||
mock_container_kill.assert_called_once_with(
|
mock_container_kill.assert_called_once_with(
|
||||||
mock.ANY, test_container_obj, cmd['signal'])
|
mock.ANY, test_container_obj, cmd['signal'])
|
||||||
|
|
||||||
|
@patch('zun.common.utils.validate_container_state')
|
||||||
@patch('zun.compute.rpcapi.API.container_kill')
|
@patch('zun.compute.rpcapi.API.container_kill')
|
||||||
@patch('zun.objects.Container.get_by_uuid')
|
@patch('zun.objects.Container.get_by_uuid')
|
||||||
def test_kill_container_which_not_exist(self,
|
def test_kill_container_which_not_exist(self,
|
||||||
mock_get_by_uuid,
|
mock_get_by_uuid,
|
||||||
mock_container_kill):
|
mock_container_kill,
|
||||||
|
mock_validate):
|
||||||
mock_container_kill.return_value = ""
|
mock_container_kill.return_value = ""
|
||||||
test_container = utils.get_test_container()
|
test_container = utils.get_test_container()
|
||||||
test_container_obj = objects.Container(self.context, **test_container)
|
test_container_obj = objects.Container(self.context, **test_container)
|
||||||
@ -695,11 +801,13 @@ class TestContainerController(api_base.FunctionalTest):
|
|||||||
'/v1/containers/%s/%s/' % (container_uuid, 'kill'))
|
'/v1/containers/%s/%s/' % (container_uuid, 'kill'))
|
||||||
self.assertTrue(mock_container_kill.called)
|
self.assertTrue(mock_container_kill.called)
|
||||||
|
|
||||||
|
@patch('zun.common.utils.validate_container_state')
|
||||||
@patch('zun.compute.rpcapi.API.container_kill')
|
@patch('zun.compute.rpcapi.API.container_kill')
|
||||||
@patch('zun.objects.Container.get_by_uuid')
|
@patch('zun.objects.Container.get_by_uuid')
|
||||||
def test_kill_container_with_exception(self,
|
def test_kill_container_with_exception(self,
|
||||||
mock_get_by_uuid,
|
mock_get_by_uuid,
|
||||||
mock_container_kill):
|
mock_container_kill,
|
||||||
|
mock_validate):
|
||||||
mock_container_kill.return_value = ""
|
mock_container_kill.return_value = ""
|
||||||
test_container = utils.get_test_container()
|
test_container = utils.get_test_container()
|
||||||
test_container_obj = objects.Container(self.context, **test_container)
|
test_container_obj = objects.Container(self.context, **test_container)
|
||||||
|
@ -18,10 +18,12 @@ from zun.common import exception
|
|||||||
from zun.common import utils
|
from zun.common import utils
|
||||||
from zun.common.utils import check_container_id
|
from zun.common.utils import check_container_id
|
||||||
from zun.common.utils import translate_exception
|
from zun.common.utils import translate_exception
|
||||||
|
from zun.objects.container import Container
|
||||||
from zun.tests import base
|
from zun.tests import base
|
||||||
|
from zun.tests.unit.db import utils as db_utils
|
||||||
|
|
||||||
|
|
||||||
class TestUtils(base.BaseTestCase):
|
class TestUtils(base.TestCase):
|
||||||
"""Test cases for zun.common.utils"""
|
"""Test cases for zun.common.utils"""
|
||||||
|
|
||||||
def test_check_container_id(self):
|
def test_check_container_id(self):
|
||||||
@ -73,3 +75,31 @@ class TestUtils(base.BaseTestCase):
|
|||||||
self.assertTrue(utils.should_pull_image('always', False))
|
self.assertTrue(utils.should_pull_image('always', False))
|
||||||
self.assertTrue(utils.should_pull_image('ifnotpresent', False))
|
self.assertTrue(utils.should_pull_image('ifnotpresent', False))
|
||||||
self.assertFalse(utils.should_pull_image('ifnotpresent', True))
|
self.assertFalse(utils.should_pull_image('ifnotpresent', True))
|
||||||
|
|
||||||
|
def test_validate_container_state(self):
|
||||||
|
container = Container(self.context, **db_utils.get_test_container())
|
||||||
|
container.status = 'Stopped'
|
||||||
|
with self.assertRaisesRegexp(exception.InvalidStateException,
|
||||||
|
"%s" % container.uuid):
|
||||||
|
utils.validate_container_state(container, 'stop')
|
||||||
|
with self.assertRaisesRegexp(exception.InvalidStateException,
|
||||||
|
"%s" % container.uuid):
|
||||||
|
utils.validate_container_state(container, 'pause')
|
||||||
|
container.status = 'Running'
|
||||||
|
with self.assertRaisesRegexp(exception.InvalidStateException,
|
||||||
|
"%s" % container.uuid):
|
||||||
|
utils.validate_container_state(container, 'start')
|
||||||
|
with self.assertRaisesRegexp(exception.InvalidStateException,
|
||||||
|
"%s" % container.uuid):
|
||||||
|
utils.validate_container_state(container, 'unpause')
|
||||||
|
with self.assertRaisesRegexp(exception.InvalidStateException,
|
||||||
|
"%s" % container.uuid):
|
||||||
|
utils.validate_container_state(container, 'delete')
|
||||||
|
self.assertIsNone(utils.validate_container_state(
|
||||||
|
container, 'reboot'))
|
||||||
|
container.status = 'Stopped'
|
||||||
|
self.assertIsNone(utils.validate_container_state(
|
||||||
|
container, 'reboot'))
|
||||||
|
container.status = 'Running'
|
||||||
|
self.assertIsNone(utils.validate_container_state(
|
||||||
|
container, 'execute'))
|
||||||
|
@ -42,33 +42,6 @@ class TestManager(base.TestCase):
|
|||||||
self.assertEqual("Creation Failed", container.status_reason)
|
self.assertEqual("Creation Failed", container.status_reason)
|
||||||
self.assertIsNone(container.task_state)
|
self.assertIsNone(container.task_state)
|
||||||
|
|
||||||
def test_validate_container_state(self):
|
|
||||||
container = Container(self.context, **utils.get_test_container())
|
|
||||||
container.status = 'Stopped'
|
|
||||||
with self.assertRaisesRegexp(exception.InvalidStateException,
|
|
||||||
"%s" % container.uuid):
|
|
||||||
self.compute_manager._validate_container_state(container, 'stop')
|
|
||||||
with self.assertRaisesRegexp(exception.InvalidStateException,
|
|
||||||
"%s" % container.uuid):
|
|
||||||
self.compute_manager._validate_container_state(container, 'pause')
|
|
||||||
container.status = 'Running'
|
|
||||||
with self.assertRaisesRegexp(exception.InvalidStateException,
|
|
||||||
"%s" % container.uuid):
|
|
||||||
self.compute_manager._validate_container_state(container, 'start')
|
|
||||||
with self.assertRaisesRegexp(exception.InvalidStateException,
|
|
||||||
"%s" % container.uuid):
|
|
||||||
self.compute_manager._validate_container_state(container,
|
|
||||||
'unpause')
|
|
||||||
container.status = 'Running'
|
|
||||||
self.assertIsNone(self.compute_manager._validate_container_state(
|
|
||||||
container, 'reboot'))
|
|
||||||
container.status = 'Stopped'
|
|
||||||
self.assertIsNone(self.compute_manager._validate_container_state(
|
|
||||||
container, 'reboot'))
|
|
||||||
container.status = 'Running'
|
|
||||||
self.assertIsNone(self.compute_manager._validate_container_state(
|
|
||||||
container, 'exec'))
|
|
||||||
|
|
||||||
@mock.patch.object(Container, 'save')
|
@mock.patch.object(Container, 'save')
|
||||||
@mock.patch('zun.image.driver.pull_image')
|
@mock.patch('zun.image.driver.pull_image')
|
||||||
@mock.patch.object(fake_driver, 'create')
|
@mock.patch.object(fake_driver, 'create')
|
||||||
@ -218,24 +191,14 @@ class TestManager(base.TestCase):
|
|||||||
mock_create.assert_called_once_with(container, None,
|
mock_create.assert_called_once_with(container, None,
|
||||||
{'name': 'nginx', 'path': None})
|
{'name': 'nginx', 'path': None})
|
||||||
|
|
||||||
@mock.patch.object(manager.Manager, '_validate_container_state')
|
|
||||||
@mock.patch.object(fake_driver, 'delete')
|
@mock.patch.object(fake_driver, 'delete')
|
||||||
def test_container_delete(self, mock_delete, mock_validate):
|
def test_container_delete(self, mock_delete):
|
||||||
container = Container(self.context, **utils.get_test_container())
|
container = Container(self.context, **utils.get_test_container())
|
||||||
self.compute_manager.container_delete(self. context, container, False)
|
self.compute_manager.container_delete(self. context, container, False)
|
||||||
mock_delete.assert_called_once_with(container, False)
|
mock_delete.assert_called_once_with(container, False)
|
||||||
|
|
||||||
@mock.patch.object(manager.Manager, '_validate_container_state')
|
|
||||||
def test_container_delete_invalid_state(self, mock_validate):
|
|
||||||
container = Container(self.context, **utils.get_test_container())
|
|
||||||
mock_validate.side_effect = exception.InvalidStateException
|
|
||||||
self.assertRaises(exception.InvalidStateException,
|
|
||||||
self.compute_manager.container_delete,
|
|
||||||
self.context, container, False)
|
|
||||||
|
|
||||||
@mock.patch.object(manager.Manager, '_validate_container_state')
|
|
||||||
@mock.patch.object(fake_driver, 'delete')
|
@mock.patch.object(fake_driver, 'delete')
|
||||||
def test_container_delete_failed(self, mock_delete, mock_validate):
|
def test_container_delete_failed(self, mock_delete):
|
||||||
container = Container(self.context, **utils.get_test_container())
|
container = Container(self.context, **utils.get_test_container())
|
||||||
mock_delete.side_effect = exception.DockerError
|
mock_delete.side_effect = exception.DockerError
|
||||||
self.assertRaises(exception.DockerError,
|
self.assertRaises(exception.DockerError,
|
||||||
@ -268,130 +231,78 @@ class TestManager(base.TestCase):
|
|||||||
self.compute_manager.container_show,
|
self.compute_manager.container_show,
|
||||||
self.context, container)
|
self.context, container)
|
||||||
|
|
||||||
@mock.patch.object(manager.Manager, '_validate_container_state')
|
|
||||||
@mock.patch.object(fake_driver, 'reboot')
|
@mock.patch.object(fake_driver, 'reboot')
|
||||||
def test_container_reboot(self, mock_reboot, mock_validate):
|
def test_container_reboot(self, mock_reboot):
|
||||||
container = Container(self.context, **utils.get_test_container())
|
container = Container(self.context, **utils.get_test_container())
|
||||||
self.compute_manager.container_reboot(self.context, container, 10)
|
self.compute_manager._do_container_reboot(self.context, container, 10)
|
||||||
mock_reboot.assert_called_once_with(container, 10)
|
mock_reboot.assert_called_once_with(container, 10)
|
||||||
|
|
||||||
@mock.patch.object(manager.Manager, '_validate_container_state')
|
|
||||||
def test_container_reboot_invalid_state(self, mock_validate):
|
|
||||||
container = Container(self.context, **utils.get_test_container())
|
|
||||||
mock_validate.side_effect = exception.InvalidStateException
|
|
||||||
self.assertRaises(exception.InvalidStateException,
|
|
||||||
self.compute_manager.container_reboot,
|
|
||||||
self.context, container, 10)
|
|
||||||
|
|
||||||
@mock.patch.object(manager.Manager, '_validate_container_state')
|
|
||||||
@mock.patch.object(fake_driver, 'reboot')
|
@mock.patch.object(fake_driver, 'reboot')
|
||||||
def test_container_reboot_failed(self, mock_reboot, mock_validate):
|
def test_container_reboot_failed(self, mock_reboot):
|
||||||
container = Container(self.context, **utils.get_test_container())
|
container = Container(self.context, **utils.get_test_container())
|
||||||
mock_reboot.side_effect = exception.DockerError
|
mock_reboot.side_effect = exception.DockerError
|
||||||
self.assertRaises(exception.DockerError,
|
self.assertRaises(exception.DockerError,
|
||||||
self.compute_manager.container_reboot,
|
self.compute_manager._do_container_reboot,
|
||||||
self.context, container, 10)
|
self.context, container, 10, reraise=True)
|
||||||
|
|
||||||
@mock.patch.object(manager.Manager, '_validate_container_state')
|
|
||||||
@mock.patch.object(fake_driver, 'stop')
|
@mock.patch.object(fake_driver, 'stop')
|
||||||
def test_container_stop(self, mock_stop, mock_validate):
|
def test_container_stop(self, mock_stop):
|
||||||
container = Container(self.context, **utils.get_test_container())
|
container = Container(self.context, **utils.get_test_container())
|
||||||
self.compute_manager.container_stop(self.context, container, 10)
|
self.compute_manager._do_container_stop(self.context, container, 10)
|
||||||
mock_stop.assert_called_once_with(container, 10)
|
mock_stop.assert_called_once_with(container, 10)
|
||||||
|
|
||||||
@mock.patch.object(manager.Manager, '_validate_container_state')
|
|
||||||
def test_container_stop_invalid_state(self, mock_validate):
|
|
||||||
container = Container(self.context, **utils.get_test_container())
|
|
||||||
mock_validate.side_effect = exception.InvalidStateException
|
|
||||||
self.assertRaises(exception.InvalidStateException,
|
|
||||||
self.compute_manager.container_stop,
|
|
||||||
self.context, container, 10)
|
|
||||||
|
|
||||||
@mock.patch.object(manager.Manager, '_validate_container_state')
|
|
||||||
@mock.patch.object(fake_driver, 'stop')
|
@mock.patch.object(fake_driver, 'stop')
|
||||||
def test_container_stop_failed(self, mock_stop, mock_validate):
|
def test_container_stop_failed(self, mock_stop):
|
||||||
container = Container(self.context, **utils.get_test_container())
|
container = Container(self.context, **utils.get_test_container())
|
||||||
mock_stop.side_effect = exception.DockerError
|
mock_stop.side_effect = exception.DockerError
|
||||||
self.assertRaises(exception.DockerError,
|
self.assertRaises(exception.DockerError,
|
||||||
self.compute_manager.container_stop,
|
self.compute_manager._do_container_stop,
|
||||||
self.context, container, 10)
|
self.context, container, 10, reraise=True)
|
||||||
|
|
||||||
@mock.patch.object(manager.Manager, '_validate_container_state')
|
|
||||||
@mock.patch.object(fake_driver, 'start')
|
@mock.patch.object(fake_driver, 'start')
|
||||||
def test_container_start(self, mock_start, mock_validate):
|
def test_container_start(self, mock_start):
|
||||||
container = Container(self.context, **utils.get_test_container())
|
container = Container(self.context, **utils.get_test_container())
|
||||||
self.compute_manager.container_start(self.context, container)
|
self.compute_manager._do_container_start(self.context, container)
|
||||||
mock_start.assert_called_once_with(container)
|
mock_start.assert_called_once_with(container)
|
||||||
|
|
||||||
@mock.patch.object(manager.Manager, '_validate_container_state')
|
|
||||||
@mock.patch.object(manager.Manager, '_fail_container')
|
|
||||||
def test_container_start_invalid_state(self, mock_fail, mock_validate):
|
|
||||||
container = Container(self.context, **utils.get_test_container())
|
|
||||||
mock_validate.side_effect = exception.InvalidStateException
|
|
||||||
self.assertRaises(exception.InvalidStateException,
|
|
||||||
self.compute_manager.container_start,
|
|
||||||
self.context, container)
|
|
||||||
mock_fail.assert_called_once()
|
|
||||||
|
|
||||||
@mock.patch.object(manager.Manager, '_validate_container_state')
|
|
||||||
@mock.patch.object(manager.Manager, '_fail_container')
|
@mock.patch.object(manager.Manager, '_fail_container')
|
||||||
@mock.patch.object(fake_driver, 'start')
|
@mock.patch.object(fake_driver, 'start')
|
||||||
def test_container_start_failed(self, mock_start,
|
def test_container_start_failed(self, mock_start,
|
||||||
mock_fail, mock_validate):
|
mock_fail):
|
||||||
container = Container(self.context, **utils.get_test_container())
|
container = Container(self.context, **utils.get_test_container())
|
||||||
mock_start.side_effect = exception.DockerError
|
mock_start.side_effect = exception.DockerError
|
||||||
self.assertRaises(exception.DockerError,
|
self.assertRaises(exception.DockerError,
|
||||||
self.compute_manager.container_start,
|
self.compute_manager._do_container_start,
|
||||||
self.context, container)
|
self.context, container, reraise=True)
|
||||||
mock_fail.assert_called_once()
|
mock_fail.assert_called_once()
|
||||||
|
|
||||||
@mock.patch.object(manager.Manager, '_validate_container_state')
|
|
||||||
@mock.patch.object(fake_driver, 'pause')
|
@mock.patch.object(fake_driver, 'pause')
|
||||||
def test_container_pause(self, mock_pause, mock_validate):
|
def test_container_pause(self, mock_pause):
|
||||||
container = Container(self.context, **utils.get_test_container())
|
container = Container(self.context, **utils.get_test_container())
|
||||||
self.compute_manager.container_pause(self.context, container)
|
self.compute_manager._do_container_pause(self.context, container)
|
||||||
mock_pause.assert_called_once_with(container)
|
mock_pause.assert_called_once_with(container)
|
||||||
|
|
||||||
@mock.patch.object(manager.Manager, '_validate_container_state')
|
|
||||||
def test_container_pause_invalid_state(self, mock_validate):
|
|
||||||
container = Container(self.context, **utils.get_test_container())
|
|
||||||
mock_validate.side_effect = exception.InvalidStateException
|
|
||||||
self.assertRaises(exception.InvalidStateException,
|
|
||||||
self.compute_manager.container_pause,
|
|
||||||
self.context, container)
|
|
||||||
|
|
||||||
@mock.patch.object(manager.Manager, '_validate_container_state')
|
|
||||||
@mock.patch.object(fake_driver, 'pause')
|
@mock.patch.object(fake_driver, 'pause')
|
||||||
def test_container_pause_failed(self, mock_pause, mock_validate):
|
def test_container_pause_failed(self, mock_pause):
|
||||||
container = Container(self.context, **utils.get_test_container())
|
container = Container(self.context, **utils.get_test_container())
|
||||||
mock_pause.side_effect = exception.DockerError
|
mock_pause.side_effect = exception.DockerError
|
||||||
self.assertRaises(exception.DockerError,
|
self.assertRaises(exception.DockerError,
|
||||||
self.compute_manager.container_pause,
|
self.compute_manager._do_container_pause,
|
||||||
self.context, container)
|
self.context, container, reraise=True)
|
||||||
|
|
||||||
@mock.patch.object(manager.Manager, '_validate_container_state')
|
|
||||||
@mock.patch.object(fake_driver, 'unpause')
|
@mock.patch.object(fake_driver, 'unpause')
|
||||||
def test_container_unpause(self, mock_unpause, mock_validate):
|
def test_container_unpause(self, mock_unpause):
|
||||||
container = Container(self.context, **utils.get_test_container())
|
container = Container(self.context, **utils.get_test_container())
|
||||||
self.compute_manager.container_unpause(self.context, container)
|
self.compute_manager._do_container_unpause(self.context, container)
|
||||||
mock_unpause.assert_called_once_with(container)
|
mock_unpause.assert_called_once_with(container)
|
||||||
|
|
||||||
@mock.patch.object(manager.Manager, '_validate_container_state')
|
|
||||||
def test_container_unpause_invalid_state(self, mock_validate):
|
|
||||||
container = Container(self.context, **utils.get_test_container())
|
|
||||||
mock_validate.side_effect = exception.InvalidStateException
|
|
||||||
self.assertRaises(exception.InvalidStateException,
|
|
||||||
self.compute_manager.container_unpause,
|
|
||||||
self.context, container)
|
|
||||||
|
|
||||||
@mock.patch.object(manager.Manager, '_validate_container_state')
|
|
||||||
@mock.patch.object(fake_driver, 'unpause')
|
@mock.patch.object(fake_driver, 'unpause')
|
||||||
def test_container_unpause_failed(self, mock_unpause, mock_validate):
|
def test_container_unpause_failed(self, mock_unpause):
|
||||||
container = Container(self.context, **utils.get_test_container())
|
container = Container(self.context, **utils.get_test_container())
|
||||||
mock_unpause.side_effect = exception.DockerError
|
mock_unpause.side_effect = exception.DockerError
|
||||||
self.assertRaises(exception.DockerError,
|
self.assertRaises(exception.DockerError,
|
||||||
self.compute_manager.container_unpause,
|
self.compute_manager._do_container_unpause,
|
||||||
self.context, container)
|
self.context, container, reraise=True)
|
||||||
|
|
||||||
@mock.patch.object(fake_driver, 'show_logs')
|
@mock.patch.object(fake_driver, 'show_logs')
|
||||||
def test_container_logs(self, mock_logs):
|
def test_container_logs(self, mock_logs):
|
||||||
@ -414,14 +325,6 @@ class TestManager(base.TestCase):
|
|||||||
self.context, container, 'fake_cmd')
|
self.context, container, 'fake_cmd')
|
||||||
mock_execute.assert_called_once_with(container, 'fake_cmd')
|
mock_execute.assert_called_once_with(container, 'fake_cmd')
|
||||||
|
|
||||||
@mock.patch.object(manager.Manager, '_validate_container_state')
|
|
||||||
def test_container_execute_invalid_state(self, mock_validate):
|
|
||||||
container = Container(self.context, **utils.get_test_container())
|
|
||||||
mock_validate.side_effect = exception.InvalidStateException
|
|
||||||
self.assertRaises(exception.InvalidStateException,
|
|
||||||
self.compute_manager.container_exec,
|
|
||||||
self.context, container, 'fake_cmd')
|
|
||||||
|
|
||||||
@mock.patch.object(fake_driver, 'execute')
|
@mock.patch.object(fake_driver, 'execute')
|
||||||
def test_container_execute_failed(self, mock_execute):
|
def test_container_execute_failed(self, mock_execute):
|
||||||
container = Container(self.context, **utils.get_test_container())
|
container = Container(self.context, **utils.get_test_container())
|
||||||
@ -433,22 +336,13 @@ class TestManager(base.TestCase):
|
|||||||
@mock.patch.object(fake_driver, 'kill')
|
@mock.patch.object(fake_driver, 'kill')
|
||||||
def test_container_kill(self, mock_kill):
|
def test_container_kill(self, mock_kill):
|
||||||
container = Container(self.context, **utils.get_test_container())
|
container = Container(self.context, **utils.get_test_container())
|
||||||
self.compute_manager.container_kill(self.context, container, None)
|
self.compute_manager._do_container_kill(self.context, container, None)
|
||||||
mock_kill.assert_called_once_with(container, None)
|
mock_kill.assert_called_once_with(container, None)
|
||||||
|
|
||||||
@mock.patch.object(manager.Manager, '_validate_container_state')
|
|
||||||
def test_container_kill_invalid_state(self, mock_validate):
|
|
||||||
container = Container(self.context, **utils.get_test_container())
|
|
||||||
mock_validate.side_effect = exception.InvalidStateException
|
|
||||||
self.assertRaises(exception.InvalidStateException,
|
|
||||||
self.compute_manager.container_kill,
|
|
||||||
self.context, container, None)
|
|
||||||
|
|
||||||
@mock.patch.object(manager.Manager, '_validate_container_state')
|
|
||||||
@mock.patch.object(fake_driver, 'kill')
|
@mock.patch.object(fake_driver, 'kill')
|
||||||
def test_container_kill_failed(self, mock_kill, mock_validate):
|
def test_container_kill_failed(self, mock_kill):
|
||||||
container = Container(self.context, **utils.get_test_container())
|
container = Container(self.context, **utils.get_test_container())
|
||||||
mock_kill.side_effect = exception.DockerError
|
mock_kill.side_effect = exception.DockerError
|
||||||
self.assertRaises(exception.DockerError,
|
self.assertRaises(exception.DockerError,
|
||||||
self.compute_manager.container_kill,
|
self.compute_manager._do_container_kill,
|
||||||
self.context, container, None)
|
self.context, container, None, reraise=True)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user