def test_get_active_vioses(self): self.mock_vios_get.return_value = self.entries vioses = tpar.get_active_vioses(self.adpt) self.assertEqual(1, len(vioses)) self.mock_vios_get.assert_called_once_with(self.adpt, xag=()) vio = vioses[0] self.assertEqual(bp.LPARState.RUNNING, vio.state) self.assertEqual(bp.RMCState.ACTIVE, vio.rmc_state) self.mock_vios_get.assert_called_once_with(self.adpt, xag=()) self.mock_vios_get.reset_mock() # Test with actual xag. find_min equal to the number found - works. vioses = tpar.get_active_vioses(self.adpt, xag='xaglist', find_min=1) self.assertEqual(1, len(vioses)) vio = vioses[0] self.assertEqual(bp.LPARState.RUNNING, vio.state) self.assertEqual(bp.RMCState.ACTIVE, vio.rmc_state) self.mock_vios_get.assert_called_once_with(self.adpt, xag='xaglist') # Violates find_min self.assertRaises(ex.NotEnoughActiveVioses, tpar.get_active_vioses, self.adpt, find_min=2)
def get_iscsi_initiators(adapter, vios_ids=None): """Gets the VIOS iSCSI initiators. For the first time invocation of this method after process start up, it populates initiators data for VIOSes (if specified, otherwise it gets active VIOSes from the host) and stores in memory for futher lookup. :param adapter: The pypowervm adapter :param vios_ids: List of VIOS ids to get the initiators. If not specified, a list of active VIOSes for the host is fetched (but only for the first time) through the pypowervm adapter. :return: A dict of the form {<vios_id>: <list of initiators>} """ global _ISCSI_INITIATORS def discover_initiator(vios_id): # Get the VIOS id lock for initiator lookup @lockutils.synchronized('inititator-lookup-' + vios_id) def _discover_initiator(): if vios_id in _ISCSI_INITIATORS and _ISCSI_INITIATORS[vios_id]: return else: try: initiator = hdisk.discover_iscsi_initiator( adapter, vios_id) _ISCSI_INITIATORS[vios_id] = initiator except (pvm_exc.ISCSIDiscoveryFailed, pvm_exc.JobRequestFailed) as e: # TODO(chhagarw): handle differently based on # error codes LOG.error(e) _discover_initiator() if vios_ids is None and not _ISCSI_INITIATORS: vios_list = pvm_partition.get_active_vioses(adapter) vios_ids = [vios.uuid for vios in vios_list] for vios_id in vios_ids or []: discover_initiator(vios_id) LOG.debug("iSCSI initiator info: %s" % _ISCSI_INITIATORS) return _ISCSI_INITIATORS
def _find_vopt_repo_data(adapter, vopt_media_volume_group): """Finds the vopt repo defaults. :param adapter: pypowervm adapter :param vopt_media_volume_group: The name of the volume group to use. :return found_vg: Returned if a volume group already exists with a media repo within it. Is that corresponding volume group. :return found_vios: Returned if a volume group already exists with a media repo within it. This is the VIOS wrapper. :return conf_vg: Returned if a volume group does not exist with a media repo within it. This is the volume group wrapper (as defined by the vopt_media_volume_group) that the consumer code should create that media repo within. :return conf_vios: Returned if a volume group does not exist with a media repo within it. This is the VIOS wrapper that is the parent of the conf_vg """ vios_wraps = partition.get_active_vioses(adapter) # First loop through the VIOSes and their VGs to see if a media repos # already exists. found_vg, found_vios = None, None # And in case we don't find the media repos, keep track of the VG on # which we should create it. conf_vg, conf_vios = None, None for vio_wrap in vios_wraps: vg_wraps = pvm_stg.VG.get(adapter, parent=vio_wrap) for vg_wrap in vg_wraps: if len(vg_wrap.vmedia_repos) != 0: found_vg, found_vios = vg_wrap, vio_wrap break # In case no media repos exists, save a pointer to the # CONFigured vopt_media_volume_group if we find it. if (conf_vg is None and not vio_wrap.is_mgmt_partition and vg_wrap.name == vopt_media_volume_group): conf_vg, conf_vios = vg_wrap, vio_wrap # If we found it, don't keep looking if found_vg: break return found_vg, found_vios, conf_vg, conf_vios
def _check_and_filter_vioses(adap, vioses, redundancy): """Return active VIOSes with appropriate vNIC capabilities. Remove all VIOSes which are not active or not vNIC capable. If min_redundancy > 1, failover is required, so remove VIOSes that are not also vNIC failover capable. Error if no VIOSes remain. :param adap: pypowervm Adapter. :param vioses: List of pypowervm.wrappers.virtual_io_server.VIOS to check. If None, all active VIOSes are retrieved from the server. :param redundancy: If greater than 1, the return list will include only vNIC failover-capable VIOSes. Otherwise, if any VIOSes are vNIC failover-capable, non-failover-capable VIOSes are excluded. :return: The filtered list of VIOS wrappers. :raise NotEnoughActiveVioses: If no active (including RMC) VIOSes can be found. :raise NoVNICCapableVIOSes: If none of the vioses are vNIC capable. :raise VNICFailoverNotSupportedVIOS: If redundancy > 1 and none of the vioses is vNIC failover capable. """ # This raises if none are found vioses = tpar.get_active_vioses(adap, xag=[], vios_wraps=vioses, find_min=1) # Filter by vNIC capability vioses = [vios for vios in vioses if vios.vnic_capable] if not vioses: raise ex.NoVNICCapableVIOSes() # Filter by failover capability, if needed. # If any are failover-capable, use just those, regardless of redundancy. failover_only = [vios for vios in vioses if vios.vnic_failover_capable] if redundancy > 1 or any(failover_only): vioses = failover_only # At this point, if the list is empty, it's because no failover capability. if not vioses: raise ex.VNICFailoverNotSupportedVIOS(red=redundancy) return vioses
def test_get_active_vioses_w_vios_wraps(self): mock_vios1 = mock_vios('vios1', 'running', 'active') mock_vios2 = mock_vios('vios2', 'running', 'inactive') mock_vios3 = mock_vios('mgmt', 'running', 'inactive', is_mgmt=True) vios_wraps = [mock_vios1, mock_vios2, mock_vios3] vioses = tpar.get_active_vioses(self.adpt, vios_wraps=vios_wraps) self.assertEqual(2, len(vioses)) self.mock_vios_get.assert_not_called() # The first should be the mgmt partition vio = vioses[0] self.assertEqual(bp.LPARState.RUNNING, vio.state) self.assertEqual(bp.RMCState.INACTIVE, vio.rmc_state) # The second should be the active one vio = vioses[1] self.assertEqual(bp.LPARState.RUNNING, vio.state) self.assertEqual(bp.RMCState.ACTIVE, vio.rmc_state) self.mock_vios_get.assert_not_called()
def vios_uuids(self): """List the UUIDs of the Virtual I/O Servers hosting the storage.""" vios_wraps = pvm_partition.get_active_vioses(self.adapter) return [wrap.uuid for wrap in vios_wraps]