def _delete_node(self, node): # TODO: add error handling; if the instance termination request # fails, we shouldn't be removing the node from the system try: instance_cache = self.instanceCacheGet(node.name) # TODO: what happens when you attempt to terminate an already # terminated instance? Exception? instance = self.__client.get_instance(instance_cache['id']) log_adapter = CustomAdapter( self.getLogger(), {'instance_ocid': instance_cache['id']}) # Issue terminate request log_adapter.debug('Terminating...') self.__client.terminate_instance(instance.data.id) # Wait 3 seconds before checking state gevent.sleep(3) # Wait until state is 'TERMINATED' self._wait_for_instance_state(instance_cache['id'], 'TERMINATED') # Clean up the instance cache. self.instanceCacheDelete(node.name) except ResourceNotFound: pass # Remove Puppet certificate bhm = osUtility.getOsObjectFactory().getOsBootHostManager() bhm.deleteNodeCleanup(node)
def __init__(self, addHostSession: Optional[str] = None) -> None: super().__init__(addHostSession=addHostSession) self._bhm = \ osUtility.getOsObjectFactory().getOsBootHostManager(self._cm) self.looping = False
def _remove_component_from_software_profile(self, kit, comp_name, comp_version, software_profile): """ Removes a kit to a software profile. This is a data-only operation, as no pre/post disable actions are called. :param kit: the OS Kit instance, whose component is being removed :param comp_name: the name of the component to remove :param comp_version: the version of the component to remove :param software_profile: the software profile to which the component will be removed :return: the Component instance that was removed """ os_obj_factory = osUtility.getOsObjectFactory( software_profile.getOsInfo().getOsFamilyInfo().getName()) comp_manager = os_obj_factory.getComponentManager() best_match_component = comp_manager.getBestMatchComponent( comp_name, comp_version, software_profile.getOsInfo(), kit.getId()) self._component_db_api.deleteComponentFromSoftwareProfile( best_match_component.getId(), software_profile.getId()) return best_match_component
def __getOsObject(self): """Get and cache the OS Object Factory""" if self.__osObject is None: from tortuga.os_utility import osUtility self.__osObject = osUtility.getOsObjectFactory() return self.__osObject
def getLockFileName(self, utilityName): \ # pylint: disable=no-self-use if not utilityName: raise InvalidArgument('Invalid utility name provided.') fsMan = osUtility.getOsObjectFactory().getOsFileSystemManager() return '%s/%s' % (fsMan.getOsLockFilePath(), utilityName)
def rebootNode(self, nodespec, bSoftReset=False, bReinstall=False): """ Raises: NodeNotFound """ session = DbManager().openSession() try: nodes = self.__expand_nodespec(session, nodespec) if not nodes: raise NodeNotFound('No nodes matching nodespec [%s]' % (nodespec)) bhm = osUtility.getOsObjectFactory().getOsBootHostManager() if bReinstall: for dbNode in nodes: bhm.setNodeForNetworkBoot(dbNode) results = NodesDbHandler().rebootNode(session, nodes, bSoftReset) session.commit() return results finally: DbManager().closeSession()
def __init__(self): super(SyncManager, self).__init__() self._isUpdateScheduled = False self._isUpdateRunning = False self._sudoCmd = \ osUtility.getOsObjectFactory().getOsSysManager().getSudoCommand() self._cm = ConfigManager()
def __init__(self, private_dns_zone): """ :param private_dns_zone: String :returns: DnsmasqDnsProvider """ super(DnsmasqDnsProvider, self).__init__(private_dns_zone) self._service_handle = getOsObjectFactory().getOsServiceManager() self._service_name = 'dnsmasq'
def __init__(self): super(NodeManager, self).__init__() self._nodeDbApi = NodeDbApi() self._hardwareProfileDbApi = HardwareProfileDbApi() self._cm = ConfigManager() self._san = san.San() self._bhm = osUtility.getOsObjectFactory().getOsBootHostManager()
def __init__(self, component_installer): """ :param component_installer: Kit installer object :returns: DhcpProvider """ self._service_name = None self._service_handle = getOsObjectFactory().getOsServiceManager() self._component_installer = component_installer
def _updateNodeStatus(self, dbNode, state=None, bootFrom=None): """ Internal method which takes a 'Nodes' object instead of a node name. """ result = NodesDbHandler().updateNodeStatus(dbNode, state, bootFrom) # Only change local boot configuration if the hardware profile is # not marked as 'remote' and we're not acting on the installer node. if dbNode.softwareprofile and \ dbNode.softwareprofile.type != 'installer' and \ dbNode.hardwareprofile.location not in \ ('remote', 'remote-vpn'): osUtility.getOsObjectFactory().getOsBootHostManager().\ writePXEFile(dbNode, localboot=bootFrom) return result
def __init__(self): super(NodeManager, self).__init__() self._nodeDbApi = NodeDbApi() self._cm = ConfigManager() self._bhm = osUtility.getOsObjectFactory().getOsBootHostManager( self._cm) self._nodesDbHandler = NodesDbHandler() self._addHostManager = AddHostManager() self._logger = logging.getLogger(NODE_NAMESPACE)
def _disableTortugaws(self): self.out(' * Disabling Tortuga webservice\n') _tortugaWsManager = self._osObjectFactory.getTortugawsManager() serviceName = _tortugaWsManager.getServiceName() _osServiceManager = getOsObjectFactory().getOsServiceManager() try: _osServiceManager.stop(serviceName) except CommandFailed: pass
def action_post_install(self, *args, **kwargs): """ Extract files from Clonezilla Live ZIP and install them """ super().action_post_install(*args, **kwargs) os_obj_factory = getOsObjectFactory() tftp_dir = os.path.join( os_obj_factory.getOsBootHostManager().getTftproot(), 'tortuga') self.copy_clonezilla_files(tftp_dir) self.create_clonezilla_support_files(tftp_dir)
def _get_os_dhcpd_manager(self, name): """ Get dhcpd manager for the appropriate os. :param name: the name of the dhcpd manager to get :returns: the dhcpd manager instance """ dir_name = '{}/util'.format(self.kit_installer.kit_path) dhcpd_manager = \ getOsObjectFactory().getOsKitApplicationManager(name, dir_name) return dhcpd_manager
def _install_os_packages(self, kit, os_info_list): """ Installs OS specific packages from the kit into the repo. :param kit: the kit instance :param os_info_list: a list of osInfo instances to install for """ all_component_list = kit.getComponentList() for os_info in os_info_list: self._logger.debug( 'Preparing to install ({}, {}, {}) for {}'.format( kit.getName(), kit.getVersion(), kit.getIteration(), os_info ) ) # # Get list of compatible components # os_object_factory = getOsObjectFactory( mapOsName(os_info.getName()) ) component_manager = os_object_factory.getComponentManager() component_list = component_manager.getCompatibleComponentList( os_info, all_component_list) if not component_list: continue # # Create the package directory in the repo # repo = repoManager.getRepo(os_info) full_dir = os.path.join(repo.getLocalPath(), kit.getKitRepoDir()) osUtility.createDir(full_dir) # # Install the packages into the repo package directory # for component in component_list: self._logger.debug( '[{0}] Found component [{1}]'.format( self.__class__.__name__, component)) for package in component.getPackageList(): package_file = os.path.join( kit.install_path, package.getRelativePath()) self._logger.debug( '[{0}] Found package [{1}]'.format( self.__class__.__name__, package_file)) repo.addPackage(package_file, kit.getKitRepoDir()) repo.create(kit.getKitRepoDir())
def __init__(self, kit_installer): super().__init__(kit_installer) os_object_factory = osUtility.getOsObjectFactory() self._os_service_manager = os_object_factory.getOsServiceManager() self._software_profile_db_api = SoftwareProfileDbApi() # self._uge_mgmt_api = Uge_mgmt_api() self._node_api = NodesDbHandler() self.installer_hostname = socket.getfqdn() self._logger = logging.getLogger('{}.{}'.format( KIT_NAMESPACE, kit_installer.name))
def idleNode(self, nodespec): """ Raises: NodeNotFound """ session = DbManager().openSession() try: nodes = self.__expand_nodespec(session, nodespec) if not nodes: raise NodeNotFound('No nodes matching nodespec [%s]' % (nodespec)) result = NodesDbHandler().idleNode(session, nodes) # Convert list of Nodes to list of node names for providing # user feedback. result_dict = {} for key, dbNodes in result.items(): result_dict[key] = [dbNode.name for dbNode in dbNodes] session.commit() # Remove Puppet certificate(s) for idled node(s) for node_name in result_dict['success']: # Remove Puppet certificate for idled node bhm = osUtility.getOsObjectFactory().getOsBootHostManager() bhm.deletePuppetNodeCert(node_name) # Schedule a cluster update self.__scheduleUpdate() return result_dict except TortugaException as ex: session.rollback() raise except Exception as ex: session.rollback() self.getLogger().exception('[%s] %s' % (self.__class__.__name__, ex)) raise finally: DbManager().closeSession()
def writeLocalBootConfiguration(self, node: Node, hardwareprofile: HardwareProfile, softwareprofile: SoftwareProfile): """ Raises: NicNotFound """ if not hardwareprofile.nics: # Hardware profile has no provisioning NICs defined. This # shouldn't happen... self.getLogger().debug( 'No provisioning nics defined in hardware profile %s' % (hardwareprofile.name)) return # Determine the provisioning nic for the hardware profile hwProfileProvisioningNic = hardwareprofile.nics[0] nic = None if hwProfileProvisioningNic.network: # Find the nic attached to the newly added node that is on # the same network as the provisioning nic. nic = self.__findNicForProvisioningNetwork( node.nics, hwProfileProvisioningNic.network) if not nic or not nic.mac: self.getLogger().warning( 'MAC address not defined for nic (ip=[%s]) on node [%s]' % (nic.ip, node.name)) return # Set up DHCP/PXE for newly addded node bhm = getOsObjectFactory().getOsBootHostManager(self._cm) # Write out the PXE file bhm.writePXEFile(self.session, node, hardwareprofile=hardwareprofile, softwareprofile=softwareprofile, localboot=False) # Add a DHCP lease bhm.addDhcpLease(node, nic)
def transferNode(self, nodeIdSoftwareProfileTuples, newSoftwareProfileName): \ # pylint: disable=unused-argument """ Raises: NodeNotFound """ bhm = osUtility.getOsObjectFactory().getOsBootHostManager() for dbNode, _ in nodeIdSoftwareProfileTuples: # Ensure PXE files are properly in place before triggering # the reboot. bhm.setNodeForNetworkBoot(dbNode) self.rebootNode([dbNode for dbNode, _ in nodeIdSoftwareProfileTuples])
def __init__(self, osdistro: DistributionFactory, **kwargs): self._osdistro: DistributionFactory = osdistro self._kit = None self._bInteractive = kwargs['bInteractive'] \ if 'bInteractive' in kwargs else False self._bUseSymlinks = kwargs['bUseSymlinks'] \ if 'bUseSymlinks' in kwargs else False self._mirror = kwargs['mirror'] if 'mirror' in kwargs else False self._logger = logging.getLogger(KIT_NAMESPACE) self._cm = ConfigManager() self.pxeboot_dir = os.path.join( getOsObjectFactory().getOsBootHostManager(self._cm).getTftproot(), 'tortuga')
def __init__(self, logger, cmdline_options=None): self._cm = ConfigManager() self._logger = logger self._osObjectFactory = osUtility.getOsObjectFactory() self._settings = self.__load_settings(cmdline_options) self._settings['installer_software_profile'] = 'Installer' self._settings['installer_hardware_profile'] = 'Installer' self._settings['eulaAccepted'] = False self._settings['fqdn'] = getfqdn() self._settings['osInfo'] = getOsInfo() self._forceCleaning = False self._depotCreated = False fsManager = self._osObjectFactory.getOsFileSystemManager() self._lockFilePath = os.path.join( fsManager.getOsLockFilePath(), 'tortuga-setup') langdomain = 'tortuga-config' localedir = os.path.join(self._cm.getRoot(), 'share', 'locale') if not os.path.exists(localedir): # Try the system path localedir = '/usr/share/locale' gettext.bindtextdomain(langdomain, localedir) gettext.textdomain(langdomain) self.gettext = gettext.gettext self._ = self.gettext self._logger.info('Detected OS: [%s]', self._settings['osInfo'])
def __init__(self, osdistro: DistributionFactory, **kwargs): self._osdistro: DistributionFactory = osdistro self._kit = None self._bInteractive = kwargs['bInteractive'] \ if 'bInteractive' in kwargs else False self._bUseSymlinks = kwargs['bUseSymlinks'] \ if 'bUseSymlinks' in kwargs else False self._mirror = kwargs['mirror'] if 'mirror' in kwargs else False self._logger = logging.getLogger('tortuga.kit.%s' % self.__class__.__name__) self._logger.addHandler(logging.NullHandler()) self._cm = ConfigManager() self.pxeboot_dir = os.path.join( getOsObjectFactory().getOsBootHostManager().getTftproot(), 'tortuga')
def activateIdleNode(self, dbNode, softwareProfileName, softwareProfileChanged): \ # pylint: disable=no-self-use bhm = osUtility.getOsObjectFactory().getOsBootHostManager() session = DbManager().openSession() try: if softwareProfileChanged: softwareprofile = SoftwareProfilesDbHandler().\ getSoftwareProfile(session, softwareProfileName) # Mark node for network boot if software profile changed dbNode.bootFrom = 0 else: softwareprofile = None bhm.writePXEFile(dbNode, localboot=not softwareProfileChanged, softwareprofile=softwareprofile) finally: DbManager().closeSession()
def _getCoreComponentForOsInfo(self, osInfo): # Find core component # Find the version of the 'core' component import tortuga.kit.kitApi _kitApi = tortuga.kit.kitApi.KitApi() baseKit = None for baseKit in _kitApi.getKitList(): if not baseKit.getName() == self.BASE_KIT_NAME: continue break else: raise KitNotFound('Kit [%s] not found.' % (self.BASE_KIT_NAME)) baseComp = None for baseComp in baseKit.getComponentList(): if baseComp.getName() != 'core': continue break else: raise ComponentNotFound('Component [%s] not found in kit [%s]' % ('core', baseKit.getName())) comp = osUtility.getOsObjectFactory().getComponentManager().\ getBestMatchComponent( baseComp.getName(), baseComp.getVersion(), osInfo, baseKit.getId()) comp.setKit(baseKit) return comp
def deleteNode(self, nodespec): """ Delete node by nodespec Raises: NodeNotFound """ installer_hostname = socket.getfqdn().split('.', 1)[0] session = DbManager().openSession() try: nodes = [] for node in self.__expand_nodespec(session, nodespec): if node.name.split('.', 1)[0] == installer_hostname: self.getLogger().info( 'Ignoring request to delete installer node' ' ([{0}])'.format(node.name)) continue nodes.append(node) if not nodes: raise NodeNotFound('No nodes matching nodespec [%s]' % (nodespec)) self.__preDeleteHost(nodes) nodeErrorDict = NodesDbHandler().deleteNode(session, nodes) # REALLY!?!? Convert a list of Nodes objects into a list of # node names so we can report the list back to the end-user. # This needs to be FIXED! result, nodes_deleted = self.__process_nodeErrorDict(nodeErrorDict) session.commit() # ============================================================ # Perform actions *after* node deletion(s) have been committed # to database. # ============================================================ self.__postDeleteHost(nodes_deleted) addHostSessions = set( [tmpnode['addHostSession'] for tmpnode in nodes_deleted]) if addHostSessions: AddHostManager().delete_sessions(addHostSessions) bhm = osUtility.getOsObjectFactory().getOsBootHostManager() for nodeName in result['NodesDeleted']: # Remove the Puppet cert bhm.deletePuppetNodeCert(nodeName) bhm.nodeCleanup(nodeName) self.getLogger().info('Node [%s] deleted' % (nodeName)) # Schedule a cluster update self.__scheduleUpdate() return result except TortugaException: session.rollback() raise except Exception: session.rollback() self.getLogger().exception('Exception in NodeManager.deleteNode()') raise finally: DbManager().closeSession()
def __dhcp_discovery(self, addNodesRequest, dbSession, dbHardwareProfile, dbSoftwareProfile): # Listen for DHCP requests if not dbHardwareProfile.nics: raise CommandFailed( 'Hardware profile [%s] does not have a provisioning' ' NIC defined' % (dbHardwareProfile.name)) newNodes = [] deviceName = addNodesRequest['deviceName'] \ if 'deviceName' in addNodesRequest else None nodeCount = addNodesRequest['count'] \ if 'count' in addNodesRequest else 0 bGenerateIp = dbHardwareProfile.location != 'remote' # Obtain platform-specific packet capture subprocess object addHostManager = osUtility.getOsObjectFactory().getOsAddHostManager() deviceName = dbHardwareProfile.nics[0].networkdevice.name p1 = addHostManager.dhcpCaptureSubprocess(deviceName) if nodeCount: self.getLogger().debug( 'Adding [%s] new %s' % (nodeCount, 'nodes' if nodeCount > 1 else 'node')) self.looping = True index = 0 # Node count was not specified, so discover DHCP nodes # until manually aborted by user. msg = 'Waiting for new node...' if not nodeCount else \ 'Waiting for new node #1 of %d...' % (nodeCount) try: while self.looping: # May not need this... dataReady = select.select([p1.stdout], [], [], 5) if not dataReady[0]: continue line = p1.stdout.readline() if not line: self.getLogger().debug( 'DHCP packet capture process ended... exiting') break self.getLogger().debug('Read line "%s" len=%s' % (line, len(line))) mac = addHostManager.getMacAddressFromCaptureEntry(line) if not mac: continue self.getLogger().debug('Discovered MAC address [%s]' % (mac)) if self.__is_duplicate_mac(mac, newNodes): # Ignore DHCP request from known MAC self.getLogger().debug( 'MAC address [%s] is already known' % (mac)) continue addNodeRequest = {} if 'rack' in addNodesRequest: addNodeRequest['rack'] = addNodesRequest['rack'] # Get nics based on hardware profile networks addNodeRequest['nics'] = initialize_nics( dbHardwareProfile.nics[0], dbHardwareProfile.hardwareprofilenetworks, mac) # We may be trying to create the same node for the # second time so we'll ignore errors try: node = self.nodeApi.createNewNode(None, addNodeRequest, dbHardwareProfile, dbSoftwareProfile, bGenerateIp=bGenerateIp) except NodeAlreadyExists as ex: existingNodeName = ex.args[0] self.getLogger().debug('Node [%s] already exists' % (existingNodeName)) continue except MacAddressAlreadyExists: self.getLogger().debug('MAC address [%s] already exists' % (mac)) continue except IpAlreadyExists as ex: self.getLogger().debug('IP address already in use by node' ' [%s]: %s' % (existingNodeName, ex)) continue # Add the newly created node to the session dbSession.add(node) # Create DHCP/PXE configuration self.writeLocalBootConfiguration(node, dbHardwareProfile, dbSoftwareProfile) index += 1 # Use first provisioning nic nic = get_provisioning_nic(node) try: msg = 'Added node [%s] IP [%s]' % (node.name, nic.ip) if nic.mac: msg += ' MAC [%s]' % (nic.mac) self.getLogger().info(msg) except Exception as ex: self.getLogger().exception('Error setting status message') self._pre_add_host(node.name, dbHardwareProfile.name, dbSoftwareProfile.name, nic.ip) newNodes.append(node) if nodeCount > 0: nodeCount -= 1 if not nodeCount: self.looping = False except Exception as msg: self.getLogger().exception('DHCP discovery failed') try: os.kill(p1.pid, signal.SIGKILL) os.waitpid(p1.pid, 0) except Exception: self.getLogger().exception('Error killing network capture process') # This is a necessary evil for the time being, until there's # a proper context manager implemented. self.addHostApi.clear_session_nodes(newNodes) return newNodes
def createHardwareProfile(self, hwProfileSpec, settingsDict=None): settingsDict = settingsDict or {} bUseDefaults = settingsDict['bUseDefaults'] \ if 'bUseDefaults' in settingsDict else False osInfo = settingsDict['osInfo'] \ if settingsDict and 'osInfo' in settingsDict else None validation.validateProfileName(hwProfileSpec.getName()) if hwProfileSpec.getDescription() is None or \ hwProfileSpec.getDescription() == '**DEFAULT**': hwProfileSpec.setDescription('%s Nodes' % (hwProfileSpec.getName())) installerNode = self._nodeDbApi.getNode(ConfigManager().getInstaller(), {'softwareprofile': True}) if bUseDefaults: if not hwProfileSpec.getNetworks(): # No <network>...</network> entries found in the template, # use the default provisioning interface from the primary # installer. # Find first provisioning network and use it for nic in installerNode.getNics(): network = nic.getNetwork() if network.getType() == 'provision': # for now set the default interface to be index 0 # with the same device networkDevice = fixNetworkDeviceName( nic.getNetworkDevice().getName()) network.setNetworkDevice( NetworkDevice(name=networkDevice)) hwProfileSpec.getNetworks().append(network) break else: raise NetworkNotFound( 'Unable to find provisioning network') else: # Ensure network device is defined installerNic = None for network in hwProfileSpec.getNetworks(): for installerNic in installerNode.getNics(): installerNetwork = installerNic.getNetwork() if network.getId() and \ network.getId() == installerNetwork.getId(): break elif network.getAddress() and \ network.getAddress() == \ installerNetwork.getAddress() and \ network.getNetmask() and \ network.getNetmask() == \ installerNetwork.getNetmask(): break else: # Unable to find network matching specification in # template. raise NetworkNotFound( 'Unable to find provisioning network [%s]' % (network)) networkDevice = fixNetworkDeviceName( installerNic.getNetworkDevice().getName()) network.setNetworkDevice(NetworkDevice(name=networkDevice)) if hwProfileSpec.getIdleSoftwareProfile(): # <idleSoftwareProfileId>...</idleSoftwareProfileId> is always # contained within the output of get-hardwareprofile. If the # command-line option '--idleSoftwareProfile' is specified, it # overrides the # <idleSoftwareProfileId>...</idleSoftwareProfileId> element idleSoftwareProfile = self._spDbApi.getSoftwareProfile( hwProfileSpec.getIdleSoftwareProfile().getName()) hwProfileSpec.setIdleSoftwareProfileId(idleSoftwareProfile.getId()) if not osInfo: osInfo = installerNode.getSoftwareProfile().getOsInfo() osObjFactory = osUtility.getOsObjectFactory(osInfo.getName()) if not hwProfileSpec.getKernel(): hwProfileSpec.setKernel( osObjFactory.getOsSysManager().getKernel(osInfo)) if not hwProfileSpec.getInitrd(): hwProfileSpec.setInitrd( osObjFactory.getOsSysManager().getInitrd(osInfo)) self._hpDbApi.addHardwareProfile(hwProfileSpec) # Iterate over all networks in the newly defined hardware profile # and build assocations to provisioning NICs if bUseDefaults: for network in \ [network for network in hwProfileSpec.getNetworks() if network.getType() == 'provision']: # Get provisioning nic for network try: provisioningNic = self.getProvisioningNicForNetwork( network.getAddress(), network.getNetmask()) except NicNotFound: # There is currently no provisioning NIC defined for # this network. This is not a fatal error. continue self.setProvisioningNic(hwProfileSpec.getName(), provisioningNic.getId())
def createSoftwareProfile(self, session: Session, swProfileSpec, settingsDict=None): """ Exceptions: ConfigurationError NetworkNotFound ComponentNotFound KitNotFound OSError """ if settingsDict == None: settingsDict = {} bOsMediaRequired = settingsDict.get('bOsMediaRequired', True) unmanagedProfile = settingsDict.get('unmanagedProfile', False) # Validate software profile name validation.validateProfileName(swProfileSpec.getName()) # Insert default description for software profile if swProfileSpec.getDescription() is None: swProfileSpec.setDescription('%s Nodes' % (swProfileSpec.getName())) self._logger.debug('Creating software profile [%s]' % (swProfileSpec)) osInfo = swProfileSpec.getOsInfo() \ if swProfileSpec.getOsInfo() else self._getOsInfo( session, bOsMediaRequired) # If we're creating an unmanaged software profile (no # DHCP/PXE/kickstart/OS) just create it now and we're done if unmanagedProfile: self._sp_db_api.addSoftwareProfile(session, swProfileSpec) else: if bOsMediaRequired and swProfileSpec.getOsInfo(): try: self._kit_db_api.getKit( session, swProfileSpec.getOsInfo().getName(), swProfileSpec.getOsInfo().getVersion(), '0') except KitNotFound: self._logger.error('OS kit for [%s] not found' % (swProfileSpec.getOsInfo())) raise else: swProfileSpec.setOsInfo(osInfo) # Get component manager for appropriate OS family osConfig = osHelper.getOsInfo(osInfo.getName(), osInfo.getVersion(), osInfo.getArch()) osObjFactory = osUtility.getOsObjectFactory( osConfig.getOsFamilyInfo().getName()) # Need to be fancy with components spComponents = swProfileSpec.getComponents() swProfileSpec.setComponents(TortugaObjectList()) bFoundOsComponent = False bFoundCoreComponent = False components = [] # Iterate over components, adding them to the software profile for c in spComponents: cobj = self._component_db_api.getBestMatchComponent( session, c.getName(), c.getVersion(), osInfo, c.getKit().getId()) k = cobj.getKit() if k.getIsOs(): # This component is a member of the OS kit, set the flag bFoundOsComponent = True elif k.getName() == 'base' and c.getName() == 'core': # Found the 'core' component in 'base' kit bFoundCoreComponent = True components.append(cobj) # If the operating system is undefined for this software # profile, use the same OS as the installer. if bOsMediaRequired and not bFoundOsComponent: # Find OS component osCompName = '%s-%s-%s' % ( osInfo.getName(), osInfo.getVersion(), osInfo.getArch()) self._logger.debug('Automatically adding OS component [%s]' ' (not specified in template)' % (osCompName)) try: osComponent = self._component_db_api.getComponent( session, osCompName, osInfo.getVersion(), osInfo, {'kit': True}) components.append(osComponent) except ComponentNotFound: # Cannot find OS component, don't freak out pass # Ensure 'core' component is enabled if not bFoundCoreComponent: # Attempt to automatically add the core component, only # if one exists for this OS try: comp = self._getCoreComponentForOsInfo(session, osInfo) self._logger.debug('Automatically adding [core] component' ' (not specified in template)') components.append(comp) except ComponentNotFound: self._logger.warning( 'OS [{}] does not have a compatible \'core\'' ' component'.format(osInfo)) # Initialize values for kernel, kernelParams, and initrd if not swProfileSpec.getKernel(): swProfileSpec.setKernel( osObjFactory.getOsSysManager().getKernel(osInfo)) if not swProfileSpec.getInitrd(): swProfileSpec.setInitrd( osObjFactory.getOsSysManager().getInitrd(osInfo)) # Add the software profile self._sp_db_api.addSoftwareProfile(session, swProfileSpec) # Enable components in one fell swoop for comp in components: self._logger.debug('Enabling component [%s]' % (comp.getName())) if comp.getKit().getIsOs(): # Don't use enableComponent() on OS kit self._component_db_api.addComponentToSoftwareProfile( session, comp.getId(), swProfileSpec.getId()) continue self.enableComponent(session, swProfileSpec.getName(), comp.getKit().getName(), comp.getKit().getVersion(), comp.getKit().getIteration(), comp.getName(), comp.getVersion()) # # Fire the tags changed event for all creates that have tags # # Get the latest version from the db in case the create method # added some embellishments # swp = self.getSoftwareProfile(session, swProfileSpec.getName()) if swp.getTags(): SoftwareProfileTagsChanged.fire(softwareprofile_id=str( swp.getId()), softwareprofile_name=swp.getName(), tags=swp.getTags(), previous_tags={})
def createSoftwareProfile(self, swProfileSpec, settingsDict=None): """ Exceptions: ConfigurationError NetworkNotFound ComponentNotFound KitNotFound OSError """ # Parse 'settingsDict' if settingsDict: # ... bOsMediaRequired; default is True bOsMediaRequired = settingsDict['bOsMediaRequired'] \ if 'bOsMediaRequired' in settingsDict else True # ... unmanagedProfile; default is False unmanagedProfile = settingsDict['unmanagedProfile'] \ if 'unmanagedProfile' in settingsDict else False # Validate software profile name validation.validateProfileName(swProfileSpec.getName()) # Insert default description for software profile if not swProfileSpec.getDescription() or \ swProfileSpec.getDescription() == '**DEFAULT**': swProfileSpec.setDescription('%s Nodes' % (swProfileSpec.getName())) self.getLogger().debug('Creating software profile [%s]' % (swProfileSpec)) osInfo = swProfileSpec.getOsInfo() \ if swProfileSpec.getOsInfo() else self._getOsInfo(bOsMediaRequired) # If we're creating an unmanaged software profile (no # DHCP/PXE/kickstart/OS) just create it now and we're done if unmanagedProfile: self._sp_db_api.addSoftwareProfile(swProfileSpec) else: if bOsMediaRequired and swProfileSpec.getOsInfo(): try: kitApiFactory.getKitApi().getKit( swProfileSpec.getOsInfo().getName(), swProfileSpec.getOsInfo().getVersion(), '0') except KitNotFound: self._logger.error('OS kit for [%s] not found' % (swProfileSpec.getOsInfo())) raise else: swProfileSpec.setOsInfo(osInfo) # Get component manager for appropriate OS family osConfig = osHelper.getOsInfo(osInfo.getName(), osInfo.getVersion(), osInfo.getArch()) osObjFactory = osUtility.getOsObjectFactory( osConfig.getOsFamilyInfo().getName()) compManager = osObjFactory.getComponentManager() # Need to be fancy with components spComponents = swProfileSpec.getComponents() swProfileSpec.setComponents(TortugaObjectList()) bFoundOsComponent = False bFoundCoreComponent = False components = [] # Iterate over components, adding them to the software profile for c in spComponents: cobj = compManager.getBestMatchComponent( c.getName(), c.getVersion(), osInfo, c.getKit().getId()) k = cobj.getKit() if k.getIsOs(): # This component is a member of the OS kit, set the flag bFoundOsComponent = True else: if c.getName() == 'core': # Found the 'core' component, set the flag bFoundCoreComponent = True components.append(cobj) # If the operating system is undefined for this software # profile, use the same OS as the installer. if bOsMediaRequired and not bFoundOsComponent: # Find OS component osCompName = '%s-%s-%s' % ( osInfo.getName(), osInfo.getVersion(), osInfo.getArch()) self.getLogger().debug('Automatically adding OS component [%s]' ' (not specified in template)' % (osCompName)) try: osComponent = self._component_db_api.getComponent( osCompName, osInfo.getVersion(), osInfo, {'kit': True}) components.append(osComponent) except ComponentNotFound: # Cannot find OS component, don't freak out pass # Ensure 'core' component is enabled if not bFoundCoreComponent: # Attempt to automatically add the core component, only # if one exists for this OS try: comp = self._getCoreComponentForOsInfo(osInfo) self.getLogger().debug( 'Automatically adding [core] component' ' (not specified in template)') components.append(comp) except ComponentNotFound: pass # Initialize values for kernel, kernelParams, and initrd if not swProfileSpec.getKernel(): swProfileSpec.setKernel( osObjFactory.getOsSysManager().getKernel(osInfo)) if not swProfileSpec.getInitrd(): swProfileSpec.setInitrd( osObjFactory.getOsSysManager().getInitrd(osInfo)) # Add the software profile self._sp_db_api.addSoftwareProfile(swProfileSpec) # Enable components in one fell swoop for comp in components: self.getLogger().debug('Enabling component [%s]' % (comp.getName())) if comp.getKit().getIsOs(): # Don't use enableComponent() on OS kit self._component_db_api.\ addComponentToSoftwareProfile( comp.getId(), swProfileSpec.getId()) continue self.enableComponent(swProfileSpec.getName(), comp.getKit().getName(), comp.getKit().getVersion(), comp.getKit().getIteration(), comp.getName(), comp.getVersion()) self.getLogger().debug( 'Software profile [%s] created successfully' % (swProfileSpec.getName()))