diff --git a/controllerconfig/controllerconfig/controllerconfig/common/constants.py b/controllerconfig/controllerconfig/controllerconfig/common/constants.py index 97486b7d7e..e2864933aa 100644 --- a/controllerconfig/controllerconfig/controllerconfig/common/constants.py +++ b/controllerconfig/controllerconfig/controllerconfig/common/constants.py @@ -56,7 +56,7 @@ DEFAULT_VIRTUAL_BACKUP_STOR_SIZE = \ DEFAULT_EXTENSION_STOR_SIZE = \ sysinv_constants.DEFAULT_EXTENSION_STOR_SIZE -SYSTEM_CONFIG_TIMEOUT = 300 +SYSTEM_CONFIG_TIMEOUT = 420 SERVICE_ENABLE_TIMEOUT = 180 MINIMUM_ROOT_DISK_SIZE = 500 MAXIMUM_CGCS_LV_SIZE = 500 diff --git a/sysinv/cgts-client/centos/build_srpm.data b/sysinv/cgts-client/centos/build_srpm.data index bf1f9fbd69..6c18c584d7 100644 --- a/sysinv/cgts-client/centos/build_srpm.data +++ b/sysinv/cgts-client/centos/build_srpm.data @@ -1,2 +1,2 @@ SRC_DIR="cgts-client" -TIS_PATCH_VER=68 +TIS_PATCH_VER=69 diff --git a/sysinv/cgts-client/cgts-client/cgtsclient/v1/iHost_shell.py b/sysinv/cgts-client/cgts-client/cgtsclient/v1/iHost_shell.py index 47f7400764..eb14e18165 100755 --- a/sysinv/cgts-client/cgts-client/cgtsclient/v1/iHost_shell.py +++ b/sysinv/cgts-client/cgts-client/cgtsclient/v1/iHost_shell.py @@ -35,7 +35,7 @@ def _print_ihost_show(ihost): 'location', 'uptime', 'reserved', 'created_at', 'updated_at', 'boot_device', 'rootfs_device', 'install_output', 'console', 'tboot', 'vim_progress_status', 'software_load', 'install_state', - 'install_state_info'] + 'install_state_info', 'inv_state'] optional_fields = ['vsc_controllers', 'ttys_dcd'] if ihost.subfunctions != ihost.personality: fields.append('subfunctions') diff --git a/sysinv/sysinv/centos/build_srpm.data b/sysinv/sysinv/centos/build_srpm.data index 3dd3dcdb5e..a3599bb3e7 100644 --- a/sysinv/sysinv/centos/build_srpm.data +++ b/sysinv/sysinv/centos/build_srpm.data @@ -1,2 +1,2 @@ SRC_DIR="sysinv" -TIS_PATCH_VER=329 +TIS_PATCH_VER=330 diff --git a/sysinv/sysinv/sysinv/sysinv/agent/manager.py b/sysinv/sysinv/sysinv/sysinv/agent/manager.py index 11409f1a39..3104595b89 100644 --- a/sysinv/sysinv/sysinv/sysinv/agent/manager.py +++ b/sysinv/sysinv/sysinv/sysinv/agent/manager.py @@ -130,11 +130,34 @@ class AgentManager(service.PeriodicService): RPC_API_VERSION = '1.0' + NUMA = 'numa' + CPU = 'cpu' + PORT = 'port' + PCI_DEVICE = 'pci_device' + MEMORY = 'memory' + DISK = 'disk' + PV = 'pv' + LVG = 'lvg' + HOST_FILESYSTEMS = 'host_filesystems' + + # Note that this set must be extended when there are + # additional inventory required for the initial + # inventory complete (to be notified to conductor). + INVENTORY_REPORTS_REQUIRED = { + NUMA, + PORT, + PCI_DEVICE, + CPU, + MEMORY, + DISK, + PV, + LVG, + HOST_FILESYSTEMS} + def __init__(self, host, topic): serializer = objects_base.SysinvObjectSerializer() super(AgentManager, self).__init__(host, topic, serializer=serializer) - self._report_to_conductor = False self._report_to_conductor_iplatform_avail_flag = False self._ipci_operator = pci.PCIOperator() self._inode_operator = node.NodeOperator() @@ -161,6 +184,8 @@ class AgentManager(service.PeriodicService): self._tpmconfig_rpc_failure = False self._tpmconfig_host_first_apply = False self._first_grub_update = False + self._inventoried_initial = False + self._inventory_reported = set() def start(self): super(AgentManager, self).start() @@ -176,6 +201,22 @@ class AgentManager(service.PeriodicService): if tsc.system_mode == constants.SYSTEM_MODE_SIMPLEX: utils.touch(SYSINV_READY_FLAG) + def _report_to_conductor(self): + """ Initial inventory report to conductor required + + returns: True if initial inventory report_to_conductor is required + """ + + initial_reports_required = \ + self.INVENTORY_REPORTS_REQUIRED - self._inventory_reported + initial_reports_required.discard(self.HOST_FILESYSTEMS) + if initial_reports_required: + LOG.info("_report_to_conductor initial_reports_required=%s" % + initial_reports_required) + return True + else: + return False + def _report_to_conductor_iplatform_avail(self): # First report sent to conductor since boot utils.touch(SYSINV_FIRST_REPORT_FLAG) @@ -679,18 +720,16 @@ class AgentManager(service.PeriodicService): rpcapi.iport_update_by_ihost(context, host_uuid, port_list) + self._inventory_reported.add(self.PORT) except RemoteError as e: LOG.error("iport_update_by_ihost RemoteError exc_type=%s" % e.exc_type) - self._report_to_conductor = False - except exception.SysinvException: - LOG.exception("Sysinv Agent exception updating port.") - pass try: rpcapi.pci_device_update_by_host(context, host_uuid, pci_device_list) + self._inventory_reported.add(self.PCI_DEVICE) except exception.SysinvException: LOG.exception("Sysinv Agent exception updating pci_device.") pass @@ -743,7 +782,6 @@ class AgentManager(service.PeriodicService): ipersonality = ihost.get('personality') or "" if ihost and ipersonality: - self._report_to_conductor = True self._ihost_uuid = ihost['uuid'] self._ihost_personality = ihost['personality'] self._mgmt_ip = ihost['mgmt_ip'] @@ -773,7 +811,7 @@ class AgentManager(service.PeriodicService): time.sleep(30) slept += 30 - if not self._report_to_conductor: + if not self._report_to_conductor(): # let the audit take care of it instead LOG.info("Sysinv no matching ihost found... await Audit") return @@ -807,18 +845,10 @@ class AgentManager(service.PeriodicService): rpcapi.inumas_update_by_ihost(icontext, ihost['uuid'], inumas) + self._inventory_reported.add(self.NUMA) except RemoteError as e: LOG.error("inumas_update_by_ihost RemoteError exc_type=%s" % e.exc_type) - if e.exc_type == 'TimeoutError': - self._report_to_conductor = False - except Exception as e: - LOG.exception("Sysinv Agent exception updating inuma e=%s." % e) - self._report_to_conductor = True - pass - except exception.SysinvException: - LOG.exception("Sysinv Agent uncaught exception updating inuma.") - pass force_grub_update = self._force_grub_update() try: @@ -827,18 +857,10 @@ class AgentManager(service.PeriodicService): ihost['uuid'], icpus, force_grub_update) + self._inventory_reported.add(self.CPU) except RemoteError as e: LOG.error("icpus_update_by_ihost RemoteError exc_type=%s" % e.exc_type) - if e.exc_type == 'TimeoutError': - self._report_to_conductor = False - except Exception as e: - LOG.exception("Sysinv Agent exception updating icpus e=%s." % e) - self._report_to_conductor = True - pass - except exception.SysinvException: - LOG.exception("Sysinv Agent uncaught exception updating icpus conductor.") - pass imemory = self._inode_operator.inodes_get_imemory() if imemory: @@ -847,6 +869,7 @@ class AgentManager(service.PeriodicService): rpcapi.imemory_update_by_ihost(icontext, ihost['uuid'], imemory) + self._inventory_reported.add(self.MEMORY) except RemoteError as e: LOG.error("imemory_update_by_ihost RemoteError exc_type=%s" % e.exc_type) @@ -862,6 +885,7 @@ class AgentManager(service.PeriodicService): rpcapi.idisk_update_by_ihost(icontext, ihost['uuid'], idisk) + self._inventory_reported.add(self.DISK) except RemoteError as e: # TODO (oponcea): Valid for R4->R5, remove in R6. # safe to ignore during upgrades @@ -882,6 +906,7 @@ class AgentManager(service.PeriodicService): rpcapi.ipv_update_by_ihost(icontext, ihost['uuid'], ipv) + self._inventory_reported.add(self.PV) except exception.SysinvException: LOG.exception("Sysinv Agent exception updating ipv conductor.") pass @@ -891,6 +916,7 @@ class AgentManager(service.PeriodicService): rpcapi.ilvg_update_by_ihost(icontext, ihost['uuid'], ilvg) + self._inventory_reported.add(self.LVG) except exception.SysinvException: LOG.exception("Sysinv Agent exception updating ilvg conductor.") pass @@ -959,6 +985,36 @@ class AgentManager(service.PeriodicService): self._subfunctions_configured = True return True + def notify_initial_inventory_completed(self, context): + """Report the inventory completion event for this host to the + conductor when the conditions for inventory complete have + been met. + + :param context: an admin context + """ + def _conditions_for_inventory_complete_met(): + # NOTE: condition(s) for inventory complete must be + # reviewed for update when additional inventory is posted. + reports_required = \ + self.INVENTORY_REPORTS_REQUIRED - self._inventory_reported + if not reports_required: + return True + else: + LOG.info("_conditions_for_inventory_complete_met requires %s" % + reports_required) + return False + + if (_conditions_for_inventory_complete_met() and not + self._inventoried_initial): + LOG.info("Initial inventory completed host %s" % + self._ihost_uuid) + rpcapi = conductor_rpcapi.ConductorAPI( + topic=conductor_rpcapi.MANAGER_TOPIC) + + rpcapi.initial_inventory_completed(context, + self._ihost_uuid) + self._inventoried_initial = True + def _report_config_applied(self, context): """Report the latest configuration applied for this host to the conductor. @@ -1081,7 +1137,7 @@ class AgentManager(service.PeriodicService): if os.path.isfile(tsc.INITIAL_CONFIG_COMPLETE_FLAG): self._report_config_applied(icontext) - if self._report_to_conductor is False: + if self._report_to_conductor(): LOG.info("Sysinv Agent audit running inv_get_and_report.") self.ihost_inv_get_and_report(icontext) @@ -1110,6 +1166,7 @@ class AgentManager(service.PeriodicService): rpcapi.idisk_update_by_ihost(icontext, self._ihost_uuid, idisk) + self._inventory_reported.add(self.DISK) except RemoteError as e: # TODO (oponcea): Valid for R4->R5, remove in R6. # safe to ignore during upgrades @@ -1168,6 +1225,7 @@ class AgentManager(service.PeriodicService): rpcapi.imemory_update_by_ihost(icontext, self._ihost_uuid, imemory) + self._inventory_reported.add(self.MEMORY) if self._agent_throttle > 5: # throttle updates self._agent_throttle = 0 @@ -1207,6 +1265,7 @@ class AgentManager(service.PeriodicService): rpcapi.idisk_update_by_ihost(icontext, self._ihost_uuid, idisk) + self._inventory_reported.add(self.DISK) except RemoteError as e: # TODO (oponcea): Valid for R4->R5, remove in R6. # safe to ignore during upgrades @@ -1234,6 +1293,7 @@ class AgentManager(service.PeriodicService): rpcapi.ipv_update_by_ihost(icontext, self._ihost_uuid, ipv) + self._inventory_reported.add(self.PV) except exception.SysinvException: LOG.exception("Sysinv Agent exception updating ipv" "conductor.") @@ -1249,6 +1309,7 @@ class AgentManager(service.PeriodicService): rpcapi.ilvg_update_by_ihost(icontext, self._ihost_uuid, ilvg) + self._inventory_reported.add(self.LVG) except exception.SysinvException: LOG.exception("Sysinv Agent exception updating ilvg" "conductor.") @@ -1319,12 +1380,18 @@ class AgentManager(service.PeriodicService): filesystems) self._prev_fs = filesystems + self._inventory_reported.add(self.HOST_FILESYSTEMS) except Exception as e: LOG.exception( "Sysinv Agent exception creating the host filesystems." " %s" % e) self._prev_fs = None + # Notify conductor of inventory completion after necessary + # inventory reports have been sent to conductor. + # This is as defined by _conditions_for_inventory_complete_met(). + self.notify_initial_inventory_completed(icontext) + self._report_config_applied(icontext) if os.path.isfile(tsc.PLATFORM_CONF_FILE): @@ -1931,3 +1998,4 @@ class AgentManager(service.PeriodicService): self._ihost_uuid, memory, force_update=True) + self._inventory_reported.add(self.MEMORY) diff --git a/sysinv/sysinv/sysinv/sysinv/api/controllers/v1/host.py b/sysinv/sysinv/sysinv/sysinv/api/controllers/v1/host.py index 118011af39..423c83e13e 100644 --- a/sysinv/sysinv/sysinv/sysinv/api/controllers/v1/host.py +++ b/sysinv/sysinv/sysinv/sysinv/api/controllers/v1/host.py @@ -399,6 +399,9 @@ class Host(base.APIBase): ihost_action = wtypes.text 'Represent the current action task in progress' + inv_state = wtypes.text + 'Represent the inventory state' + vim_progress_status = wtypes.text 'Represent the vim progress status' @@ -559,7 +562,8 @@ class Host(base.APIBase): 'tboot', 'vsc_controllers', 'ttys_dcd', 'software_load', 'target_load', 'peers', 'peer_id', 'install_state', 'install_state_info', - 'iscsi_initiator_name'] + 'iscsi_initiator_name', + 'inv_state'] fields = minimum_fields if not expand else None uhost = Host.from_rpc_object(rpc_ihost, fields) @@ -2906,6 +2910,7 @@ class HostController(rest.RestController): 'invprovision', 'recordtype', 'ihost_action', 'action_state', + 'inv_state', 'iconfig_applied', 'iconfig_target'] @@ -4898,6 +4903,17 @@ class HostController(rest.RestController): LOG.warn("Allowing force-unlock of host %s " "undergoing reinstall." % hostupdate.displayid) + if not force_unlock: + # Ensure inventory has completed prior to allowing unlock + host = pecan.request.dbapi.ihost_get( + hostupdate.ihost_orig['uuid']) + if host.inv_state != constants.INV_STATE_INITIAL_INVENTORIED: + raise wsme.exc.ClientSideError( + _("Can not unlock host %s that has not yet been " + "inventoried. Please wait for host to complete " + "initial inventory prior to unlock." + % hostupdate.displayid)) + personality = hostupdate.ihost_patch.get('personality') if personality == constants.CONTROLLER: self.check_unlock_controller(hostupdate, force_unlock) diff --git a/sysinv/sysinv/sysinv/sysinv/common/constants.py b/sysinv/sysinv/sysinv/sysinv/common/constants.py index 6b3413e4a7..6735ebf054 100644 --- a/sysinv/sysinv/sysinv/sysinv/common/constants.py +++ b/sysinv/sysinv/sysinv/sysinv/common/constants.py @@ -192,6 +192,8 @@ HOST_ACTION_STATE = "action_state" HAS_REINSTALLING = "reinstalling" HAS_REINSTALLED = "reinstalled" +INV_STATE_INITIAL_INVENTORIED = "inventoried" + # Board Management Region Info REGION_PRIMARY = "Internal" REGION_SECONDARY = "External" diff --git a/sysinv/sysinv/sysinv/sysinv/common/utils.py b/sysinv/sysinv/sysinv/sysinv/common/utils.py index b2a963d87c..78b938ca1f 100644 --- a/sysinv/sysinv/sysinv/sysinv/common/utils.py +++ b/sysinv/sysinv/sysinv/sysinv/common/utils.py @@ -2024,15 +2024,11 @@ def is_default_huge_pages_required(host): def is_inventory_config_complete(dbapi, forihostid): """Check if the initial inventory has completed - - Due to lack of host state that signifies the completion of inventory, this - function retrieves the list of persistent volumes from the database. If - the count is not zero; ports, disks and PVs have been inventoried. """ try: - pvs = dbapi.ipv_get_by_ihost(forihostid) - return len(pvs) > 0 + host = dbapi.ihost_get(forihostid) + return host.inv_state == constants.INV_STATE_INITIAL_INVENTORIED except Exception: return False diff --git a/sysinv/sysinv/sysinv/sysinv/conductor/manager.py b/sysinv/sysinv/sysinv/sysinv/conductor/manager.py index 3fbbc802d2..64f864af7f 100644 --- a/sysinv/sysinv/sysinv/sysinv/conductor/manager.py +++ b/sysinv/sysinv/sysinv/sysinv/conductor/manager.py @@ -4366,6 +4366,16 @@ class ConductorManager(service.PeriodicService): config_uuid = imsg_dict['config_applied'] self._update_host_config_applied(context, ihost, config_uuid) + def initial_inventory_completed(self, context, host_uuid): + host_uuid.strip() + try: + self.dbapi.ihost_update( + host_uuid, + {'inv_state': constants.INV_STATE_INITIAL_INVENTORIED}) + except exception.ServerNotFound: + LOG.error("initial_inventory_completed invalid host_uuid %s" % + host_uuid) + def subfunctions_update_by_ihost(self, context, ihost_uuid, subfunctions): """Update subfunctions for a host. diff --git a/sysinv/sysinv/sysinv/sysinv/conductor/rpcapi.py b/sysinv/sysinv/sysinv/sysinv/conductor/rpcapi.py index 9c54eba7f0..f404502ec1 100644 --- a/sysinv/sysinv/sysinv/sysinv/conductor/rpcapi.py +++ b/sysinv/sysinv/sysinv/sysinv/conductor/rpcapi.py @@ -1029,6 +1029,18 @@ class ConductorAPI(sysinv.openstack.common.rpc.proxy.RpcProxy): ihost_uuid=ihost_uuid, imsg_dict=imsg_dict)) + def initial_inventory_completed(self, context, host_uuid): + """Notify of initial inventory completion for a host. + + :param context: an admin context + :param host_uuid: host unique id + """ + + return self.call(context, + self.make_msg('initial_inventory_completed', + host_uuid=host_uuid, + )) + def iinterface_get_providernets(self, context, pn_names=None): diff --git a/sysinv/sysinv/sysinv/sysinv/db/sqlalchemy/migrate_repo/versions/090_inv_state.py b/sysinv/sysinv/sysinv/sysinv/db/sqlalchemy/migrate_repo/versions/090_inv_state.py new file mode 100644 index 0000000000..ebcfbc9dbb --- /dev/null +++ b/sysinv/sysinv/sysinv/sysinv/db/sqlalchemy/migrate_repo/versions/090_inv_state.py @@ -0,0 +1,38 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 +# +# Copyright (c) 2019 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# + +from sqlalchemy import Column, MetaData, Table +from sqlalchemy import String, Integer + +ENGINE = 'InnoDB' +CHARSET = 'utf8' + + +def upgrade(migrate_engine): + """ + This database upgrade creates a new host inv_state attribute for + storing the inventory state for a host. + """ + + meta = MetaData() + meta.bind = migrate_engine + + host = Table('i_host', + meta, + Column('id', Integer, primary_key=True, nullable=False), + mysql_engine=ENGINE, mysql_charset=CHARSET, autoload=True) + + # Add the inventory state attribute + host.create_column(Column('inv_state', String(255))) + + +def downgrade(migrate_engine): + meta = MetaData() + meta.bind = migrate_engine + + # Downgrade is unsupported in this release. + raise NotImplementedError('SysInv database downgrade is unsupported.') diff --git a/sysinv/sysinv/sysinv/sysinv/db/sqlalchemy/models.py b/sysinv/sysinv/sysinv/sysinv/db/sqlalchemy/models.py index b39c97116e..c5d319bd4c 100644 --- a/sysinv/sysinv/sysinv/sysinv/db/sqlalchemy/models.py +++ b/sysinv/sysinv/sysinv/sysinv/db/sqlalchemy/models.py @@ -211,6 +211,7 @@ class ihost(Base): action = Column(actionEnum, default="none") ihost_action = Column(String(255)) action_state = Column(String(255)) + inv_state = Column(String(255)) mtce_info = Column(String(255)) install_state = Column(String(255)) install_state_info = Column(String(255)) diff --git a/sysinv/sysinv/sysinv/sysinv/objects/host.py b/sysinv/sysinv/sysinv/sysinv/objects/host.py index 1946532a74..ee9d865178 100644 --- a/sysinv/sysinv/sysinv/sysinv/objects/host.py +++ b/sysinv/sysinv/sysinv/sysinv/objects/host.py @@ -65,6 +65,7 @@ class Host(base.SysinvObject): 'availability': utils.str_or_none, 'ihost_action': utils.str_or_none, 'action_state': utils.str_or_none, + 'inv_state': utils.str_or_none, 'mtce_info': utils.str_or_none, 'vim_progress_status': utils.str_or_none, 'action': utils.str_or_none, diff --git a/sysinv/sysinv/sysinv/sysinv/tests/api/test_host.py b/sysinv/sysinv/sysinv/sysinv/tests/api/test_host.py index 82158b716b..d0663f5bb5 100644 --- a/sysinv/sysinv/sysinv/sysinv/tests/api/test_host.py +++ b/sysinv/sysinv/sysinv/sysinv/tests/api/test_host.py @@ -13,6 +13,7 @@ Tests for the API /ihosts/ methods. import mock import webtest.app +from six.moves import http_client from sysinv.common import constants from sysinv.openstack.common import uuidutils @@ -622,12 +623,14 @@ class TestListHosts(TestHost): class TestPatch(TestHost): - def _patch_host_action(self, hostname, action, user_agent): + def _patch_host_action( + self, hostname, action, user_agent, expect_errors=False): return self.patch_json('/ihosts/%s' % hostname, [{'path': '/action', 'value': action, 'op': 'replace'}], - headers={'User-Agent': user_agent}) + headers={'User-Agent': user_agent}, + expect_errors=expect_errors) def test_update_optimizable(self): # Create controller-0 @@ -645,7 +648,7 @@ class TestPatch(TestHost): 'op': 'replace'}], headers={'User-Agent': 'sysinv-test'}) self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.status_code, 200) + self.assertEqual(response.status_code, http_client.OK) # Verify that the host was updated with the specified location result = self.get_json('/ihosts/%s' % ndict['hostname']) @@ -666,7 +669,7 @@ class TestPatch(TestHost): constants.UNLOCK_ACTION, 'sysinv-test') self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.status_code, 200) + self.assertEqual(response.status_code, http_client.OK) # Verify that the unlock was sent to the VIM self.mock_vim_api_host_action.assert_called_with( @@ -698,7 +701,7 @@ class TestPatch(TestHost): constants.FORCE_UNLOCK_ACTION, 'sysinv-test') self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.status_code, 200) + self.assertEqual(response.status_code, http_client.OK) # Verify that the unlock was sent to the VIM self.mock_vim_api_host_action.assert_called_with( @@ -715,6 +718,26 @@ class TestPatch(TestHost): result = self.get_json('/ihosts/%s' % c0_host['hostname']) self.assertEqual(constants.NONE_ACTION, result['action']) + def test_unlock_action_controller_inventory_not_complete(self): + self._configure_networks() + # Create controller-0 without inv_state initial inventory complete + c0_host = self._create_controller_0( + subfunctions=constants.CONTROLLER, + invprovision=constants.PROVISIONED, + administrative=constants.ADMIN_LOCKED, + operational=constants.OPERATIONAL_ENABLED, + availability=constants.AVAILABILITY_ONLINE, + inv_state=None) + + # Unlock host + response = self._patch_host_action(c0_host['hostname'], + constants.UNLOCK_ACTION, + 'sysinv-test', + expect_errors=True) + self.assertEqual(response.content_type, 'application/json') + self.assertEqual(http_client.BAD_REQUEST, response.status_int) + self.assertTrue(response.json['error_message']) + def test_lock_action_controller(self): self._configure_networks() # Create controller-0 @@ -739,7 +762,7 @@ class TestPatch(TestHost): constants.LOCK_ACTION, 'sysinv-test') self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.status_code, 200) + self.assertEqual(response.status_code, http_client.OK) # Verify that the SM lock pre check was done self.mock_sm_api_lock_pre_check.assert_called_with(c1_host['hostname'], @@ -782,7 +805,7 @@ class TestPatch(TestHost): constants.FORCE_LOCK_ACTION, 'sysinv-test') self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.status_code, 200) + self.assertEqual(response.status_code, http_client.OK) # Verify that the SM lock pre check was not done self.mock_sm_api_lock_pre_check.assert_not_called() @@ -832,7 +855,7 @@ class TestPatch(TestHost): constants.UNLOCK_ACTION, 'sysinv-test') self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.status_code, 200) + self.assertEqual(response.status_code, http_client.OK) # Verify that the unlock was sent to the VIM self.mock_vim_api_host_action.assert_called_with( @@ -880,7 +903,7 @@ class TestPatch(TestHost): constants.LOCK_ACTION, 'sysinv-test') self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.status_code, 200) + self.assertEqual(response.status_code, http_client.OK) # Verify that the SM lock pre check was not done self.mock_sm_api_lock_pre_check.assert_not_called() @@ -932,7 +955,7 @@ class TestPatch(TestHost): constants.SWACT_ACTION, 'sysinv-test') self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.status_code, 200) + self.assertEqual(response.status_code, http_client.OK) # Verify that the SM swact pre check was done self.mock_sm_api_swact_pre_check.assert_called_with(c1_host['hostname'], @@ -970,7 +993,7 @@ class TestPatch(TestHost): constants.FORCE_SWACT_ACTION, 'sysinv-test') self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.status_code, 200) + self.assertEqual(response.status_code, http_client.OK) # Verify that the SM swact pre check was not done self.mock_sm_api_swact_pre_check.assert_not_called() @@ -1007,7 +1030,7 @@ class TestPatch(TestHost): constants.RESET_ACTION, 'sysinv-test') self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.status_code, 200) + self.assertEqual(response.status_code, http_client.OK) # Verify that the reset was not sent to the VIM self.mock_vim_api_host_action.assert_not_called() @@ -1042,7 +1065,7 @@ class TestPatch(TestHost): constants.REBOOT_ACTION, 'sysinv-test') self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.status_code, 200) + self.assertEqual(response.status_code, http_client.OK) # Verify that the reboot was not sent to the VIM self.mock_vim_api_host_action.assert_not_called() @@ -1077,7 +1100,7 @@ class TestPatch(TestHost): constants.REINSTALL_ACTION, 'sysinv-test') self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.status_code, 200) + self.assertEqual(response.status_code, http_client.OK) # Verify that the host config was removed self.fake_conductor_api.remove_host_config.assert_called_with( @@ -1115,7 +1138,7 @@ class TestPatch(TestHost): constants.POWERON_ACTION, 'sysinv-test') self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.status_code, 200) + self.assertEqual(response.status_code, http_client.OK) # Verify that the poweron was not sent to the VIM self.mock_vim_api_host_action.assert_not_called() @@ -1150,7 +1173,7 @@ class TestPatch(TestHost): constants.POWEROFF_ACTION, 'sysinv-test') self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.status_code, 200) + self.assertEqual(response.status_code, http_client.OK) # Verify that the poweroff was not sent to the VIM self.mock_vim_api_host_action.assert_not_called() @@ -1186,7 +1209,7 @@ class TestPatch(TestHost): constants.VIM_SERVICES_ENABLED, 'vim') self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.status_code, 200) + self.assertEqual(response.status_code, http_client.OK) # Verify that the services enabled was not sent to the VIM self.mock_vim_api_host_action.assert_not_called() @@ -1229,7 +1252,7 @@ class TestPatch(TestHost): constants.VIM_SERVICES_DISABLED, 'vim') self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.status_code, 200) + self.assertEqual(response.status_code, http_client.OK) # Verify that the services disabled was not sent to the VIM self.mock_vim_api_host_action.assert_not_called() @@ -1273,7 +1296,7 @@ class TestPatch(TestHost): constants.VIM_SERVICES_DISABLE_FAILED, 'vim') self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.status_code, 200) + self.assertEqual(response.status_code, http_client.OK) # Verify that the services disable failed was not sent to the VIM self.mock_vim_api_host_action.assert_not_called() @@ -1316,7 +1339,7 @@ class TestPatch(TestHost): constants.VIM_SERVICES_DISABLE_EXTEND, 'vim') self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.status_code, 200) + self.assertEqual(response.status_code, http_client.OK) # Verify that the services disable extend was not sent to the VIM self.mock_vim_api_host_action.assert_not_called() @@ -1358,7 +1381,7 @@ class TestPatch(TestHost): constants.VIM_SERVICES_DELETE_FAILED, 'vim') self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.status_code, 200) + self.assertEqual(response.status_code, http_client.OK) # Verify that the services disable failed was not sent to the VIM self.mock_vim_api_host_action.assert_not_called() @@ -1437,7 +1460,7 @@ class TestPatch(TestHost): constants.SUBFUNCTION_CONFIG_ACTION, 'sysinv-test') self.assertEqual(response.content_type, 'application/json') - self.assertEqual(response.status_code, 200) + self.assertEqual(response.status_code, http_client.OK) # Verify that the configure was not sent to the VIM self.mock_vim_api_host_action.assert_not_called() diff --git a/sysinv/sysinv/sysinv/sysinv/tests/db/utils.py b/sysinv/sysinv/sysinv/sysinv/tests/db/utils.py index c1865e9c98..3816a34265 100644 --- a/sysinv/sysinv/sysinv/sysinv/tests/db/utils.py +++ b/sysinv/sysinv/sysinv/sysinv/tests/db/utils.py @@ -160,6 +160,7 @@ def get_test_ihost(**kw): 'install_state': kw.get('install_state', None), 'install_state_info': kw.get('install_state_info', None), 'iscsi_initiator_name': kw.get('iscsi_initiator_name', None), + 'inv_state': kw.get('inv_state', 'inventoried'), } return inv