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)
예제 #2
0
파일: default.py 프로젝트: joedborg/tortuga
    def __init__(self, addHostSession: Optional[str] = None) -> None:
        super().__init__(addHostSession=addHostSession)

        self._bhm = \
            osUtility.getOsObjectFactory().getOsBootHostManager(self._cm)

        self.looping = False
예제 #3
0
    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
예제 #4
0
    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
예제 #5
0
    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)
예제 #6
0
    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()
예제 #7
0
    def __init__(self):
        super(SyncManager, self).__init__()

        self._isUpdateScheduled = False
        self._isUpdateRunning = False
        self._sudoCmd = \
            osUtility.getOsObjectFactory().getOsSysManager().getSudoCommand()
        self._cm = ConfigManager()
예제 #8
0
파일: component.py 프로젝트: ffxf/tortuga
 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'
예제 #9
0
    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()
예제 #10
0
 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
예제 #11
0
    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
예제 #12
0
    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)
예제 #13
0
    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
예제 #14
0
    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)
예제 #15
0
    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
예제 #16
0
파일: manager.py 프로젝트: dtougas/tortuga
    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())
예제 #17
0
    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))
예제 #18
0
    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()
예제 #19
0
    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)
예제 #20
0
파일: default.py 프로젝트: ilumb/tortuga
    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])
예제 #21
0
    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')
예제 #22
0
    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'])
예제 #23
0
    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')
예제 #24
0
파일: default.py 프로젝트: ilumb/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()
예제 #25
0
    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
예제 #26
0
    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()
예제 #27
0
파일: default.py 프로젝트: ilumb/tortuga
    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
예제 #28
0
    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())
예제 #29
0
    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={})
예제 #30
0
    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()))