nfv/nfv/nfv-vim/nfv_vim/directors/_host_director.py

776 lines
27 KiB
Python
Executable File

#
# Copyright (c) 2015-2016 Wind River Systems, Inc.
#
# SPDX-License-Identifier: Apache-2.0
#
import six
from nfv_common import debug
from nfv_common.helpers import coroutine
from nfv_common.helpers import Singleton
from nfv_vim import nfvi
from nfv_vim import objects
from nfv_vim import tables
from nfv_vim.directors._directors_defs import Operation
from nfv_vim.directors._directors_defs import OPERATION_STATE
from nfv_vim.directors._directors_defs import OPERATION_TYPE
DLOG = debug.debug_get_logger('nfv_vim.host_director')
_host_director = None
@six.add_metaclass(Singleton)
class HostDirector(object):
"""
Host Director
"""
def __init__(self):
self._host_operation = None
@coroutine
def _nfvi_lock_host_callback(self):
"""
NFVI Lock Host Callback
"""
from nfv_vim import directors
response = (yield)
DLOG.verbose("NFVI Lock Host callback response=%s." % response)
if not response['completed']:
DLOG.info("Lock of host %s failed, reason=%s."
% (response['host_name'], response['reason']))
host_table = tables.tables_get_host_table()
host = host_table.get(response['host_name'], None)
if host is None:
DLOG.verbose("Host %s does not exist." % response['host_name'])
return
if self._host_operation is None:
DLOG.verbose("No host %s operation inprogress." % host.name)
return
if OPERATION_TYPE.LOCK_HOSTS != self._host_operation.operation_type:
DLOG.verbose("Unexpected host %s operation %s, ignoring."
% (host.name, self._host_operation.operation_type))
return
sw_mgmt_director = directors.get_sw_mgmt_director()
sw_mgmt_director.host_lock_failed(host)
def _nfvi_lock_host(self, host_uuid, host_name):
"""
NFVI Lock Host
"""
nfvi.nfvi_lock_host(host_uuid, host_name, self._nfvi_lock_host_callback())
@coroutine
def _nfvi_disable_host_services_callback(self, service):
"""
NFVI Disable Host Services Callback
"""
from nfv_vim import directors
response = (yield)
DLOG.verbose("NFVI Disable Host %s Services callback "
"response=%s." % (service, response))
if not response['completed']:
DLOG.info("Disable of %s services on host %s failed"
", reason=%s."
% (service, response['host_name'], response['reason']))
host_table = tables.tables_get_host_table()
host = host_table.get(response['host_name'], None)
if host is None:
DLOG.verbose("Host %s does not exist." % response['host_name'])
return
if self._host_operation is None:
DLOG.verbose("No host %s operation inprogress." % host.name)
return
if OPERATION_TYPE.DISABLE_HOST_SERVICES != \
self._host_operation.operation_type:
DLOG.verbose("Unexpected host %s operation %s, ignoring."
% (host.name, self._host_operation.operation_type))
return
sw_mgmt_director = directors.get_sw_mgmt_director()
sw_mgmt_director.disable_host_services_failed(host)
def _nfvi_disable_host_services(self, host_uuid, host_name,
host_personality, service):
"""
NFVI Disable Host Services
"""
if service == objects.HOST_SERVICES.COMPUTE:
nfvi.nfvi_disable_compute_host_services(
host_uuid, host_name, host_personality,
self._nfvi_disable_host_services_callback(
objects.HOST_SERVICES.COMPUTE))
elif service == objects.HOST_SERVICES.GUEST:
nfvi.nfvi_disable_guest_host_services(
host_uuid, host_name, host_personality,
self._nfvi_disable_host_services_callback(
objects.HOST_SERVICES.GUEST))
elif service == objects.HOST_SERVICES.CONTAINER:
nfvi.nfvi_disable_container_host_services(
host_uuid, host_name, host_personality,
self._nfvi_disable_host_services_callback(
objects.HOST_SERVICES.CONTAINER))
else:
DLOG.error("Trying to disable unknown service: %s" % service)
@coroutine
def _nfvi_enable_host_services_callback(self, service):
"""
NFVI Enable Host Services Callback
"""
from nfv_vim import directors
response = (yield)
DLOG.verbose("NFVI Enable Host %s Services callback "
"response=%s." % (service, response))
if not response['completed']:
DLOG.info("Enable of %s services on host %s failed, reason=%s."
% (service, response['host_name'], response['reason']))
host_table = tables.tables_get_host_table()
host = host_table.get(response['host_name'], None)
if host is None:
DLOG.verbose("Host %s does not exist." % response['host_name'])
return
if self._host_operation is None:
DLOG.verbose("No host %s operation inprogress." % host.name)
return
if OPERATION_TYPE.ENABLE_HOST_SERVICES != \
self._host_operation.operation_type:
DLOG.verbose("Unexpected host %s operation %s, ignoring."
% (host.name,
self._host_operation.operation_type))
return
sw_mgmt_director = directors.get_sw_mgmt_director()
sw_mgmt_director.enable_host_services_failed(host)
def _nfvi_enable_host_services(self, host_uuid, host_name,
host_personality, service):
"""
NFVI Enable Host Services
"""
if service == objects.HOST_SERVICES.COMPUTE:
nfvi.nfvi_enable_compute_host_services(
host_uuid, host_name, host_personality,
self._nfvi_enable_host_services_callback(
objects.HOST_SERVICES.COMPUTE))
elif service == objects.HOST_SERVICES.GUEST:
nfvi.nfvi_enable_guest_host_services(
host_uuid, host_name, host_personality,
self._nfvi_enable_host_services_callback(
objects.HOST_SERVICES.GUEST))
elif service == objects.HOST_SERVICES.CONTAINER:
nfvi.nfvi_enable_container_host_services(
host_uuid, host_name, host_personality,
self._nfvi_enable_host_services_callback(
objects.HOST_SERVICES.CONTAINER))
elif service == objects.HOST_SERVICES.NETWORK:
nfvi.nfvi_enable_network_host_services(
host_uuid, host_name, host_personality,
self._nfvi_enable_host_services_callback(
objects.HOST_SERVICES.NETWORK))
else:
DLOG.error("Trying to enable unknown service: %s" % service)
@coroutine
def _nfvi_unlock_host_callback(self):
"""
NFVI Unlock Host Callback
"""
from nfv_vim import directors
response = (yield)
DLOG.verbose("NFVI Unlock Host callback response=%s." % response)
if not response['completed']:
DLOG.info("Unlock of host %s failed, reason=%s."
% (response['host_name'], response['reason']))
host_table = tables.tables_get_host_table()
host = host_table.get(response['host_name'], None)
if host is None:
DLOG.verbose("Host %s does not exist." % response['host_name'])
return
if self._host_operation is None:
DLOG.verbose("No host %s operation inprogress." % host.name)
return
if OPERATION_TYPE.UNLOCK_HOSTS != self._host_operation.operation_type:
DLOG.verbose("Unexpected host %s operation %s, ignoring."
% (host.name, self._host_operation.operation_type))
return
sw_mgmt_director = directors.get_sw_mgmt_director()
sw_mgmt_director.host_unlock_failed(host)
def _nfvi_unlock_host(self, host_uuid, host_name):
"""
NFVI Unlock Host
"""
nfvi.nfvi_unlock_host(host_uuid, host_name,
self._nfvi_unlock_host_callback())
@coroutine
def _nfvi_reboot_host_callback(self):
"""
NFVI Reboot Host Callback
"""
from nfv_vim import directors
response = (yield)
DLOG.verbose("NFVI Reboot Host callback response=%s." % response)
if not response['completed']:
DLOG.info("Reboot of host %s failed, reason=%s."
% (response['host_name'], response['reason']))
host_table = tables.tables_get_host_table()
host = host_table.get(response['host_name'], None)
if host is None:
DLOG.verbose("Host %s does not exist." % response['host_name'])
return
if self._host_operation is None:
DLOG.verbose("No host %s operation inprogress." % host.name)
return
if OPERATION_TYPE.REBOOT_HOSTS != self._host_operation.operation_type:
DLOG.verbose("Unexpected host %s operation %s, ignoring."
% (host.name, self._host_operation.operation_type))
return
sw_mgmt_director = directors.get_sw_mgmt_director()
sw_mgmt_director.host_reboot_failed(host)
def _nfvi_reboot_host(self, host_uuid, host_name):
"""
NFVI Reboot Host
"""
nfvi.nfvi_reboot_host(host_uuid, host_name,
self._nfvi_reboot_host_callback())
@coroutine
def _nfvi_upgrade_host_callback(self):
"""
NFVI Upgrade Host Callback
"""
from nfv_vim import directors
response = (yield)
DLOG.verbose("NFVI Upgrade Host callback response=%s." % response)
if not response['completed']:
DLOG.info("Upgrade of host %s failed, reason=%s."
% (response['host_name'], response['reason']))
host_table = tables.tables_get_host_table()
host = host_table.get(response['host_name'], None)
if host is None:
DLOG.verbose("Host %s does not exist." % response['host_name'])
return
if self._host_operation is None:
DLOG.verbose("No host %s operation inprogress." % host.name)
return
if OPERATION_TYPE.UPGRADE_HOSTS != self._host_operation.operation_type:
DLOG.verbose("Unexpected host %s operation %s, ignoring."
% (host.name, self._host_operation.operation_type))
return
sw_mgmt_director = directors.get_sw_mgmt_director()
sw_mgmt_director.host_upgrade_failed(host)
def _nfvi_upgrade_host(self, host_uuid, host_name):
"""
NFVI Upgrade Host
"""
nfvi.nfvi_upgrade_host(host_uuid, host_name,
self._nfvi_upgrade_host_callback())
@coroutine
def _nfvi_swact_host_callback(self):
"""
NFVI Swact Host Callback
"""
from nfv_vim import directors
response = (yield)
DLOG.verbose("NFVI Swact Host callback response=%s." % response)
if not response['completed']:
DLOG.info("Swact of host %s failed, reason=%s."
% (response['host_name'], response['reason']))
host_table = tables.tables_get_host_table()
host = host_table.get(response['host_name'], None)
if host is None:
DLOG.verbose("Host %s does not exist." % response['host_name'])
return
if self._host_operation is None:
DLOG.verbose("No host %s operation inprogress." % host.name)
return
if OPERATION_TYPE.SWACT_HOSTS != self._host_operation.operation_type:
DLOG.verbose("Unexpected host %s operation %s, ignoring."
% (host.name, self._host_operation.operation_type))
return
sw_mgmt_director = directors.get_sw_mgmt_director()
sw_mgmt_director.host_swact_failed(host)
def _nfvi_swact_host(self, host_uuid, host_name):
"""
NFVI Swact Host
"""
nfvi.nfvi_swact_from_host(host_uuid, host_name,
self._nfvi_swact_host_callback())
def host_operation_inprogress(self):
"""
Returns true if a lock of hosts
"""
if self._host_operation is not None:
return self._host_operation.is_inprogress()
return False
@staticmethod
def host_has_instances(host, skip_stopped=False):
"""
Returns true if a host has instances located on it
"""
from nfv_vim import directors
instance_director = directors.get_instance_director()
return instance_director.host_has_instances(host, skip_stopped=skip_stopped)
@staticmethod
def host_instances_moved(host, host_operation):
"""
Notifies the host director that all the instances have been moved from
a host
"""
host.notify_instances_moved(host_operation)
@staticmethod
def host_instances_stopped(host, host_operation):
"""
Notifies the host director that all the instances have been stopped on
a host
"""
host.notify_instances_stopped(host_operation)
@staticmethod
def host_enabled(host):
"""
Notifies the host director that a host is enabled
"""
from nfv_vim import directors
DLOG.info("Notify other directors that the host %s is enabled."
% host.name)
instance_director = directors.get_instance_director()
instance_director.recover_instances()
@staticmethod
def host_services_disabling(host):
"""
Notifies the host director that host services are being disabled
"""
from nfv_vim import directors
DLOG.info("Notify other directors that the host %s services are "
"disabling." % host.name)
instance_director = directors.get_instance_director()
host_operation = instance_director.host_services_disabling(host)
return host_operation
@staticmethod
def host_services_disabled(host):
"""
Notifies the host director that host services are disabled
"""
from nfv_vim import directors
DLOG.info("Notify other directors that the host %s services are "
"disabled." % host.name)
instance_director = directors.get_instance_director()
host_operation = instance_director.host_services_disabled(host)
return host_operation
@staticmethod
def host_disabled(host):
"""
Notifies the host director that a host is disabled
"""
from nfv_vim import directors
DLOG.info("Notify other directors that the host %s is disabled."
% host.name)
instance_director = directors.get_instance_director()
instance_director.host_disabled(host)
@staticmethod
def host_offline(host):
"""
Notifies the host director that a host is offline
"""
from nfv_vim import directors
DLOG.info("Notify other directors that the host %s is offline."
% host.name)
instance_director = directors.get_instance_director()
instance_director.host_offline(host)
# Now that the host is offline, we may be able to recover instances
# on that host (i.e. evacuate them).
instance_director.recover_instances()
@staticmethod
def host_audit(host):
"""
Notifies the host director that a host audit is inprogress
"""
from nfv_vim import directors
DLOG.verbose("Notify other directors that a host %s audit is inprogress."
% host.name)
instance_director = directors.get_instance_director()
instance_director.host_audit(host)
sw_mgmt_director = directors.get_sw_mgmt_director()
sw_mgmt_director.host_audit(host)
@staticmethod
def host_abort(host):
"""
Notifies the host director that a host abort is inprogress
"""
from nfv_vim import directors
DLOG.info("Notify other directors that a host %s abort is inprogress."
% host.name)
instance_director = directors.get_instance_director()
instance_director.host_operation_cancel(host.name)
@staticmethod
def host_state_change_notify(host):
"""
Notifies the host director that a host has changed state
"""
from nfv_vim import directors
DLOG.info("Host %s state change notification." % host.name)
sw_mgmt_director = directors.get_sw_mgmt_director()
sw_mgmt_director.host_state_change(host)
def lock_hosts(self, host_names):
"""
Lock a list of hosts
"""
DLOG.info("Lock hosts: %s" % host_names)
host_operation = Operation(OPERATION_TYPE.LOCK_HOSTS)
if self._host_operation is not None:
DLOG.debug("Canceling previous host operation %s, before "
"continuing with host operation %s."
% (self._host_operation.operation_type,
host_operation.operation_type))
self._host_operation = None
host_table = tables.tables_get_host_table()
for host_name in host_names:
host = host_table.get(host_name, None)
if host is None:
reason = "Unknown host %s given." % host_name
DLOG.info(reason)
host_operation.set_failed(reason)
return host_operation
if host.is_locking():
host_operation.add_host(host.name, OPERATION_STATE.INPROGRESS)
elif host.is_locked():
host_operation.add_host(host.name, OPERATION_STATE.COMPLETED)
else:
host_operation.add_host(host.name, OPERATION_STATE.INPROGRESS)
self._nfvi_lock_host(host.uuid, host.name)
if host_operation.is_inprogress():
self._host_operation = host_operation
return host_operation
def unlock_hosts(self, host_names):
"""
Unlock a list of hosts
"""
DLOG.info("Unlock hosts: %s" % host_names)
host_operation = Operation(OPERATION_TYPE.UNLOCK_HOSTS)
if self._host_operation is not None:
DLOG.debug("Canceling previous host operation %s, before "
"continuing with host operation %s."
% (self._host_operation.operation_type,
host_operation.operation_type))
self._host_operation = None
host_table = tables.tables_get_host_table()
for host_name in host_names:
host = host_table.get(host_name, None)
if host is None:
reason = "Unknown host %s given." % host_name
DLOG.info(reason)
host_operation.set_failed(reason)
return host_operation
if host.is_locked():
host_operation.add_host(host.name, OPERATION_STATE.INPROGRESS)
self._nfvi_unlock_host(host.uuid, host.name)
elif host.is_unlocking():
host_operation.add_host(host.name, OPERATION_STATE.INPROGRESS)
else:
host_operation.add_host(host.name, OPERATION_STATE.INPROGRESS)
if host_operation.is_inprogress():
self._host_operation = host_operation
return host_operation
def reboot_hosts(self, host_names):
"""
Reboot a list of hosts
"""
DLOG.info("Reboot hosts: %s" % host_names)
host_operation = Operation(OPERATION_TYPE.REBOOT_HOSTS)
if self._host_operation is not None:
DLOG.debug("Canceling previous host operation %s, before "
"continuing with host operation %s."
% (self._host_operation.operation_type,
host_operation.operation_type))
self._host_operation = None
host_table = tables.tables_get_host_table()
for host_name in host_names:
host = host_table.get(host_name, None)
if host is None:
reason = "Unknown host %s given." % host_name
DLOG.info(reason)
host_operation.set_failed(reason)
return host_operation
if host.is_locked():
host_operation.add_host(host.name, OPERATION_STATE.INPROGRESS)
self._nfvi_reboot_host(host.uuid, host.name)
else:
reason = "Cannot reboot unlocked host %s." % host_name
DLOG.info(reason)
host_operation.set_failed(reason)
return host_operation
if host_operation.is_inprogress():
self._host_operation = host_operation
return host_operation
def upgrade_hosts(self, host_names):
"""
Upgrade a list of hosts
"""
DLOG.info("Upgrade hosts: %s" % host_names)
host_operation = Operation(OPERATION_TYPE.UPGRADE_HOSTS)
if self._host_operation is not None:
DLOG.debug("Canceling previous host operation %s, before "
"continuing with host operation %s."
% (self._host_operation.operation_type,
host_operation.operation_type))
self._host_operation = None
host_table = tables.tables_get_host_table()
for host_name in host_names:
host = host_table.get(host_name, None)
if host is None:
reason = "Unknown host %s given." % host_name
DLOG.info(reason)
host_operation.set_failed(reason)
return host_operation
if host.is_locked():
host_operation.add_host(host.name, OPERATION_STATE.INPROGRESS)
self._nfvi_upgrade_host(host.uuid, host.name)
else:
reason = "Cannot upgrade unlocked host %s." % host_name
DLOG.info(reason)
host_operation.set_failed(reason)
return host_operation
if host_operation.is_inprogress():
self._host_operation = host_operation
return host_operation
def swact_hosts(self, host_names):
"""
Swact a list of hosts
"""
DLOG.info("Swact hosts: %s" % host_names)
host_operation = Operation(OPERATION_TYPE.SWACT_HOSTS)
if self._host_operation is not None:
DLOG.debug("Canceling previous host operation %s, before "
"continuing with host operation %s."
% (self._host_operation.operation_type,
host_operation.operation_type))
self._host_operation = None
host_table = tables.tables_get_host_table()
for host_name in host_names:
host = host_table.get(host_name, None)
if host is None:
reason = "Unknown host %s given." % host_name
DLOG.info(reason)
host_operation.set_failed(reason)
return host_operation
host_operation.add_host(host.name, OPERATION_STATE.INPROGRESS)
self._nfvi_swact_host(host.uuid, host.name)
if host_operation.is_inprogress():
self._host_operation = host_operation
return host_operation
def disable_host_services(self, host_names, service):
"""
Disable a host service on a list of hosts
"""
DLOG.info("Disable host services: %s service: %s" %
(host_names, service))
host_operation = Operation(OPERATION_TYPE.DISABLE_HOST_SERVICES)
if self._host_operation is not None:
DLOG.debug("Canceling previous host operation %s, before "
"continuing with host operation %s."
% (self._host_operation.operation_type,
host_operation.operation_type))
self._host_operation = None
host_table = tables.tables_get_host_table()
host_list = list()
for host_name in host_names:
host = host_table.get(host_name, None)
if host is None:
reason = "Unknown host %s given." % host_name
DLOG.info(reason)
host_operation.set_failed(reason)
return host_operation
host.host_services_locked = True
if (objects.HOST_SERVICE_STATE.DISABLED ==
host.host_service_state(service)):
host_operation.add_host(host.name, OPERATION_STATE.COMPLETED)
else:
host_operation.add_host(host.name, OPERATION_STATE.INPROGRESS)
host_list.append(host)
for host in host_list:
self._nfvi_disable_host_services(
host.uuid, host.name, host.personality, service)
if host_operation.is_inprogress():
self._host_operation = host_operation
return host_operation
def enable_host_services(self, host_names, service):
"""
Enable a host service on a list of hosts
"""
DLOG.info("Enable host services: %s service: %s" %
(host_names, service))
host_operation = Operation(OPERATION_TYPE.ENABLE_HOST_SERVICES)
if self._host_operation is not None:
DLOG.debug("Canceling previous host operation %s, before "
"continuing with host operation %s."
% (self._host_operation.operation_type,
host_operation.operation_type))
self._host_operation = None
host_table = tables.tables_get_host_table()
host_list = list()
for host_name in host_names:
host = host_table.get(host_name, None)
if host is None:
reason = "Unknown host %s given." % host_name
DLOG.info(reason)
host_operation.set_failed(reason)
return host_operation
host.host_services_locked = False
if (objects.HOST_SERVICE_STATE.ENABLED ==
host.host_service_state(service)):
host_operation.add_host(host.name, OPERATION_STATE.COMPLETED)
else:
host_operation.add_host(host.name, OPERATION_STATE.INPROGRESS)
host_list.append(host)
for host in host_list:
self._nfvi_enable_host_services(
host.uuid, host.name, host.personality, service)
if host_operation.is_inprogress():
self._host_operation = host_operation
return host_operation
def get_host_director():
"""
Returns the Host Director
"""
return _host_director
def host_director_initialize():
"""
Initialize Host Director
"""
global _host_director
_host_director = HostDirector()
def host_director_finalize():
"""
Finalize Host Director
"""
pass