Fixes for H/W replacement during Upgrades
Disallow host-delete during upgrade: Prior to the controller upgrade, disallow host-delete during an upgrade. Issue was triggered when a host-delete was allowed when the active controller has not yet been upgraded and a host-delete was performed. This updates sysinv to disallow the host-delete prior to controller upgrade. The user would need to abort and delete prior to continuing. Disallow host-lock compute during upgrade: host-lock of computes is prevented during an upgrade as instance migrations are not allowed prior to upgrading both controllers. In AIO-DX, allow host-lock controller-0 after upgrading controller-1. Story: 2002886 Task: 22847 Change-Id: If74480e9e253528ebaf0e3bc3132b93fb7aa5e8e Signed-off-by: Jack Ding <jack.ding@windriver.com>
This commit is contained in:
parent
7bc4528e9d
commit
876e915bfc
|
@ -2087,6 +2087,39 @@ class HostController(rest.RestController):
|
|||
self._api_token = None
|
||||
pass # VIM audit will pickup
|
||||
|
||||
@staticmethod
|
||||
def _check_host_delete_during_upgrade():
|
||||
""" Determine whether host delete is allowed during upgrade
|
||||
|
||||
returns: boolean False if not allowed
|
||||
"""
|
||||
|
||||
upgrade = None
|
||||
try:
|
||||
upgrade = pecan.request.dbapi.software_upgrade_get_one()
|
||||
except exception.NotFound:
|
||||
return True
|
||||
|
||||
if upgrade:
|
||||
loads = pecan.request.dbapi.load_get_list()
|
||||
to_load = cutils.get_imported_load(loads)
|
||||
|
||||
active_controller = utils.HostHelper.get_active_controller()
|
||||
host_upgrade = objects.host_upgrade.get_by_host_id(
|
||||
pecan.request.context, active_controller.id)
|
||||
|
||||
if ((host_upgrade.target_load != to_load.id) or
|
||||
(host_upgrade.software_load != to_load.id)):
|
||||
LOG.info("_check_host_delete_during_upgrade %s sw=%s "
|
||||
"target=%s load=%s" %
|
||||
(active_controller.hostname,
|
||||
host_upgrade.target_load,
|
||||
host_upgrade.software_load,
|
||||
to_load.id))
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
@cutils.synchronized(LOCK_NAME)
|
||||
@wsme_pecan.wsexpose(None, unicode, status_code=204)
|
||||
def delete(self, ihost_id):
|
||||
|
@ -2115,6 +2148,10 @@ class HostController(rest.RestController):
|
|||
|
||||
raise exception.HostLocked(action=constants.DELETE_ACTION, host=host)
|
||||
|
||||
if not self._check_host_delete_during_upgrade():
|
||||
raise wsme.exc.ClientSideError(_(
|
||||
"host-delete rejected: not allowed at this upgrade stage"))
|
||||
|
||||
personality = ihost.personality
|
||||
# allow deletion of unprovisioned locked disabled & offline storage hosts
|
||||
skip_ceph_checks = (
|
||||
|
@ -2398,6 +2435,12 @@ class HostController(rest.RestController):
|
|||
"all osds must be down.")
|
||||
% (rpc_ihost.hostname))
|
||||
|
||||
if upgrade.state in [constants.UPGRADE_STARTED]:
|
||||
LOG.info("host-upgrade check upgrade_refresh %s" %
|
||||
rpc_ihost.hostname)
|
||||
force = body.get('force', False) is True
|
||||
self._semantic_check_upgrade_refresh(upgrade, rpc_ihost, force)
|
||||
|
||||
# Update the target load for this host
|
||||
self._update_load(uuid, body, new_target_load)
|
||||
|
||||
|
@ -3717,19 +3760,20 @@ class HostController(rest.RestController):
|
|||
new_hw = []
|
||||
disks = pecan.request.dbapi.idisk_get_by_ihost(host.id)
|
||||
new_disks = [x.uuid for x in disks
|
||||
if x.created_at > upgrade_created_at]
|
||||
if x.created_at and (x.created_at > upgrade_created_at)]
|
||||
if new_disks:
|
||||
new_hw.append(('disks', host.hostname, new_disks))
|
||||
|
||||
interfaces = pecan.request.dbapi.iinterface_get_by_ihost(host.id)
|
||||
new_interfaces = [x.uuid for x in interfaces
|
||||
if x.created_at > upgrade_created_at]
|
||||
new_interfaces = [
|
||||
x.uuid for x in interfaces
|
||||
if x.created_at and (x.created_at > upgrade_created_at)]
|
||||
if new_interfaces:
|
||||
new_hw.append(('interfaces', host.hostname, new_interfaces))
|
||||
|
||||
stors = pecan.request.dbapi.istor_get_by_ihost(host.id)
|
||||
new_stors = [x.uuid for x in stors
|
||||
if x.created_at > upgrade_created_at]
|
||||
if x.created_at and (x.created_at > upgrade_created_at)]
|
||||
if new_stors:
|
||||
new_hw.append(('stors', host.hostname, new_stors))
|
||||
|
||||
|
@ -4713,6 +4757,11 @@ class HostController(rest.RestController):
|
|||
elif personality == constants.STORAGE:
|
||||
self.check_lock_storage(hostupdate)
|
||||
|
||||
subfunctions_set = \
|
||||
set(hostupdate.ihost_patch[constants.SUBFUNCTIONS].split(','))
|
||||
if constants.COMPUTE in subfunctions_set:
|
||||
self.check_lock_compute(hostupdate)
|
||||
|
||||
hostupdate.notify_vim = True
|
||||
hostupdate.notify_mtce = True
|
||||
|
||||
|
@ -5353,6 +5402,54 @@ class HostController(rest.RestController):
|
|||
"and replication is lost. This may result in data loss. ")
|
||||
raise wsme.exc.ClientSideError(msg)
|
||||
|
||||
def check_lock_compute(self, hostupdate, force=False):
|
||||
"""Pre lock semantic checks for compute"""
|
||||
|
||||
LOG.info("%s host check_lock_compute" % hostupdate.displayid)
|
||||
if force:
|
||||
return
|
||||
|
||||
upgrade = None
|
||||
try:
|
||||
upgrade = pecan.request.dbapi.software_upgrade_get_one()
|
||||
except exception.NotFound:
|
||||
return
|
||||
|
||||
upgrade_state = upgrade.state
|
||||
system = pecan.request.dbapi.isystem_get_one()
|
||||
system_mode = system.system_mode
|
||||
system_type = system.system_type
|
||||
hostname = hostupdate.ihost_patch.get('hostname')
|
||||
|
||||
if system_mode == constants.SYSTEM_MODE_SIMPLEX:
|
||||
return
|
||||
|
||||
if upgrade_state in [
|
||||
constants.UPGRADE_STARTING,
|
||||
constants.UPGRADE_STARTED,
|
||||
constants.UPGRADE_DATA_MIGRATION,
|
||||
constants.UPGRADE_DATA_MIGRATION_COMPLETE,
|
||||
constants.UPGRADE_DATA_MIGRATION_FAILED]:
|
||||
if system_type == constants.TIS_AIO_BUILD:
|
||||
if hostname == constants.CONTROLLER_1_HOSTNAME:
|
||||
# Allow AIO-DX lock of controller-1
|
||||
return
|
||||
raise wsme.exc.ClientSideError(
|
||||
_("Rejected: Can not lock %s with compute function "
|
||||
"at this upgrade stage '%s'.") %
|
||||
(hostupdate.displayid, upgrade_state))
|
||||
|
||||
if upgrade_state in [constants.UPGRADE_UPGRADING_CONTROLLERS]:
|
||||
if system_type == constants.TIS_AIO_BUILD:
|
||||
# Allow lock for AIO-DX controller-0 after upgrading
|
||||
# controller-1. Allow lock for AIO-DX controllers.
|
||||
if hostname == constants.CONTROLLER_0_HOSTNAME:
|
||||
return
|
||||
raise wsme.exc.ClientSideError(
|
||||
_("Rejected: Can not lock %s with compute function "
|
||||
"at this upgrade stage '%s'.") %
|
||||
(hostupdate.displayid, upgrade_state))
|
||||
|
||||
def check_unlock_interfaces(self, hostupdate):
|
||||
"""Semantic check for interfaces on host-unlock."""
|
||||
ihost = hostupdate.ihost_patch
|
||||
|
|
Loading…
Reference in New Issue