Merge "Add Host Maintenance Mode Get and evacuation support"
This commit is contained in:
commit
b1b733cdc0
|
@ -3,6 +3,7 @@
|
|||
import six
|
||||
import urllib
|
||||
from novaclient import base as client_base
|
||||
from novaclient import exceptions
|
||||
from novaclient.v1_1 import servers
|
||||
from novaclient.v1_1 import hypervisors
|
||||
from novaclient.v1_1 import images
|
||||
|
@ -10,6 +11,7 @@ from novaclient.v1_1 import flavors
|
|||
from novaclient.v1_1 import volumes
|
||||
from novaclient.v1_1.volume_types import VolumeType
|
||||
from powervc.common.client.extensions import base
|
||||
from powervc.common.gettextutils import _
|
||||
from powervc.common import utils
|
||||
import logging
|
||||
|
||||
|
@ -21,7 +23,7 @@ class Client(base.ClientExtension):
|
|||
def __init__(self, client):
|
||||
super(Client, self).__init__(client)
|
||||
self.manager = PVCServerManager(client)
|
||||
self.hypervisors = hypervisors.HypervisorManager(client)
|
||||
self.hypervisors = PVCHypervisorManager(client)
|
||||
self.images = images.ImageManager(client)
|
||||
self.flavors = flavors.FlavorManager(client)
|
||||
self.storage_connectivity_groups = \
|
||||
|
@ -31,6 +33,66 @@ class Client(base.ClientExtension):
|
|||
# any extensions to std nova client go below
|
||||
|
||||
|
||||
class PVCHypervisorManager(hypervisors.HypervisorManager):
|
||||
"""
|
||||
This HypervisorManager class is specific for extending PowerVC driver
|
||||
feature to get/set the hypervisor status and maintenance mode.
|
||||
"""
|
||||
|
||||
def get_host_maintenance_mode(self, hostname):
|
||||
"""Get host maintenance mode by host name from PowerVC driver
|
||||
"""
|
||||
# If cannot find hypervisor by hostname, will raise
|
||||
# itemNotFoundException from novaclient, just raise
|
||||
# to upper layer to handle.
|
||||
hypervisors = self.search(hostname)
|
||||
|
||||
if not hypervisors[0] or not self.get(hypervisors[0]):
|
||||
raise exceptions.NotFound(_("No hypervisor matching '%s' could be"
|
||||
" found.")
|
||||
% hostname)
|
||||
|
||||
hypervisor = self.get(hypervisors[0])
|
||||
|
||||
# Either "ok" (maintenance off), "entering", "on" or "error"
|
||||
# compatible with previous powervc version, if no such property
|
||||
# set as "ok"
|
||||
maintenance_status = getattr(hypervisor, "maintenance_status", "ok")
|
||||
# Either the empty string (i.e., not in maintenance),
|
||||
# "none": dont migrate anything
|
||||
# "active-only": migrate active-only vm
|
||||
# "all": migrate all vm
|
||||
maintenance_migration_action = \
|
||||
getattr(hypervisor, "maintenance_migration_action", "none")
|
||||
|
||||
return {"maintenance_status": maintenance_status,
|
||||
"maintenance_migration_action": maintenance_migration_action}
|
||||
|
||||
def update_host_maintenance_mode(self, hostname, enabled, migrate):
|
||||
"""Update host maintenance mode status.
|
||||
:hostname: The hostname of the hypervisor
|
||||
:enabled: should be "enable" or "disable"
|
||||
:migrate: should be
|
||||
"none", do not migrate any vm
|
||||
"active-only", migrate only active vm
|
||||
"all", migrate all vm
|
||||
"""
|
||||
# Refer to PowerVC HLD host maintenance mode chapter
|
||||
url = "/ego/prs/hypervisor_maintenance/%s" % hostname
|
||||
body = {"status": enabled,
|
||||
"migrate": migrate}
|
||||
|
||||
# send set maintenance mode request by put http method
|
||||
_resp, resp_body = self.api.client.put(url, body=body)
|
||||
|
||||
# check response content
|
||||
if "hypervisor_maintenance" not in resp_body:
|
||||
raise exceptions.NotFound(_("response body doesn't contain "
|
||||
"maintenance status info for %s.")
|
||||
% hostname)
|
||||
return resp_body
|
||||
|
||||
|
||||
class PVCServerManager(servers.ServerManager):
|
||||
"""
|
||||
This ServerManager class is specific for PowerVC booting a VM.
|
||||
|
|
|
@ -0,0 +1,83 @@
|
|||
# Copyright 2014 IBM Corp.
|
||||
|
||||
from webob import exc
|
||||
from nova.api.openstack import extensions
|
||||
from nova.api.openstack import wsgi
|
||||
from nova import compute
|
||||
from nova.openstack.common.gettextutils import _
|
||||
from powervc.common import constants as common_constants
|
||||
from powervc.common import config
|
||||
|
||||
config.parse_power_config([], 'nova')
|
||||
|
||||
authorize = extensions.extension_authorizer('compute', 'host-maintenance-mode')
|
||||
|
||||
|
||||
class Controller(wsgi.Controller):
|
||||
"""Controller class to show host maintenance mode and set host maintenance
|
||||
mode with evacuation operation
|
||||
"""
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(Controller, self).__init__(*args, **kwargs)
|
||||
self.compute_api = compute.API()
|
||||
self.host_api = compute.HostAPI()
|
||||
from powervc.common.client import factory
|
||||
self.pvcclient = factory.POWERVC.new_client(
|
||||
str(common_constants.SERVICE_TYPES.compute))
|
||||
|
||||
@wsgi.extends
|
||||
def show(self, req, id):
|
||||
"""Describe host-maintenance-mode by hostname."""
|
||||
context = req.environ["nova.context"]
|
||||
authorize(context)
|
||||
host_name = id
|
||||
# Get maintenance mode from powervc client
|
||||
maintenance_status = self.pvcclient.hypervisors.\
|
||||
get_host_maintenance_mode(host_name)
|
||||
|
||||
return maintenance_status
|
||||
|
||||
@wsgi.extends
|
||||
def update(self, req, id, body):
|
||||
"""Update host-maintenance-mode by hostname."""
|
||||
context = req.environ["nova.context"]
|
||||
authorize(context)
|
||||
|
||||
host_name = id
|
||||
maintenance_status_candidate = ["enable", "disable"]
|
||||
maintenance_status = body.get("status")
|
||||
if not maintenance_status or maintenance_status.lower() not in \
|
||||
maintenance_status_candidate:
|
||||
raise exc.HTTPBadRequest(_("Malformed request body, status"
|
||||
"wrong in request body, should be"
|
||||
"'enable' or 'disable'"))
|
||||
|
||||
migrate_candidate = ["none", "active-only", "all"]
|
||||
migrate = body.get("migrate", "none")
|
||||
if migrate.lower() not in migrate_candidate:
|
||||
raise exc.HTTPBadRequest(_("Malformed request body, migrate wrong "
|
||||
"in request body, should be 'none',"
|
||||
"active-only, all or empty"))
|
||||
# Set maintenance mode from powervc client
|
||||
maintenance_update_status = self.pvcclient.hypervisors.\
|
||||
update_host_maintenance_mode(host_name, maintenance_status,
|
||||
migrate)
|
||||
return maintenance_update_status
|
||||
|
||||
|
||||
class Host_maintenance_mode(extensions.ExtensionDescriptor):
|
||||
"""Get and enable/disable Host maintenance mode, and evacuate all
|
||||
servers for the maintenance mode entered host.
|
||||
"""
|
||||
|
||||
name = "Host-maintenance-mode"
|
||||
alias = "os-host-maintenance-mode"
|
||||
namespace = "http://docs.openstack.org/compute/ext/host_maintenance_mode/"\
|
||||
"api/v2"
|
||||
updated = "2014-09-15T00:00:00Z"
|
||||
|
||||
def get_resources(self):
|
||||
controller = Controller()
|
||||
res = extensions.ResourceExtension(Host_maintenance_mode.alias,
|
||||
controller)
|
||||
return [res]
|
Loading…
Reference in New Issue