Merge "Bring fw update detect and monitor up to the host level"
This commit is contained in:
commit
91d18e0615
|
@ -33,6 +33,7 @@ def host_state(host_uuid, host_name, host_personality, host_sub_functions,
|
|||
data_port_oper_state, data_port_avail_status,
|
||||
data_port_fault_handling_enabled):
|
||||
"""
|
||||
Takes as input the host state info received from maintenance.
|
||||
Returns a tuple of administrative state, operational state, availability
|
||||
status and nfvi-data for a host from the perspective of being able to
|
||||
host services and instances.
|
||||
|
@ -417,6 +418,7 @@ class NFVIInfrastructureAPI(nfvi.api.v1.NFVIInfrastructureAPI):
|
|||
host_action = host_action.rstrip('-')
|
||||
software_load = host_data['software_load']
|
||||
target_load = host_data['target_load']
|
||||
device_image_update = host_data['device_image_update']
|
||||
|
||||
future.work(sysinv.get_host_labels, self._platform_token,
|
||||
host_uuid)
|
||||
|
@ -450,6 +452,7 @@ class NFVIInfrastructureAPI(nfvi.api.v1.NFVIInfrastructureAPI):
|
|||
host_data['uptime'],
|
||||
software_load,
|
||||
target_load,
|
||||
device_image_update,
|
||||
openstack_compute,
|
||||
openstack_control,
|
||||
remote_storage,
|
||||
|
@ -552,6 +555,7 @@ class NFVIInfrastructureAPI(nfvi.api.v1.NFVIInfrastructureAPI):
|
|||
host_action = (host_data.get('ihost_action') or "").rstrip('-')
|
||||
software_load = host_data['software_load']
|
||||
target_load = host_data['target_load']
|
||||
device_image_update = host_data['device_image_update']
|
||||
|
||||
admin_state, oper_state, avail_status, nfvi_data \
|
||||
= host_state(host_uuid, host_name, host_personality,
|
||||
|
@ -584,6 +588,7 @@ class NFVIInfrastructureAPI(nfvi.api.v1.NFVIInfrastructureAPI):
|
|||
host_data['uptime'],
|
||||
software_load,
|
||||
target_load,
|
||||
device_image_update,
|
||||
openstack_compute,
|
||||
openstack_control,
|
||||
remote_storage,
|
||||
|
@ -1268,6 +1273,7 @@ class NFVIInfrastructureAPI(nfvi.api.v1.NFVIInfrastructureAPI):
|
|||
host_action = (host_data.get('ihost_action') or "").rstrip('-')
|
||||
software_load = host_data['software_load']
|
||||
target_load = host_data['target_load']
|
||||
device_image_update = host_data['device_image_update']
|
||||
|
||||
admin_state, oper_state, avail_status, nfvi_data \
|
||||
= host_state(host_uuid, host_name, host_personality,
|
||||
|
@ -1300,6 +1306,7 @@ class NFVIInfrastructureAPI(nfvi.api.v1.NFVIInfrastructureAPI):
|
|||
host_data['uptime'],
|
||||
software_load,
|
||||
target_load,
|
||||
device_image_update,
|
||||
openstack_compute,
|
||||
openstack_control,
|
||||
remote_storage,
|
||||
|
@ -1386,6 +1393,7 @@ class NFVIInfrastructureAPI(nfvi.api.v1.NFVIInfrastructureAPI):
|
|||
host_action = (host_data.get('ihost_action') or "").rstrip('-')
|
||||
software_load = host_data['software_load']
|
||||
target_load = host_data['target_load']
|
||||
device_image_update = host_data['device_image_update']
|
||||
|
||||
admin_state, oper_state, avail_status, nfvi_data \
|
||||
= host_state(host_uuid, host_name, host_personality,
|
||||
|
@ -1418,6 +1426,7 @@ class NFVIInfrastructureAPI(nfvi.api.v1.NFVIInfrastructureAPI):
|
|||
host_data['uptime'],
|
||||
software_load,
|
||||
target_load,
|
||||
device_image_update,
|
||||
openstack_compute,
|
||||
openstack_control,
|
||||
remote_storage,
|
||||
|
@ -1503,6 +1512,7 @@ class NFVIInfrastructureAPI(nfvi.api.v1.NFVIInfrastructureAPI):
|
|||
data_port_avail_status = state.get('data_ports_avail', None)
|
||||
software_load = host_data['software_load']
|
||||
target_load = host_data['target_load']
|
||||
device_image_update = host_data['device_image_update']
|
||||
|
||||
admin_state, oper_state, avail_status, nfvi_data \
|
||||
= host_state(host_uuid, host_name, host_personality,
|
||||
|
@ -1535,6 +1545,7 @@ class NFVIInfrastructureAPI(nfvi.api.v1.NFVIInfrastructureAPI):
|
|||
host_data['uptime'],
|
||||
software_load,
|
||||
target_load,
|
||||
device_image_update,
|
||||
openstack_compute,
|
||||
openstack_control,
|
||||
remote_storage,
|
||||
|
@ -1619,6 +1630,7 @@ class NFVIInfrastructureAPI(nfvi.api.v1.NFVIInfrastructureAPI):
|
|||
data_port_avail_status = state.get('data_ports_avail', None)
|
||||
software_load = host_data['software_load']
|
||||
target_load = host_data['target_load']
|
||||
device_image_update = host_data['device_image_update']
|
||||
|
||||
admin_state, oper_state, avail_status, nfvi_data \
|
||||
= host_state(host_uuid, host_name, host_personality,
|
||||
|
@ -1651,6 +1663,7 @@ class NFVIInfrastructureAPI(nfvi.api.v1.NFVIInfrastructureAPI):
|
|||
host_data['uptime'],
|
||||
software_load,
|
||||
target_load,
|
||||
device_image_update,
|
||||
openstack_compute,
|
||||
openstack_control,
|
||||
remote_storage,
|
||||
|
@ -1788,6 +1801,7 @@ class NFVIInfrastructureAPI(nfvi.api.v1.NFVIInfrastructureAPI):
|
|||
data_port_avail_status = state.get('data_ports_avail', None)
|
||||
software_load = host_data['software_load']
|
||||
target_load = host_data['target_load']
|
||||
device_image_update = host_data['device_image_update']
|
||||
|
||||
admin_state, oper_state, avail_status, nfvi_data \
|
||||
= host_state(host_uuid, host_name, host_personality,
|
||||
|
@ -1820,6 +1834,7 @@ class NFVIInfrastructureAPI(nfvi.api.v1.NFVIInfrastructureAPI):
|
|||
host_data['uptime'],
|
||||
software_load,
|
||||
target_load,
|
||||
device_image_update,
|
||||
openstack_compute,
|
||||
openstack_control,
|
||||
remote_storage,
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -14,16 +14,16 @@ from . import testcase # noqa: H304
|
|||
|
||||
class TestNFVDatabaseUpgrade(testcase.NFVTestCase):
|
||||
|
||||
def test_nfv_vim_database_upgrade_from_18_03(self):
|
||||
def test_nfv_vim_database_upgrade_from_19_12(self):
|
||||
"""
|
||||
Test VIM database upgrades from 18.03 GA
|
||||
Test VIM database upgrades from stx 19_12
|
||||
"""
|
||||
root_dir = os.environ['VIRTUAL_ENV']
|
||||
|
||||
devnull = open(os.devnull, 'w')
|
||||
try:
|
||||
vim_cmd = ("nfv-vim-manage db-load-data -d %s "
|
||||
"-f %s/nfv_vim_db_18.03_GA" % (root_dir, root_dir))
|
||||
"-f %s/nfv_vim_db_stx_19.12" % (root_dir, root_dir))
|
||||
|
||||
subprocess.check_call([vim_cmd], shell=True, stderr=devnull)
|
||||
|
||||
|
|
|
@ -64,10 +64,10 @@ def database_host_add(host_obj):
|
|||
"""
|
||||
db = database_get()
|
||||
session = db.session()
|
||||
query = session.query(model.Host_v6).filter(model.Host_v6.name == host_obj.name)
|
||||
query = session.query(model.Host_v7).filter(model.Host_v7.name == host_obj.name)
|
||||
host = query.first()
|
||||
if not host:
|
||||
host = model.Host_v6()
|
||||
host = model.Host_v7()
|
||||
host.uuid = host_obj.uuid
|
||||
host.name = host_obj.name
|
||||
host.personality = host_obj.personality
|
||||
|
@ -98,8 +98,8 @@ def database_host_delete(host_name):
|
|||
"""
|
||||
db = database_get()
|
||||
session = db.session()
|
||||
query = session.query(model.Host_v6)
|
||||
query.filter(model.Host_v6.name == host_name).delete()
|
||||
query = session.query(model.Host_v7)
|
||||
query.filter(model.Host_v7.name == host_name).delete()
|
||||
session.commit()
|
||||
|
||||
|
||||
|
@ -124,6 +124,7 @@ def database_host_get_list():
|
|||
nfvi_host_data['uptime'],
|
||||
nfvi_host_data['software_load'],
|
||||
nfvi_host_data['target_load'],
|
||||
nfvi_host_data['device_image_update'],
|
||||
nfvi_host_data['openstack_compute'],
|
||||
nfvi_host_data['openstack_control'],
|
||||
nfvi_host_data['remote_storage'],
|
||||
|
|
|
@ -12,53 +12,28 @@ from nfv_common import debug
|
|||
DLOG = debug.debug_get_logger('nfv_vim.database')
|
||||
|
||||
|
||||
def _migrate_hosts_v5_to_v6(session, hosts_v5, hosts_v6):
|
||||
def _migrate_hosts_v6_to_v7(session, hosts_v6, hosts_v7):
|
||||
"""
|
||||
Migrate host_v5 table to host_v6 table
|
||||
Migrate host_v6 table to host_v7 table
|
||||
"""
|
||||
if 0 == len(hosts_v6):
|
||||
for host_v5 in hosts_v5:
|
||||
host_v6 = model.Host_v6()
|
||||
host_v6.data = host_v5.data
|
||||
nfvi_host_data = json.loads(host_v5.nfvi_host_data)
|
||||
nfvi_host_data['openstack_compute'] = False
|
||||
nfvi_host_data['openstack_control'] = False
|
||||
nfvi_host_data['remote_storage'] = False
|
||||
host_v6.nfvi_host_data = json.dumps(nfvi_host_data)
|
||||
session.add(host_v6)
|
||||
|
||||
|
||||
def _migrate_instance_types_v4_to_v5(session, instance_types_v4,
|
||||
instance_types_v5):
|
||||
"""
|
||||
Migrate instance_types_v4 table to instance_types_v5 table
|
||||
"""
|
||||
if 0 == len(instance_types_v5):
|
||||
for instance_type_v4 in instance_types_v4:
|
||||
instance_type_v5 = model.InstanceType_v5()
|
||||
del instance_type_v4.data['storage_type']
|
||||
instance_type_v5.data = instance_type_v4.data
|
||||
session.add(instance_type_v5)
|
||||
if 0 == len(hosts_v7):
|
||||
for host_v6 in hosts_v6:
|
||||
host_v7 = model.Host_v7()
|
||||
host_v7.data = host_v6.data
|
||||
nfvi_host_data = json.loads(host_v6.nfvi_host_data)
|
||||
nfvi_host_data['device_image_update'] = None
|
||||
host_v7.nfvi_host_data = json.dumps(nfvi_host_data)
|
||||
session.add(host_v7)
|
||||
|
||||
|
||||
def migrate_tables(session, table_names):
|
||||
"""
|
||||
Migrate database tables
|
||||
"""
|
||||
if 'hosts_v5' in table_names and 'hosts_v6' in table_names:
|
||||
hosts_v5_query = session.query(model.Host_v5)
|
||||
hosts_v5 = hosts_v5_query.all()
|
||||
if 'hosts_v6' in table_names and 'hosts_v7' in table_names:
|
||||
hosts_v6_query = session.query(model.Host_v6)
|
||||
hosts_v6 = hosts_v6_query.all()
|
||||
_migrate_hosts_v5_to_v6(session, hosts_v5, hosts_v6)
|
||||
hosts_v5_query.delete()
|
||||
|
||||
if 'instance_types_v4' in table_names and \
|
||||
'instance_types_v5' in table_names:
|
||||
instance_types_v4_query = session.query(model.InstanceType)
|
||||
instance_types_v4 = instance_types_v4_query.all()
|
||||
instance_types_v5_query = session.query(model.InstanceType_v5)
|
||||
instance_types_v5 = instance_types_v5_query.all()
|
||||
_migrate_instance_types_v4_to_v5(session, instance_types_v4,
|
||||
instance_types_v5)
|
||||
instance_types_v4_query.delete()
|
||||
hosts_v7_query = session.query(model.Host_v7)
|
||||
hosts_v7 = hosts_v7_query.all()
|
||||
_migrate_hosts_v6_to_v7(session, hosts_v6, hosts_v7)
|
||||
hosts_v6_query.delete()
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
#
|
||||
from nfv_vim.database.model._base import Base # noqa: F401
|
||||
from nfv_vim.database.model._base import lookup_class_by_table # noqa: F401
|
||||
from nfv_vim.database.model._host import Host_v5 # noqa: F401
|
||||
from nfv_vim.database.model._host import Host_v6 # noqa: F401
|
||||
from nfv_vim.database.model._host import Host_v7 # noqa: F401
|
||||
from nfv_vim.database.model._host_aggregate import HostAggregate # noqa: F401
|
||||
from nfv_vim.database.model._host_group import HostGroup # noqa: F401
|
||||
from nfv_vim.database.model._hypervisor import Hypervisor # noqa: F401
|
||||
|
|
|
@ -11,6 +11,31 @@ from nfv_vim.database.model._base import AsDictMixin
|
|||
from nfv_vim.database.model._base import Base
|
||||
|
||||
|
||||
class Host_v7(AsDictMixin, Base):
|
||||
"""
|
||||
Host Database Table Entry
|
||||
Note: Changes are only in nfvi_host_data to add device_image_update string
|
||||
"""
|
||||
__tablename__ = 'hosts_v7'
|
||||
|
||||
uuid = Column(String(64), nullable=False, primary_key=True)
|
||||
name = Column(String(64), nullable=False)
|
||||
personality = Column(String(64), nullable=False)
|
||||
state = Column(String(64), nullable=False)
|
||||
action = Column(String(64), nullable=False)
|
||||
upgrade_inprogress = Column(Boolean, nullable=False)
|
||||
recover_instances = Column(Boolean, nullable=False)
|
||||
uptime = Column(String(64), nullable=False)
|
||||
elapsed_time_in_state = Column(String(64), nullable=False)
|
||||
host_services_locked = Column(Boolean, nullable=False)
|
||||
nfvi_host_data = Column(String(2048), nullable=False)
|
||||
|
||||
def __repr__(self):
|
||||
return "<Host(%r, %r, %r, %r, %r %r)>" % (self.uuid, self.name,
|
||||
self.personality, self.state,
|
||||
self.action, self.uptime)
|
||||
|
||||
|
||||
class Host_v6(AsDictMixin, Base):
|
||||
"""
|
||||
Host Database Table Entry
|
||||
|
@ -34,28 +59,3 @@ class Host_v6(AsDictMixin, Base):
|
|||
return "<Host(%r, %r, %r, %r, %r %r)>" % (self.uuid, self.name,
|
||||
self.personality, self.state,
|
||||
self.action, self.uptime)
|
||||
|
||||
|
||||
class Host_v5(AsDictMixin, Base):
|
||||
"""
|
||||
Host Database Table Entry
|
||||
Note: There were changes in both the attributes and the nfvi_host_data.
|
||||
"""
|
||||
__tablename__ = 'hosts_v5'
|
||||
|
||||
uuid = Column(String(64), nullable=False, primary_key=True)
|
||||
name = Column(String(64), nullable=False)
|
||||
personality = Column(String(64), nullable=False)
|
||||
state = Column(String(64), nullable=False)
|
||||
action = Column(String(64), nullable=False)
|
||||
upgrade_inprogress = Column(Boolean, nullable=False)
|
||||
recover_instances = Column(Boolean, nullable=False)
|
||||
uptime = Column(String(64), nullable=False)
|
||||
elapsed_time_in_state = Column(String(64), nullable=False)
|
||||
host_services_locked = Column(Boolean, nullable=False)
|
||||
nfvi_host_data = Column(String(2048), nullable=False)
|
||||
|
||||
def __repr__(self):
|
||||
return "<Host(%r, %r, %r, %r, %r %r)>" % (self.uuid, self.name,
|
||||
self.personality, self.state,
|
||||
self.action, self.uptime)
|
||||
|
|
|
@ -107,6 +107,7 @@ class Host(ObjectData):
|
|||
"""
|
||||
def __init__(self, uuid, name, personality, admin_state, oper_state,
|
||||
avail_status, action, uptime, software_load, target_load,
|
||||
device_image_update=None,
|
||||
openstack_compute=False,
|
||||
openstack_control=False,
|
||||
remote_storage=False,
|
||||
|
@ -120,6 +121,7 @@ class Host(ObjectData):
|
|||
uptime=uptime,
|
||||
software_load=software_load,
|
||||
target_load=target_load,
|
||||
device_image_update=device_image_update,
|
||||
openstack_compute=openstack_compute,
|
||||
openstack_control=openstack_control,
|
||||
remote_storage=remote_storage))
|
||||
|
|
|
@ -16,7 +16,7 @@ from nfv_vim.strategy._strategy_steps import FwUpdateHostsStep # noqa: F401
|
|||
from nfv_vim.strategy._strategy_steps import LockHostsStep # noqa: F401
|
||||
from nfv_vim.strategy._strategy_steps import MigrateInstancesStep # noqa: F401
|
||||
from nfv_vim.strategy._strategy_steps import QueryAlarmsStep # noqa: F401
|
||||
from nfv_vim.strategy._strategy_steps import QueryHostDeviceListStep # noqa: F401
|
||||
from nfv_vim.strategy._strategy_steps import QueryFwUpdateHostStep # noqa: F401
|
||||
from nfv_vim.strategy._strategy_steps import QuerySwPatchesStep # noqa: F401
|
||||
from nfv_vim.strategy._strategy_steps import QuerySwPatchHostsStep # noqa: F401
|
||||
from nfv_vim.strategy._strategy_steps import QueryUpgradeStep # noqa: F401
|
||||
|
|
|
@ -1732,7 +1732,7 @@ class FwUpdateStrategy(SwUpdateStrategy):
|
|||
for host in host_table.values():
|
||||
if HOST_PERSONALITY.WORKER in host.personality:
|
||||
if host.is_unlocked() and host.is_enabled():
|
||||
stage.add_step(strategy.QueryHostDeviceListStep(host))
|
||||
stage.add_step(strategy.QueryFwUpdateHostStep(host))
|
||||
|
||||
self.build_phase.add_stage(stage)
|
||||
super(FwUpdateStrategy, self).build()
|
||||
|
|
|
@ -45,8 +45,7 @@ class StrategyStepNames(Constants):
|
|||
WAIT_DATA_SYNC = Constant('wait-data-sync')
|
||||
QUERY_SW_PATCHES = Constant('query-sw-patches')
|
||||
QUERY_SW_PATCH_HOSTS = Constant('query-sw-patch-hosts')
|
||||
QUERY_HOST_DEVICES = Constant('query-host-devices')
|
||||
QUERY_HOST_DEVICE = Constant('query-host-device')
|
||||
QUERY_FW_UPDATE_HOST = Constant('query-fw-update-host')
|
||||
QUERY_UPGRADE = Constant('query-upgrade')
|
||||
DISABLE_HOST_SERVICES = Constant('disable-host-services')
|
||||
ENABLE_HOST_SERVICES = Constant('enable-host-services')
|
||||
|
@ -1751,19 +1750,18 @@ class QuerySwPatchHostsStep(strategy.StrategyStep):
|
|||
return data
|
||||
|
||||
|
||||
class QueryHostDeviceListStep(strategy.StrategyStep):
|
||||
class QueryFwUpdateHostStep(strategy.StrategyStep):
|
||||
"""
|
||||
Query Host Device List
|
||||
Query Host
|
||||
"""
|
||||
|
||||
# This step queries system inventory for each host's device list.
|
||||
# Any hosts whose devices have a firmware update pending have its name
|
||||
# added to _fw_update_hosts to build a list of host names that require
|
||||
# firmware update.
|
||||
# This step queries system inventory for the host in self._host_names
|
||||
# If the host's 'device_image_update' field shows 'pending' then its
|
||||
# hostname is added to the strategy's fw_update_hosts list.
|
||||
|
||||
def __init__(self, host):
|
||||
super(QueryHostDeviceListStep, self).__init__(
|
||||
STRATEGY_STEP_NAME.QUERY_HOST_DEVICES, timeout_in_secs=60)
|
||||
super(QueryFwUpdateHostStep, self).__init__(
|
||||
STRATEGY_STEP_NAME.QUERY_FW_UPDATE_HOST, timeout_in_secs=60)
|
||||
|
||||
self._host_names = list()
|
||||
self._host_uuids = list()
|
||||
|
@ -1771,38 +1769,36 @@ class QueryHostDeviceListStep(strategy.StrategyStep):
|
|||
self._host_uuids.append(host.uuid)
|
||||
|
||||
@coroutine
|
||||
def _get_host_devices_callback(self):
|
||||
def _get_host_callback(self):
|
||||
"""
|
||||
Query Host Device List callback
|
||||
Query Host callback
|
||||
"""
|
||||
from nfv_vim import tables
|
||||
|
||||
response = (yield)
|
||||
|
||||
DLOG.verbose("get-host-devices %s callback response=%s." %
|
||||
DLOG.verbose("Get-Host %s callback response=%s." %
|
||||
(self._host_names[0], response))
|
||||
|
||||
if response['completed']:
|
||||
if self.strategy is not None:
|
||||
pci_devices = response['result-data'].get('pci_devices')
|
||||
if pci_devices:
|
||||
host_added_to_fw_update_hosts_list = False
|
||||
for pci_device in pci_devices:
|
||||
if pci_device.get(FW_UPDATE_LABEL.DEVICE_IMAGE_NEEDS_FIRMWARE_UPDATE) is False:
|
||||
DLOG.verbose("%s:%s device is up-to-date" %
|
||||
(self._host_names[0],
|
||||
pci_device.get('name')))
|
||||
continue
|
||||
|
||||
# using existing vim host inventory for host info
|
||||
host_table = tables.tables_get_host_table()
|
||||
for host in host_table.values():
|
||||
if host.uuid == pci_device['host_uuid']:
|
||||
DLOG.info("%s:%s device requires update" %
|
||||
(host.name, pci_device.get('name')))
|
||||
if host_added_to_fw_update_hosts_list is False:
|
||||
self.strategy.fw_update_hosts.append(host.name)
|
||||
host_added_to_fw_update_hosts_list = True
|
||||
hostname = response['result-data'].get('name')
|
||||
if hostname:
|
||||
device_image_update = response['result-data'].get('device_image_update')
|
||||
# device_image_update = 'pending'
|
||||
if device_image_update is None:
|
||||
DLOG.verbose("%s no firmware update required" % hostname)
|
||||
elif device_image_update == FW_UPDATE_LABEL.DEVICE_IMAGE_UPDATE_PENDING:
|
||||
self.strategy.fw_update_hosts.append(hostname)
|
||||
# DLOG.verbose("%s requires firmware update" % hostname)
|
||||
DLOG.info("%s requires firmware update" % hostname)
|
||||
elif device_image_update == FW_UPDATE_LABEL.DEVICE_IMAGE_UPDATE_IN_PROGRESS:
|
||||
DLOG.info("%s firmware update in-progress" % hostname)
|
||||
elif device_image_update == FW_UPDATE_LABEL.DEVICE_IMAGE_UPDATE_COMPLETED:
|
||||
DLOG.info("%s firmware update complete" % hostname)
|
||||
elif device_image_update == FW_UPDATE_LABEL.DEVICE_IMAGE_UPDATE_FAILED:
|
||||
DLOG.info("%s firmware update failed" % hostname)
|
||||
else:
|
||||
DLOG.error("%s firmware update ; unknown state '%s'" % (hostname, device_image_update))
|
||||
|
||||
result = strategy.STRATEGY_STEP_RESULT.SUCCESS
|
||||
self.stage.step_complete(result, "")
|
||||
|
@ -1812,23 +1808,23 @@ class QueryHostDeviceListStep(strategy.StrategyStep):
|
|||
|
||||
def apply(self):
|
||||
"""
|
||||
Query Host Device List Apply
|
||||
Query Host Apply
|
||||
"""
|
||||
from nfv_vim import nfvi
|
||||
|
||||
DLOG.info("%s %s step apply" % (self._host_names[0], self._name))
|
||||
|
||||
# This step is only ever called with one host name.
|
||||
nfvi.nfvi_get_host_devices(self._host_uuids[0],
|
||||
self._host_names[0],
|
||||
self._get_host_devices_callback())
|
||||
nfvi.nfvi_get_host(self._host_uuids[0],
|
||||
self._host_names[0],
|
||||
self._get_host_callback())
|
||||
return strategy.STRATEGY_STEP_RESULT.WAIT, ""
|
||||
|
||||
def from_dict(self, data):
|
||||
"""
|
||||
Load the firmware update host device list step
|
||||
"""
|
||||
super(QueryHostDeviceListStep, self).from_dict(data)
|
||||
super(QueryFwUpdateHostStep, self).from_dict(data)
|
||||
self._host_names = data['entity_names']
|
||||
self._host_uuids = data['entity_uuids']
|
||||
return self
|
||||
|
@ -1837,7 +1833,7 @@ class QueryHostDeviceListStep(strategy.StrategyStep):
|
|||
"""
|
||||
Represent the object as a dictionary for the strategy
|
||||
"""
|
||||
data = super(QueryHostDeviceListStep, self).as_dict()
|
||||
data = super(QueryFwUpdateHostStep, self).as_dict()
|
||||
data['entity_type'] = ''
|
||||
data['entity_names'] = self._host_names
|
||||
data['entity_uuids'] = self._host_uuids
|
||||
|
@ -1853,66 +1849,95 @@ class FwUpdateHostsStep(strategy.StrategyStep):
|
|||
super(FwUpdateHostsStep, self).__init__(
|
||||
STRATEGY_STEP_NAME.FW_UPDATE_HOSTS, timeout_in_secs=3600)
|
||||
|
||||
# Constants
|
||||
self.MONITOR_THRESHOLD = 0
|
||||
|
||||
self._hosts = hosts
|
||||
self._host_names = list()
|
||||
self._host_uuids = list()
|
||||
self._monitoring_fw_update = False
|
||||
self._wait_time = 0
|
||||
self._host_failed_device_update = dict()
|
||||
self._host_monitor_counter = dict()
|
||||
self._host_completed = dict()
|
||||
for host in hosts:
|
||||
self._host_names.append(host.name)
|
||||
self._host_uuids.append(host.uuid)
|
||||
self._host_completed[host.name] = (False, False, '')
|
||||
self._host_monitor_counter[host.uuid] = 0
|
||||
self._host_failed_device_update[host.name] = list()
|
||||
|
||||
@coroutine
|
||||
def _host_devices_list_callback(self):
|
||||
def _get_host_callback(self):
|
||||
"""
|
||||
Query Host Device List callback used for monitoring update process
|
||||
Query Host callback used for monitoring update process
|
||||
"""
|
||||
response = (yield)
|
||||
DLOG.debug("Host-Device-List callback response=%s." % response)
|
||||
DLOG.debug("Get-Host callback response=%s." % response)
|
||||
try:
|
||||
if response['completed']:
|
||||
if self.strategy is not None:
|
||||
# find the host for this callback response
|
||||
host_uuid = response['result-data']['pci_devices'][0].get('host_uuid')
|
||||
if host_uuid:
|
||||
if len(self._hosts):
|
||||
for host in self._hosts:
|
||||
if host.uuid == host_uuid:
|
||||
# found it
|
||||
self._host_monitor_counter[host.uuid] += 1
|
||||
pci_devices = response['result-data'].get('pci_devices')
|
||||
if len(pci_devices):
|
||||
self._check_status(host.name,
|
||||
host.uuid,
|
||||
pci_devices)
|
||||
return
|
||||
else:
|
||||
DLOG.info("failed to find any pci devices")
|
||||
hostname = response['result-data'].get('name')
|
||||
if hostname:
|
||||
device_image_update = response['result-data'].get('device_image_update')
|
||||
if device_image_update is None:
|
||||
DLOG.verbose("%s no firmware update required" % hostname)
|
||||
elif device_image_update == FW_UPDATE_LABEL.DEVICE_IMAGE_UPDATE_PENDING:
|
||||
self.strategy.fw_update_hosts.append(hostname)
|
||||
DLOG.info("%s requires firmware update" % hostname)
|
||||
elif device_image_update == FW_UPDATE_LABEL.DEVICE_IMAGE_UPDATE_IN_PROGRESS:
|
||||
DLOG.info("%s firmware update in-progress" % hostname)
|
||||
elif device_image_update == FW_UPDATE_LABEL.DEVICE_IMAGE_UPDATE_COMPLETED:
|
||||
if self._host_completed[hostname][0] is False:
|
||||
self._host_completed[hostname] = (True, True, '')
|
||||
DLOG.info("%s firmware update complete" % hostname)
|
||||
elif device_image_update == FW_UPDATE_LABEL.DEVICE_IMAGE_UPDATE_FAILED:
|
||||
if self._host_completed[hostname][0] is False:
|
||||
failed_msg = hostname + ' firmware update failed'
|
||||
self._host_completed[hostname] = (True, False, failed_msg)
|
||||
DLOG.error(failed_msg)
|
||||
else:
|
||||
DLOG.error("failed to find %s in hosts list" % host_uuid)
|
||||
if self._host_completed[hostname][0] is False:
|
||||
failed_msg = hostname + ' firmware update failed ; unknown state ' + device_image_update
|
||||
self._host_completed[hostname] = (True, False, failed_msg)
|
||||
DLOG.error(failed_msg)
|
||||
|
||||
# Check for firmware upgrade step complete
|
||||
self._check_step_complete()
|
||||
return
|
||||
else:
|
||||
DLOG.error("failed to get hostname in host device list response")
|
||||
DLOG.error("failed to get hostname or data from get host response")
|
||||
else:
|
||||
DLOG.error("failed to get host-device-list ; no strategy")
|
||||
DLOG.error("failed to monitor firmware update ; no strategy")
|
||||
else:
|
||||
DLOG.error("get host device list request did not complete")
|
||||
DLOG.error("get host request did not complete")
|
||||
except Exception as e:
|
||||
DLOG.exception("Caught exception interpreting host device list")
|
||||
DLOG.exception("Caught exception interpreting host info")
|
||||
DLOG.error("Response: %s" % response)
|
||||
|
||||
result = strategy.STRATEGY_STEP_RESULT.FAILED
|
||||
fail_msg = "failed to get or parse fw update info"
|
||||
self.stage.step_complete(result, fail_msg)
|
||||
|
||||
def _check_step_complete(self):
|
||||
"""
|
||||
Check for firmware upgrade step complete
|
||||
"""
|
||||
|
||||
failed_hosts = ""
|
||||
done = True
|
||||
for hostname in self._host_names:
|
||||
if self._host_completed[hostname][0] is False:
|
||||
done = False
|
||||
elif self._host_completed[hostname][1] is False:
|
||||
failed_hosts += hostname + ' '
|
||||
else:
|
||||
DLOG.verbose("%s firmware update is complete" % hostname)
|
||||
|
||||
if done:
|
||||
if len(failed_hosts) == 0:
|
||||
result = strategy.STRATEGY_STEP_RESULT.SUCCESS
|
||||
self.stage.step_complete(result, '')
|
||||
else:
|
||||
result = strategy.STRATEGY_STEP_RESULT.FAILED
|
||||
failed_msg = 'Firmware update failed ; %s' % failed_hosts
|
||||
self.stage.step_complete(result, failed_msg)
|
||||
|
||||
def apply(self):
|
||||
"""
|
||||
Firmware Update Hosts Apply
|
||||
|
@ -1971,94 +1996,15 @@ class FwUpdateHostsStep(strategy.StrategyStep):
|
|||
DLOG.info("%s update already done")
|
||||
continue
|
||||
|
||||
DLOG.info("%s firmware update monitor request %d" %
|
||||
(host.name, self._host_monitor_counter[host.uuid] + 1))
|
||||
nfvi.nfvi_get_host_devices(host.uuid,
|
||||
host.name,
|
||||
self._host_devices_list_callback())
|
||||
nfvi.nfvi_get_host(host.uuid,
|
||||
host.name,
|
||||
self._get_host_callback())
|
||||
return True
|
||||
else:
|
||||
DLOG.warn("Unexpected event (%s)" % event)
|
||||
|
||||
return False
|
||||
|
||||
def _check_status(self, host_name, host_uuid, pci_devices):
|
||||
"""Check firmware update status for specified host"""
|
||||
|
||||
done = True
|
||||
for pci_device in pci_devices:
|
||||
if pci_device.get(FW_UPDATE_LABEL.DEVICE_IMAGE_NEEDS_FIRMWARE_UPDATE) is False:
|
||||
continue
|
||||
|
||||
status = pci_device.get('status')
|
||||
pci_device_name = pci_device.get('name')
|
||||
|
||||
# Handle simulated testing ; Remove after integration testing
|
||||
if self.MONITOR_THRESHOLD > 0 or status is None:
|
||||
if self._host_monitor_counter[host_uuid] >= self.MONITOR_THRESHOLD:
|
||||
status = FW_UPDATE_LABEL.DEVICE_IMAGE_UPDATE_COMPLETED
|
||||
else:
|
||||
status = FW_UPDATE_LABEL.DEVICE_IMAGE_UPDATE_IN_PROGRESS
|
||||
|
||||
# stop monitoring failed devices
|
||||
if pci_device_name in self._host_failed_device_update[host_name]:
|
||||
continue
|
||||
|
||||
elif status == FW_UPDATE_LABEL.DEVICE_IMAGE_UPDATE_IN_PROGRESS:
|
||||
done = False
|
||||
DLOG.verbose("%s pci device %s firmware update in-progress" %
|
||||
(host_name, pci_device_name))
|
||||
|
||||
elif status == FW_UPDATE_LABEL.DEVICE_IMAGE_UPDATE_COMPLETED:
|
||||
DLOG.verbose("%s %s firmware update complete" %
|
||||
(host_name, pci_device_name))
|
||||
|
||||
elif status == FW_UPDATE_LABEL.DEVICE_IMAGE_UPDATE_FAILED:
|
||||
if pci_device_name not in self._host_failed_device_update[host_name]:
|
||||
DLOG.info("%s %s firmware update failed" %
|
||||
(host_name, pci_device_name))
|
||||
self._host_failed_device_update[host_name].append(pci_device_name)
|
||||
|
||||
else:
|
||||
if pci_device_name not in self._host_failed_device_update[host_name]:
|
||||
self._host_failed_device_update[host_name].append(pci_device_name)
|
||||
DLOG.info('unexpected device image status (%s)' % status)
|
||||
|
||||
if done:
|
||||
if len(self._host_failed_device_update[host_name]):
|
||||
failed_msg = "firmware update failed for devices: "
|
||||
failed_msg += str(self._host_failed_device_update[host_name])
|
||||
self._host_completed[host_name] = (True, False, failed_msg)
|
||||
else:
|
||||
self._host_completed[host_name] = (True, True, '')
|
||||
|
||||
# Check for firmware upgrade step complete
|
||||
self._check_step_complete()
|
||||
|
||||
def _check_step_complete(self):
|
||||
"""
|
||||
Check for firmware upgrade step complete
|
||||
"""
|
||||
|
||||
failed_hosts = ""
|
||||
done = True
|
||||
for hostname in self._host_names:
|
||||
if self._host_completed[hostname][0] is False:
|
||||
done = False
|
||||
elif self._host_completed[hostname][1] is False:
|
||||
failed_hosts += hostname + ' '
|
||||
else:
|
||||
DLOG.info("%s firmware update is complete" % hostname)
|
||||
|
||||
if done:
|
||||
if len(failed_hosts) == 0:
|
||||
result = strategy.STRATEGY_STEP_RESULT.SUCCESS
|
||||
self.stage.step_complete(result, '')
|
||||
else:
|
||||
result = strategy.STRATEGY_STEP_RESULT.FAILED
|
||||
failed_msg = 'Firmware update failed ; %s' % failed_hosts
|
||||
self.stage.step_complete(result, failed_msg)
|
||||
|
||||
def abort(self):
|
||||
"""
|
||||
Returns the abort step related to this step
|
||||
|
@ -2538,8 +2484,8 @@ def strategy_step_rebuild_from_dict(data):
|
|||
elif STRATEGY_STEP_NAME.FW_UPDATE_ABORT_HOSTS == data['name']:
|
||||
step_obj = object.__new__(FwUpdateAbortHostsStep)
|
||||
|
||||
elif STRATEGY_STEP_NAME.QUERY_HOST_DEVICES == data['name']:
|
||||
step_obj = object.__new__(QueryHostDeviceListStep)
|
||||
elif STRATEGY_STEP_NAME.QUERY_FW_UPDATE_HOST == data['name']:
|
||||
step_obj = object.__new__(QueryFwUpdateHostStep)
|
||||
|
||||
else:
|
||||
step_obj = object.__new__(strategy.StrategyStep)
|
||||
|
|
|
@ -133,7 +133,7 @@ deps = {[nfv]deps}
|
|||
stestr
|
||||
testtools
|
||||
setenv = PYTHONDONTWRITEBYTECODE=True
|
||||
commands = cp -v {[nfv]nfv_base_dir}/nfv-tests/nfv_unit_tests/test_data/nfv_vim_db_18.03_GA {envdir}/
|
||||
commands = cp -v {[nfv]nfv_base_dir}/nfv-tests/nfv_unit_tests/test_data/nfv_vim_db_stx_19.12 {envdir}/
|
||||
stestr --test-path={[nfv]nfv_base_dir}/nfv-tests/nfv_unit_tests/tests run '{posargs}'
|
||||
stestr slowest
|
||||
|
||||
|
@ -146,7 +146,7 @@ deps = {[nfv]deps}
|
|||
stestr
|
||||
testtools
|
||||
setenv = PYTHONDONTWRITEBYTECODE=True
|
||||
commands = cp -v {[nfv]nfv_base_dir}/nfv-tests/nfv_unit_tests/test_data/nfv_vim_db_18.03_GA {envdir}/
|
||||
commands = cp -v {[nfv]nfv_base_dir}/nfv-tests/nfv_unit_tests/test_data/nfv_vim_db_stx_19.12 {envdir}/
|
||||
stestr --test-path={[nfv]nfv_base_dir}/nfv-tests/nfv_unit_tests/tests run '{posargs}'
|
||||
stestr slowest
|
||||
|
||||
|
@ -161,7 +161,7 @@ deps = {[nfv]deps}
|
|||
setenv =
|
||||
PYTHON=coverage run --parallel-mode
|
||||
PYTHONDONTWRITEBYTECODE=True
|
||||
commands = cp -v {[nfv]nfv_base_dir}/nfv-tests/nfv_unit_tests/test_data/nfv_vim_db_18.03_GA {envdir}/
|
||||
commands = cp -v {[nfv]nfv_base_dir}/nfv-tests/nfv_unit_tests/test_data/nfv_vim_db_stx_19.12 {envdir}/
|
||||
coverage erase
|
||||
stestr --test-path={[nfv]nfv_base_dir}/nfv-tests/nfv_unit_tests/tests run '{posargs}'
|
||||
coverage combine
|
||||
|
|
Loading…
Reference in New Issue