Add Host Maintenance Mode Get and evacuation support
To support GET the "host maintenance mode" from PowerVC by PowerVC Driver, and evacuation all host out of the maintenance entered host by PowerVC Driver. The design finally goes to Implement a new nova rest-API for Get/Set maintenance status, and evacuate vm during maintenance. Change-Id: I9fba6b47e143ae8ea2165573302448fcdc61406f Closes-Bug: 1372730
This commit is contained in:
parent
66ac1ea035
commit
3b9f42bf53
@ -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.
|
||||
|
83
nova-powervc/powervc/nova/extension/host_maintenance_mode.py
Normal file
83
nova-powervc/powervc/nova/extension/host_maintenance_mode.py
Normal file
@ -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
Block a user