class HardwareProfileDbApi(TortugaDbApi): """ HardwareProfile DB API class. """ def __init__(self): TortugaDbApi.__init__(self) self._hardwareProfilesDbHandler = HardwareProfilesDbHandler() self._nodesDbHandler = NodesDbHandler() self._globalParametersDbHandler = GlobalParametersDbHandler() self._adminsDbHandler = AdminsDbHandler() self._nicsDbHandler = NicsDbHandler() self._resourceAdaptersDbHandler = ResourceAdaptersDbHandler() self._networkDevicesDbHandler = NetworkDevicesDbHandler() self._networksDbHandler = NetworksDbHandler() def getHardwareProfile(self, name: str, optionDict: Optional[Union[dict, None]] = None): """ Get hardwareProfile from the db. Returns: hardwareProfile Throws: HardwareProfileNotFound DbError """ session = DbManager().openSession() try: dbHardwareProfile = self._hardwareProfilesDbHandler.\ getHardwareProfile(session, name) self.loadRelations(dbHardwareProfile, optionDict) self.loadRelations(dbHardwareProfile, dict(tags=True)) return HardwareProfile.getFromDbDict(dbHardwareProfile.__dict__) except TortugaException as ex: raise except Exception as ex: self.getLogger().exception('%s' % ex) raise finally: DbManager().closeSession() def getHardwareProfileById(self, hardwareProfileId: int, optionDict: Optional[Union[dict, None]] = None): """ Get hardwareProfile from the db. Returns: hardwareProfile Throws: HardwareProfileNotFound DbError """ session = DbManager().openSession() try: dbHardwareProfile = self._hardwareProfilesDbHandler.\ getHardwareProfileById(session, hardwareProfileId) self.loadRelations(dbHardwareProfile, optionDict) return HardwareProfile.getFromDbDict(dbHardwareProfile.__dict__) except TortugaException as ex: raise except Exception as ex: self.getLogger().exception('%s' % ex) raise finally: DbManager().closeSession() def getHardwareProfileList(self, optionDict: Optional[Union[dict, None]] = None, tags: Optional[Union[dict, None]] = None): """ Get list of all available hardwareProfiles from the db. Returns: [hardwareProfile] Throws: DbError """ session = DbManager().openSession() try: dbHardwareProfileList = self._hardwareProfilesDbHandler.\ getHardwareProfileList(session, tags=tags) hardwareProfileList = TortugaObjectList() for dbHardwareProfile in dbHardwareProfileList: # For now expand networks self.loadRelation(dbHardwareProfile, 'hardwareprofilenetworks') self.loadRelations(dbHardwareProfile, optionDict) self.loadRelations(dbHardwareProfile, dict(tags=True)) hardwareProfileList.append( HardwareProfile.getFromDbDict(dbHardwareProfile.__dict__)) return hardwareProfileList except TortugaException as ex: raise except Exception as ex: self.getLogger().exception('%s' % ex) raise finally: DbManager().closeSession() def setIdleSoftwareProfile(self, hardwareProfileName, softwareProfileName=None): """ Sets the idle software profile Returns: -none- Raises: SoftwareProfileNotFound SoftwareProfileNotIdle """ session = DbManager().openSession() try: dbSoftwareProfile = SoftwareProfilesDbHandler().\ getSoftwareProfile(session, softwareProfileName) \ if softwareProfileName else None dbHardwareProfile = self._hardwareProfilesDbHandler.\ getHardwareProfile(session, hardwareProfileName) self._hardwareProfilesDbHandler.setIdleSoftwareProfile( dbHardwareProfile, dbSoftwareProfile) session.commit() except TortugaException as ex: raise except Exception as ex: self.getLogger().exception('%s' % ex) raise finally: DbManager().closeSession() def addHardwareProfile(self, hardwareProfile, session=None): """ Insert hardwareProfile into the db. Returns: (none) Throws: HardwareProfileAlreadyExists DbError """ # Keep local 'session' instance. If 'session' is None, # ensure transaction is committed before returning to the # caller, otherwise the caller is responsible. On exceptions, # the rollback is performed regardless. _session = session if _session is None: _session = DbManager().openSession() try: try: self._hardwareProfilesDbHandler.getHardwareProfile( _session, hardwareProfile.getName()) raise HardwareProfileAlreadyExists( 'Hardware profile [%s] already exists' % (hardwareProfile)) except HardwareProfileNotFound as ex: pass dbHardwareProfile = self.__populateHardwareProfile( _session, hardwareProfile) _session.add(dbHardwareProfile) if session is None: _session.commit() self.getLogger().info('Added hardware profile [%s]' % (dbHardwareProfile.name)) except TortugaException as ex: _session.rollback() raise except Exception as ex: _session.rollback() self.getLogger().exception('%s' % ex) raise finally: if session is None: DbManager().closeSession() def deleteHardwareProfile(self, name): """ Delete hardwareProfile from the db. Returns: None Throws: HardwareProfileNotFound DbError TortugaException """ session = DbManager().openSession() try: hwProfile = self._hardwareProfilesDbHandler.getHardwareProfile( session, name) if hwProfile.nodes: raise TortugaException( 'Unable to remove hardware profile with associated' ' nodes') # First delete the mappings hwProfile.mappedsoftwareprofiles = [] self.getLogger().debug( 'Marking hardware profile [%s] for deletion' % (name)) session.delete(hwProfile) session.commit() except TortugaException as ex: session.rollback() raise except Exception as ex: session.rollback() self.getLogger().exception('%s' % ex) raise finally: DbManager().closeSession() def copyHardwareProfile(self, srcHardwareProfileName, dstHardwareProfileName): session = DbManager().openSession() try: srcHardwareProfile = self.getHardwareProfile( srcHardwareProfileName, { 'admins': True, 'hardwareprofilenetworks': True, 'nics': True, 'resourceadapter': True, }) dstHardwareProfile = \ self.getHardwareProfile(srcHardwareProfileName) dstHardwareProfile.setName(dstHardwareProfileName) newDescription = 'Copy of %s' % ( dstHardwareProfile.getDescription()) dstHardwareProfile.setDescription(newDescription) dstHardwareProfile.setNetworks(srcHardwareProfile.getNetworks()) dstHardwareProfile.setProvisioningNics( srcHardwareProfile.getProvisioningNics()) dstHardwareProfile.setResourceAdapter( srcHardwareProfile.getResourceAdapter()) self.addHardwareProfile(dstHardwareProfile, session) session.commit() finally: DbManager().closeSession() def getNode(self, name): """ Get node from the db. Returns: node Throws: NodeNotFound DbError """ session = DbManager().openSession() try: return self._nodesDbHandler.getNode(session, name) except TortugaException as ex: raise except Exception as ex: self.getLogger().exception('%s' % ex) raise finally: DbManager().closeSession() def deleteNode(self, name): """ Delete node from the db. Returns: None Throws: NodeNotFound DbError """ session = DbManager().openSession() try: self._nodesDbHandler.deleteNode(session, name) session.commit() except TortugaException as ex: session.rollback() raise except Exception as ex: session.rollback() self.getLogger().exception('%s' % ex) raise finally: DbManager().closeSession() def addAdmin(self, hardwareProfileName, adminUsername): """ Add an admin to this hardware profile Raises: AdminAlreadyExists """ session = DbManager().openSession() try: dbAdmin = self._adminsDbHandler.getAdmin(session, adminUsername) dbHardwareProfile = self._hardwareProfilesDbHandler.\ getHardwareProfile(session, hardwareProfileName) if dbAdmin in dbHardwareProfile.admins: raise AdminAlreadyExists( 'The admin %s is already associated with %s.' % (adminUsername, hardwareProfileName)) dbHardwareProfile.admins.append(dbAdmin) session.commit() except TortugaException as ex: session.rollback() raise except Exception as ex: session.rollback() self.getLogger().exception('%s' % ex) raise finally: DbManager().closeSession() def deleteAdmin(self, hardwareProfileName, adminUsername): """ Delete an admin from a hardware profile Raises: AdminNotFound """ session = DbManager().openSession() try: dbAdmin = self._adminsDbHandler.getAdmin(session, adminUsername) dbHardwareProfile = self._hardwareProfilesDbHandler.\ getHardwareProfile(session, hardwareProfileName) if dbAdmin not in dbHardwareProfile.admins: raise AdminNotFound('Admin user [%s] not associated with %s.' % (adminUsername, hardwareProfileName)) dbHardwareProfile.admins.remove(dbAdmin) session.commit() except TortugaException as ex: session.rollback() raise except Exception as ex: session.rollback() self.getLogger().exception('%s' % ex) raise finally: DbManager().closeSession() def updateHardwareProfile(self, hardwareProfileObject): """ Update Hardware Profile Object """ session = DbManager().openSession() try: dbHardwareProfile = self._hardwareProfilesDbHandler.\ getHardwareProfileById(session, hardwareProfileObject.getId()) self.__populateHardwareProfile(session, hardwareProfileObject, dbHardwareProfile) session.commit() except TortugaException as ex: session.rollback() raise except Exception as ex: session.rollback() self.getLogger().exception('%s' % ex) raise finally: DbManager().closeSession() def __getInstallerNode(self, session): return self._nodesDbHandler.getNode(session, ConfigManager().getInstaller()) def __get_provisioning_nics(self, session): return self.__getInstallerNode(session).nics def __get_all_networks(self, session): return self._networksDbHandler.getNetworkList(session) def __get_network_devices(self, session): \ # pylint: disable=no-self-use return session.query(NetworkDevices).all() def __populateHardwareProfile(self, session, hardwareProfile, dbHardwareProfile=None): """ Helper function for creating / updating HardwareProfiles. If 'dbHardwareProfile' is specified, this is an update (vs. add) operation Raises: NicNotFound """ # Preload provisioning nics and networks prov_nics = self.__get_provisioning_nics(session) all_networks = self.__get_all_networks(session) networkdevices = self.__get_network_devices(session) # Validate hw profile if hardwareProfile.getName() is None: raise ConfigurationError('Hardware profile requires name.') if hardwareProfile.getNameFormat() is None: raise ConfigurationError( 'Hardware profile requires name format field.') # Handle the special case of a hardware profile not having an # associated idle software profile (ie. Installer hardware # profile) idleSoftwareProfileId = hardwareProfile.getIdleSoftwareProfileId() \ if hardwareProfile.getIdleSoftwareProfileId else None if dbHardwareProfile is None: dbHardwareProfile = HardwareProfiles() dbHardwareProfile.name = hardwareProfile.getName() dbHardwareProfile.description = hardwareProfile.getDescription() dbHardwareProfile.nameFormat = hardwareProfile.getNameFormat() if hardwareProfile.getInstallType() is None: if hardwareProfile.getLocation() == 'remote': dbHardwareProfile.installType = 'bootstrap' else: raise ConfigurationError( 'Hardware profile must have valid install type.') else: dbHardwareProfile.installType = hardwareProfile.\ getInstallType() if hardwareProfile.getLocation() != 'remote': dbHardwareProfile.kernel = hardwareProfile.getKernel() dbHardwareProfile.kernelParams = hardwareProfile.\ getKernelParams() dbHardwareProfile.initrd = hardwareProfile.getInitrd() dbHardwareProfile.localBootParams = hardwareProfile.\ getLocalBootParams() dbHardwareProfile.softwareOverrideAllowed = hardwareProfile.\ getSoftwareOverrideAllowed() dbHardwareProfile.idleSoftwareProfileId = idleSoftwareProfileId dbHardwareProfile.location = hardwareProfile.getLocation() dbHardwareProfile.hypervisorSoftwareProfileId = hardwareProfile.\ getHypervisorSoftwareProfileId() dbHardwareProfile.maxUnits = hardwareProfile.getMaxUnits() dbHardwareProfile.bcastEnabled = hardwareProfile.getBcastEnabled() dbHardwareProfile.mcastEnabled = hardwareProfile.getMcastEnabled() dbHardwareProfile.cost = hardwareProfile.getCost() # Add resource adapter resourceAdapter = hardwareProfile.getResourceAdapter() if resourceAdapter: dbHardwareProfile.resourceAdapter = self.\ _resourceAdaptersDbHandler.getResourceAdapter( session, resourceAdapter.getName()) dbHardwareProfile.resourceAdapterId = dbHardwareProfile.\ resourceAdapter.id # Add networks networks = [] for network in hardwareProfile.getNetworks(): for prov_network in all_networks: if prov_network.address == network.getAddress(): dbNetwork = prov_network break else: raise NetworkNotFound('Network [%s] does not exist' % (network.getAddress())) # Lookup network device for network_device in networkdevices: if network.getNetworkDevice().getName() == network_device.name: dbNetworkDevice = network_device break else: dbNetworkDevice = NetworkDevices() dbNetworkDevice.name = network.getNetworkDevice().getName() # Now check if we have this one already... for dbHardwareProfileNetwork in dbHardwareProfile.\ hardwareprofilenetworks: if dbHardwareProfileNetwork.\ networkDeviceId == dbNetworkDevice.id and \ dbHardwareProfileNetwork.networkId == dbNetwork.id: break else: dbHardwareProfileNetwork = HardwareProfileNetworks() if dbNetwork.id is not None: dbHardwareProfileNetwork.networkId = dbNetwork.id else: dbHardwareProfileNetwork.network = dbNetwork dbHardwareProfileNetwork.hardwareProfileId = \ dbHardwareProfile.id if dbNetworkDevice.id is not None: dbHardwareProfileNetwork.networkDeviceId = \ dbNetworkDevice.id else: dbHardwareProfileNetwork.networkdevice = dbNetworkDevice dbHardwareProfile.hardwareprofilenetworks.append( dbHardwareProfileNetwork) networks.append(dbHardwareProfileNetwork) # Now remove all old networks for dbNetwork in dbHardwareProfile.hardwareprofilenetworks: for network in networks: if network.networkDeviceId == dbNetwork.networkDeviceId \ and network.networkId == dbNetwork.networkId: # Its a keeper break else: # No match...delete time session.delete(dbNetwork) # Add provisioning Nics if hardwareProfile.getProvisioningNics(): # Only one provisioning nic is possible nic = hardwareProfile.getProvisioningNics()[0] for prov_nic in prov_nics: if nic.getIp() == prov_nic.ip: dbNic = prov_nic break else: raise NicNotFound('Provisioning NIC with IP [%s] not found' % (nic.getIp())) if dbNic not in dbHardwareProfile.nics: dbHardwareProfile.nics.append(dbNic) return dbHardwareProfile def getHypervisorNodes(self, hardwareProfileName): """ Get list of nodes that belong to hypervisorSoftwareProfileId assigned to the given hardware profile name. """ session = DbManager().openSession() try: dbHardwareProfile = self._hardwareProfilesDbHandler.\ getHardwareProfile(session, hardwareProfileName) if not dbHardwareProfile.hypervisor: return TortugaObjectList() return self.getTortugaObjectList( Node, dbHardwareProfile.hypervisor.nodes) except TortugaException as ex: raise except Exception as ex: self.getLogger().exception('%s' % ex) raise finally: DbManager().closeSession() def setProvisioningNic(self, hardwareProfileName, nicId): session = DbManager().openSession() try: dbNic = self._nicsDbHandler.getNicById(session, nicId) dbHardwareProfile = self._hardwareProfilesDbHandler.\ getHardwareProfile(session, hardwareProfileName) dbHardwareProfile.nics.append(dbNic) session.commit() except sqlalchemy.exc.IntegrityError as ex: # Entry for this hwProfile/nicId already exists, ignore self.getLogger().debug( 'setProvisioningNic(): entry already exists for' ' hwProfile=%s, nicId=%d' % (hardwareProfileName, nicId)) except TortugaException as ex: raise except Exception as ex: self.getLogger().exception('%s' % ex) raise finally: DbManager().closeSession() def getProvisioningNicForNetwork(self, network, netmask): """ Raises: NicNotFound """ session = DbManager().openSession() try: installer_node = self.__getInstallerNode(session) nics = [ dbNic for dbNic in installer_node.hardwareprofile.nics if dbNic.network.address == network and dbNic.network.netmask == netmask ] if not nics: raise NicNotFound( 'Unable to find provisioning NIC for network [%s]' ' netmask [%s]' % (network, netmask)) return tortuga.objects.nic.Nic.getFromDbDict(nics[0].__dict__) except TortugaException as ex: self.getLogger().exception('%s' % ex) raise finally: DbManager().closeSession()
class SoftwareProfileDbApi(TortugaDbApi): """ SoftwareProfile DB API class. """ def __init__(self): TortugaDbApi.__init__(self) self._softwareProfilesDbHandler = SoftwareProfilesDbHandler() self._nodesDbHandler = NodesDbHandler() self._globalParametersDbHandler = GlobalParametersDbHandler() self._adminsDbHandler = AdminsDbHandler() self._osDbHandler = OperatingSystemsDbHandler() def getSoftwareProfile(self, name, optionDict=None): """ Get softwareProfile from the db. Returns: softwareProfile Throws: SoftwareProfileNotFound DbError """ session = DbManager().openSession() try: dbSoftwareProfile = self._softwareProfilesDbHandler.\ getSoftwareProfile(session, name) self.loadRelations(dbSoftwareProfile, optionDict or {}) self.loadRelations(dbSoftwareProfile, dict(tags=True)) return SoftwareProfile.getFromDbDict(dbSoftwareProfile.__dict__) except TortugaException as ex: raise except Exception as ex: self.getLogger().exception('%s' % ex) raise finally: DbManager().closeSession() def getSoftwareProfileById(self, softwareProfileId, optionDict=None): """ Get softwareProfile from the db. Returns: softwareProfile Throws: SoftwareProfileNotFound DbError """ session = DbManager().openSession() try: dbSoftwareProfile = self._softwareProfilesDbHandler.\ getSoftwareProfileById(session, softwareProfileId) self.loadRelations(dbSoftwareProfile, optionDict or {}) return SoftwareProfile.getFromDbDict(dbSoftwareProfile.__dict__) except TortugaException as ex: raise except Exception as ex: self.getLogger().exception('%s' % ex) raise finally: DbManager().closeSession() def getSoftwareProfileList(self, tags=None): """ Get list of all available softwareProfiles from the db. Returns: [softwareProfile] Throws: DbError """ session = DbManager().openSession() try: dbSoftwareProfileList = self._softwareProfilesDbHandler.\ getSoftwareProfileList(session, tags=tags) softwareProfileList = TortugaObjectList() for dbSoftwareProfile in dbSoftwareProfileList: self.loadRelations( dbSoftwareProfile, { 'components': True, 'partitions': True, 'hardwareprofiles': True, 'tags': True, }) softwareProfileList.append( SoftwareProfile.getFromDbDict(dbSoftwareProfile.__dict__)) return softwareProfileList except TortugaException as ex: raise except Exception as ex: self.getLogger().exception('%s' % ex) raise finally: DbManager().closeSession() def getIdleSoftwareProfileList(self): """ Get list of all available idle softwareProfiles from the db. Returns: [idle softwareProfile] Throws: DbError """ session = DbManager().openSession() try: dbSoftwareProfileList = self._softwareProfilesDbHandler.\ getIdleSoftwareProfileList(session) return self.getTortugaObjectList(SoftwareProfile, dbSoftwareProfileList) except TortugaException as ex: raise except Exception as ex: self.getLogger().exception('%s' % ex) raise finally: DbManager().closeSession() def setIdleState(self, softwareProfileName, state): """ Set idle state of a software profile Returns: -none- Throws: DbError """ session = DbManager().openSession() try: dbSoftwareProfile = self._softwareProfilesDbHandler.\ getSoftwareProfile(session, softwareProfileName) self.getLogger().debug( 'Setting idle state [%s] on software profile [%s]' % (state, dbSoftwareProfile.name)) dbSoftwareProfile.isIdle = state session.commit() except TortugaException as ex: raise except Exception as ex: self.getLogger().exception('%s' % ex) raise finally: DbManager().closeSession() def addSoftwareProfile(self, softwareProfile, session=None): """ Insert software profile into the db. Raises: SoftwareProfileAlreadyExists DbError """ # Keep local 'session' instance. If 'session' is None, # ensure transaction is committed before returning to the # caller, otherwise the caller is responsible. On exceptions, # the rollback is performed regardless. _session = session if _session is None: _session = DbManager().openSession() try: try: dbSoftwareProfile = self._softwareProfilesDbHandler.\ getSoftwareProfile( _session, softwareProfile.getName()) raise SoftwareProfileAlreadyExists( 'Software profile [%s] already exists' % (softwareProfile)) except SoftwareProfileNotFound as ex: pass dbSoftwareProfile = self.__populateSoftwareProfile( _session, softwareProfile) _session.query(func.max(SoftwareProfiles.id)).one() softwareProfile.setId(dbSoftwareProfile.id) if session is None: _session.commit() self.getLogger().info('Added software profile [%s]' % (dbSoftwareProfile.name)) return dbSoftwareProfile except TortugaException as ex: _session.rollback() raise except Exception as ex: _session.rollback() self.getLogger().exception('%s' % ex) raise finally: if session is None: DbManager().closeSession() def deleteSoftwareProfile(self, name): """ Delete softwareProfile from the db. Returns: None Throws: SoftwareProfileNotFound DbError """ session = DbManager().openSession() try: # This role of this lookup is twofold. One, it validates # the existence of the software profile to be deleted and # second, gets the id for looking up any associated nodes dbSwProfile = self._softwareProfilesDbHandler.\ getSoftwareProfile(session, name) if dbSwProfile.nodes: # The software profile cannot be removed while # associated # nodes exist raise TortugaException('Unable to delete software profile with' ' associated nodes') if dbSwProfile.isIdle: # Ensure this software profile is not associated with # a hardware profile if dbSwProfile.hwprofileswithidle: # This software profile is associated with one # or more hardware profiles raise TortugaException( 'Unable to delete software profile.' ' This software profile is associated' ' with one or more hardware profiles: [%s]' % (' '.join([ hwprofile.name for hwprofile in dbSwProfile.hwprofileswithidle ]))) # Proceed with software profile deletion self.getLogger().debug( 'Marking software profile [%s] for deletion' % (name)) session.delete(dbSwProfile) session.commit() except TortugaException as ex: session.rollback() raise except Exception as ex: session.rollback() self.getLogger().exception('%s' % ex) raise finally: DbManager().closeSession() def getNode(self, name): """ Get node from the db. Returns: node Throws: NodeNotFound DbError """ session = DbManager().openSession() try: return self._nodesDbHandler.getNode(session, name) except TortugaException as ex: raise except Exception as ex: self.getLogger().exception('%s' % ex) raise finally: DbManager().closeSession() def getAllEnabledComponentList(self): """ Get a list of all enabled components in the system Returns: [ components ] Throws: DbError """ session = DbManager().openSession() try: handler = ComponentsDbHandler() dbComponents = handler.getEnabledComponentList(session) return self.getTortugaObjectList(Component, dbComponents) except TortugaException as ex: raise except Exception as ex: self.getLogger().exception('%s' % ex) raise finally: DbManager().closeSession() def getEnabledComponentList(self, name): """ Get a list of enabled components from the db. Returns: node Throws: DbError """ session = DbManager().openSession() try: componentList = TortugaObjectList() for c in self._softwareProfilesDbHandler.getSoftwareProfile( session, name).components: self.loadRelation(c, 'kit') componentList.append(Component.getFromDbDict(c.__dict__)) return componentList except TortugaException as ex: raise except Exception as ex: self.getLogger().exception('%s' % ex) raise finally: DbManager().closeSession() def getNodeList(self, softwareProfile): """ Get list of nodes in 'softwareProfile' Returns: [node] Throws: DbError """ session = DbManager().openSession() try: dbSoftwareProfile = self._softwareProfilesDbHandler.\ getSoftwareProfile(session, softwareProfile) nodeList = TortugaObjectList() for dbNode in dbSoftwareProfile.nodes: self.loadRelation(dbNode, 'hardwareprofile') nodeList.append(Node.getFromDbDict(dbNode.__dict__)) return nodeList except TortugaException as ex: raise except Exception as ex: self.getLogger().exception('%s' % ex) raise finally: DbManager().closeSession() def getNodeListByNodeStateAndSoftwareProfileName(self, nodeState, softwareProfileName): """ Return a list of Node objects based on the specified node state and software profile """ session = DbManager().openSession() try: dbNodes = self._nodesDbHandler.\ getNodeListByNodeStateAndSoftwareProfileName( session, nodeState, softwareProfileName) return self.getTortugaObjectList(Node, dbNodes) except TortugaException as ex: raise except Exception as ex: self.getLogger().exception('%s' % ex) raise finally: DbManager().closeSession() def deleteNode(self, name): """ Delete node from the db. Returns: None Throws: NodeNotFound DbError """ session = DbManager().openSession() try: self._nodesDbHandler.deleteNode(session, name) session.commit() except TortugaException as ex: session.rollback() raise except Exception as ex: session.rollback() self.getLogger().exception('%s' % ex) raise finally: DbManager().closeSession() def getPackageList(self, softwareProfileName): """ Get a list of packages from the db. Returns: [package] Throws: SoftwareProfileNotFound DbError """ session = DbManager().openSession() try: dbPackages = self._softwareProfilesDbHandler.\ getSoftwareProfile( session, softwareProfileName).packages return self.getTortugaObjectList(Package, dbPackages) except TortugaException as ex: raise except Exception as ex: self.getLogger().exception('%s' % ex) raise finally: DbManager().closeSession() def getPartitionList(self, softwareProfileName): """ Get a list of software profile partitions from the db. Returns: [partition] Throws: SoftwareProfileNotFound DbError """ session = DbManager().openSession() try: dbSoftwareProfile = self._softwareProfilesDbHandler.\ getSoftwareProfile(session, softwareProfileName) return self.getTortugaObjectList(Partition, dbSoftwareProfile.partitions) except TortugaException as ex: raise except Exception as ex: self.getLogger().exception('%s' % ex) raise finally: DbManager().closeSession() def addPackage(self, packageName, softwareProfileName): """ Add software profile package. Returns: packageId Throws: PackageAlreadyExists SoftwareProfileNotFound DbError """ session = DbManager().openSession() try: self._softwareProfilesDbHandler.addPackageToSoftwareProfile( session, packageName, softwareProfileName) session.commit() except TortugaException as ex: session.rollback() raise except Exception as ex: session.rollback() self.getLogger().exception('%s' % ex) raise finally: DbManager().closeSession() def deletePackage(self, packageName, softwareProfileName): """ Delete node from the db. Returns: None Throws: PackageNotFound SoftwareProfileNotFound DbError """ session = DbManager().openSession() try: self._softwareProfilesDbHandler.\ deletePackageFromSoftwareProfile( session, packageName, softwareProfileName) session.commit() except TortugaException as ex: session.rollback() raise except Exception as ex: session.rollback() self.getLogger().exception('%s' % ex) raise finally: DbManager().closeSession() def addPartition(self, partitionName, softwareProfileName): """ Add software profile partition. Returns: partitionId Throws: PartitionAlreadyExists SoftwareProfileNotFound DbError """ session = DbManager().openSession() try: self._softwareProfilesDbHandler.\ addPartitionToSoftwareProfile( session, partitionName, softwareProfileName) session.commit() except TortugaException as ex: session.rollback() raise except Exception as ex: session.rollback() self.getLogger().exception('%s' % ex) raise finally: DbManager().closeSession() def deletePartition(self, partitionName, softwareProfileName): """ Delete node from the db. Returns: None Throws: PartitionNotFound SoftwareProfileNotFound DbError """ session = DbManager().openSession() try: self._softwareProfilesDbHandler.\ deletePartitionFromSoftwareProfile( session, partitionName, softwareProfileName) session.commit() except TortugaException as ex: session.rollback() raise except Exception as ex: session.rollback() self.getLogger().exception('%s' % ex) raise finally: DbManager().closeSession() def addUsableHardwareProfileToSoftwareProfile(self, hardwareProfileName, softwareProfileName): """ Add hardwareProfile to softwareProfile Returns: SoftwareUsesHardwareId Throws: HardwareProfileNotFound SoftwareProfileNotFound SoftwareUsesHardwareAlreadyExists DbError """ session = DbManager().openSession() try: swUsesHwId = self._softwareProfilesDbHandler.\ addUsableHardwareProfileToSoftwareProfile( session, hardwareProfileName, softwareProfileName) session.commit() return swUsesHwId except TortugaException as ex: session.rollback() raise except Exception as ex: session.rollback() self.getLogger().exception('%s' % ex) raise finally: DbManager().closeSession() def deleteUsableHardwareProfileFromSoftwareProfile(self, hardwareProfileName, softwareProfileName): """ Delete hardwareProfile from softwareProfile Returns: None Throws: HardwareProfileNotFound SoftwareProfileNotFound SoftwareUsesHardwareNotFound DbError """ session = DbManager().openSession() try: self._softwareProfilesDbHandler.\ deleteUsableHardwareProfileFromSoftwareProfile( session, hardwareProfileName, softwareProfileName) session.commit() except TortugaException as ex: session.rollback() raise except Exception as ex: session.rollback() self.getLogger().exception('%s' % ex) raise finally: DbManager().closeSession() def addAdmin(self, softwareProfileName, adminUsername): """ Add an admin to this software profile """ session = DbManager().openSession() try: dbAdmin = self._adminsDbHandler.getAdmin(session, adminUsername) dbSoftwareProfile = self._softwareProfilesDbHandler.\ getSoftwareProfile(session, softwareProfileName) if dbAdmin not in dbSoftwareProfile.admins: dbSoftwareProfile.admins.append(dbAdmin) else: raise AdminAlreadyExists( 'Admin [%s] already associated with %s' % (adminUsername, softwareProfileName)) session.commit() except TortugaException as ex: session.rollback() raise except Exception as ex: session.rollback() self.getLogger().exception('%s' % ex) raise finally: DbManager().closeSession() def deleteAdmin(self, softwareProfileName, adminUsername): """ Delete an admin from a software profile """ session = DbManager().openSession() try: dbAdmin = self._adminsDbHandler.getAdmin(session, adminUsername) dbSoftwareProfile = self._softwareProfilesDbHandler.\ getSoftwareProfile(session, softwareProfileName) if dbAdmin in dbSoftwareProfile.admins: dbSoftwareProfile.admins.remove(dbAdmin) else: raise AdminNotFound( 'Admin [%s] not associated with software profile' ' [%s]' % (adminUsername, softwareProfileName)) session.commit() except TortugaException as ex: session.rollback() raise except Exception as ex: session.rollback() self.getLogger().exception('%s' % ex) raise finally: DbManager().closeSession() def updateSoftwareProfile(self, softwareProfileObject): """ Update a software profile """ session = DbManager().openSession() try: dbSoftwareProfile = self._softwareProfilesDbHandler.\ getSoftwareProfileById( session, softwareProfileObject.getId()) self.__populateSoftwareProfile(session, softwareProfileObject, dbSoftwareProfile) session.commit() except TortugaException as ex: session.rollback() raise except Exception as ex: session.rollback() self.getLogger().exception('%s' % ex) raise finally: DbManager().closeSession() def __populateSoftwareProfile(self, session, softwareProfile, dbSoftwareProfile=None): """ Helper function for creating/updating dbSoftwareProfile Object """ # Validate object if softwareProfile.getName() is None: raise UpdateSoftwareProfileFailed('Software profile name required') if softwareProfile.getType() is None: raise UpdateSoftwareProfileFailed( 'Software profile must have valid type') osInfo = softwareProfile.getOsInfo() if osInfo is None or osInfo.getName() is None: raise UpdateSoftwareProfileFailed( 'Software profile must have valid operating system') if dbSoftwareProfile is None: dbSoftwareProfile = SoftwareProfiles() dbOs = self._osDbHandler.addOsIfNotFound(session, osInfo) dbSoftwareProfile.name = softwareProfile.getName() dbSoftwareProfile.description = softwareProfile.getDescription() dbSoftwareProfile.kernel = softwareProfile.getKernel() dbSoftwareProfile.kernelParams = softwareProfile.getKernelParams() dbSoftwareProfile.initrd = softwareProfile.getInitrd() dbSoftwareProfile.os = dbOs dbSoftwareProfile.type = softwareProfile.getType() dbSoftwareProfile.minNodes = softwareProfile.getMinNodes() dbSoftwareProfile.isIdle = softwareProfile.getIsIdle() # Add packages packages = {} for package in softwareProfile.getPackages(): # This is a new package dbPackage = Packages() dbPackage.name = package.getName() if packages.get(dbPackage.name) is not None: # Duplicate package ...error raise UpdateSoftwareProfileFailed( 'Duplicate package [%s] found' % (dbPackage.name)) packages[dbPackage.name] = dbPackage # Add partitions partitions = {} for partition in softwareProfile.getPartitions(): # This is a new partition dbPartition = Partitions() dbPartition.name = partition.getName() dbPartition.device = partition.getDevice() dbPartition.mountPoint = partition.getMountPoint() dbPartition.fsType = partition.getFsType() dbPartition.size = partition.getSize() dbPartition.options = partition.getOptions() dbPartition.preserve = partition.getPreserve() dbPartition.bootLoader = partition.getBootLoader() dbPartition.diskSize = partition.getDiskSize() dbPartition.directAttachment = partition.getDirectAttachment() dbPartition.indirectAttachment = partition.\ getIndirectAttachment() dbPartition.sanVolume = partition.getSanVolume() if not dbPartition.name: raise InvalidPartitionScheme( 'Invalid partition in software profile:' ' missing or empty name') if not dbPartition.device: raise InvalidPartitionScheme( 'Invalid partition in software profile:' ' missing or empty device') if not dbPartition.fsType: raise InvalidPartitionScheme( 'Invalid partition [%s/%s] in software profile:' ' missing or empty fsType' % (dbPartition.name, dbPartition.device)) if dbPartition.size is None: raise InvalidPartitionScheme( 'Invalid partition [%s/%s] in software profile:' ' missing size' % (dbPartition.name, dbPartition.device)) if partitions.get( (dbPartition.name, dbPartition.device)) is not None: # Duplicate partition ...error raise UpdateSoftwareProfileFailed( 'Duplicate partition [%s/%s] found' % (dbPartition.name, dbPartition.device)) try: int(dbPartition.size) except ValueError: raise InvalidPartitionScheme( 'Invalid partition [%s/%s] in software profile:' ' non-integer size' % (dbPartition.name, dbPartition.device)) try: if dbPartition.diskSize is not None: int(dbPartition.diskSize) except ValueError: raise InvalidPartitionScheme( 'Invalid partition [%s/%s] in software profile:' ' non-integer disk size' % (dbPartition.name, dbPartition.device)) bGrow = partition.getGrow() if bGrow is not None: dbPartition.grow = bGrow maxSize = partition.getMaxSize() if maxSize is not None: dbPartition.maxSize = maxSize partitions[(dbPartition.name, dbPartition.device)] = \ dbPartition # Delete out the old ones dbSoftwareProfile.partitions = [] dbSoftwareProfile.packages = [] session.flush() dbSoftwareProfile.partitions = list(partitions.values()) dbSoftwareProfile.packages = list(packages.values()) session.add(dbSoftwareProfile) session.flush() return dbSoftwareProfile def copySoftwareProfile(self, srcSoftwareProfileName, dstSoftwareProfileName): session = DbManager().openSession() srcSoftwareProfile = self.getSoftwareProfile(srcSoftwareProfileName, { 'partitions': True, 'packages': True, 'components': True, }) dstSoftwareProfile = self.getSoftwareProfile(srcSoftwareProfileName) dstSoftwareProfile.setName(dstSoftwareProfileName) newDescription = 'Copy of %s' % (dstSoftwareProfile.getDescription()) dstSoftwareProfile.setDescription(newDescription) # partitions dstSoftwareProfile.setPartitions(srcSoftwareProfile.getPartitions()) # packages dstSoftwareProfile.setPackages(srcSoftwareProfile.getPackages()) # Finally add the software profile dstSoftwareProfile = self.addSoftwareProfile(dstSoftwareProfile, session) # Enable components separately srcCompList = self.getEnabledComponentList(srcSoftwareProfileName) for srcComp in srcCompList: if srcComp.getKit().getIsOs() or srcComp.getName() == 'core': self._softwareProfilesDbHandler.\ addComponentToSoftwareProfileEx( session, srcComp.getId(), dstSoftwareProfile) session.commit() def getUsableNodes(self, name): """ Return list of nodes with same software/hardware profile mapping as the specified software profile. """ session = DbManager().openSession() try: dbSoftwareProfile = self._softwareProfilesDbHandler.\ getSoftwareProfile(session, name) nodes = [ dbNode for dbHardwareProfile in dbSoftwareProfile.hardwareprofiles for dbNode in dbHardwareProfile.nodes ] return self.getTortugaObjectList(Node, nodes) except TortugaException as ex: raise except Exception as ex: self.getLogger().exception('%s' % ex) raise finally: DbManager().closeSession()