Merge "Add Host Maintenance Mode Get and evacuation support"

This commit is contained in:
Jenkins 2014-09-24 09:26:08 +00:00 committed by Gerrit Code Review
commit b1b733cdc0
2 changed files with 146 additions and 1 deletions

View File

@ -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.

View 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]