def _install_puppet_module(self, module_name):
        """
        Installs a puppet module from the kit puppet_modules directory.

        :param module_name: The name of the puppet module to install.

        """
        files = glob.glob(
            os.path.join(self.kit_installer.puppet_modules_path,
                         '{}-*.tar.gz'.format(module_name)))
        if not files:
            logger.error('Unable to find Puppet module {}'.format(module_name))
            raise ConfigurationError('Missing Puppet module for Base kit')

        logger.info('Installing Puppet module {}'.format(module_name))

        module_path = files[0]
        if not os.path.exists(module_path):
            raise ConfigurationError(
                'File does not exist: {}'.format(module_path))

        cmd = ('/opt/puppetlabs/bin/puppet module install --color false'
               ' --force {}'.format(module_path))

        tortugaSubprocess.executeCommand(cmd)
Exemple #2
0
    def run_script(self, action, software_profiles, nodes=None):
        script_path = self._get_host_action_hook_script()

        if script_path is None:
            return

        cmd = '{} --action {}'.format(script_path, action)

        if software_profiles:
            cmd += ' --software-profiles {}'.format(
                ','.join(software_profiles))

        tmp_file_to_delete = None

        if nodes:
            fh, tmp_file_name = self._get_tmp_file()
            os.write(fh, '\n'.join(nodes))
            os.close(fh)
            cmd += ' --nodes {}'.format(tmp_file_name)
            tmp_file_to_delete = tmp_file_name

        tortugaSubprocess.executeCommand(cmd)

        if tmp_file_to_delete:
            os.unlink(tmp_file_to_delete)
Exemple #3
0
    def _update_python_repo(self, pkg_dir: str):
        """
        Updates the Tortuga Python repo with packages from the kit.

        :param pkg_dir: the source directory from which the packages will
                        be copied

        """
        #
        # Copy the files from the pkg_dir to the Tortuga repo
        #
        whl_path = os.path.join(pkg_dir, '*.whl')
        repo_path = os.path.join(self.config_manager.getTortugaIntWebRoot(),
                                 'python-tortuga')

        cmd = 'rsync -a {} {}'.format(whl_path, repo_path)

        logger.debug(cmd)

        executeCommand(cmd)

        #
        # Re-build the package index
        #
        dir2pi = os.path.join(self.config_manager.getBinDir(), 'dir2pi')

        cmd = '{} {}'.format(dir2pi, repo_path)

        logger.debug(cmd)

        executeCommand(cmd)
Exemple #4
0
    def copy_clonezilla_files(self, dst_dir):
        tmp_dir = self.extract_clonezilla_files()

        if not os.path.exists(dst_dir):
            logger.info('Creating destination directory: {}'.format(dst_dir))
            os.makedirs(dst_dir)

        logger.info('Copying Clonezilla files to {}'.format(dst_dir))

        # Copy files into place
        file_pairs = [(os.path.join(tmp_dir, 'vmlinuz'),
                       os.path.join(dst_dir, 'vmlinuz-cz')),
                      (os.path.join(tmp_dir, 'initrd.img'),
                       os.path.join(dst_dir, 'initrd-cz.img')),
                      (os.path.join(tmp_dir, 'filesystem.squashfs'),
                       os.path.join(dst_dir, 'filesystem.squashfs'))]

        clonezilla_files_path = os.path.join(
            self.kit_installer.config_manager.getRoot(),
            'var/lib/clonezilla_files.txt')
        with open(clonezilla_files_path, 'w') as fp:
            for tmp_src_file, tmp_dst_file in file_pairs:
                shutil.copyfile(tmp_src_file, tmp_dst_file)
                #
                # Add entry into file catalog for clean uninstallation later
                #
                fp.write(tmp_dst_file + '\n')
        #
        # Cleanup the temporary directory
        #
        tortugaSubprocess.executeCommand('rm -rf {}'.format(tmp_dir))
Exemple #5
0
    def action_post_install(self, *args, **kwargs):
        self.configure()

        sshdir = '/root/.ssh'
        privkey = os.path.join(sshdir, 'id_rsa')
        pubkey = os.path.join(sshdir, 'id_rsa.pub')
        authkeys = os.path.join(sshdir, 'authorized_keys')

        if not os.path.exists(sshdir):
            os.makedirs(sshdir, 0o700)

        #
        # Create public key if key not found
        #
        if not os.path.exists(pubkey):
            #
            # RSA key, 2048 bits in size, /root/.ssh/id_rsa, no passphrase
            #
            tortugaSubprocess.executeCommand(
                'ssh-keygen -t rsa -b 2048 -f {} -N ""'.format(privkey))

        #
        # copy public key to authorized_keys
        #
        if not os.path.exists(authkeys):
            shutil.copy(pubkey, authkeys)
Exemple #6
0
    def action_post_uninstall(self, *args, **kwargs):
        super().action_post_install(*args, **kwargs)

        #
        # Remove symlink to modules
        #
        tortugaSubprocess.executeCommand(
            '/bin/rm -f {}/lib/tortuga/vmwareUtil'.format(self.getRoot()))

        #
        # Delete the hardware and software profiles we created in
        # post_install
        #
        hardware_profile_api = getHardwareProfileApi()
        software_profile_api = getSoftwareProfileApi()

        for hwp_name in DEFAULT_HARDWARE_PROFILE_LIST:
            try:
                hardware_profile_api.deleteHardwareProfile(hwp_name)
            except HardwareProfileNotFound:
                #
                # We can safely ignore this error
                #
                pass

        for swp_name in DEFAULT_SOFTWARE_PROFILE_LIST:
            try:
                software_profile_api.deleteSoftwareProfile(swp_name)
            except SoftwareProfileNotFound:
                #
                # We can safely ignore this error
                #
                pass
Exemple #7
0
    def extract_clonezilla_files(self):
        """
        Extracts requisite files from Clonezilla Live zip archive

        Returns:
            <path to temporary directory containing files>

        Raises:
            InvalidActionRequest
            CommandFailed

        """
        if not os.path.exists(SRC_CLONEZILLA_LIVE_ZIP):
            raise invalidActionRequest.InvalidActionRequest(
                'Clonezilla Live zip archive not found: {}'.format(
                    SRC_CLONEZILLA_LIVE_ZIP))

        tmp_dir = tempfile.mkdtemp()

        logger.info('Extracting Clonezilla Live ZIP to {}'.format(tmp_dir))

        reqd_files = [
            'live/vmlinuz', 'live/initrd.img', 'live/filesystem.squashfs'
        ]

        cmd = 'unzip -j -o {} -d {} {}'.format(SRC_CLONEZILLA_LIVE_ZIP,
                                               tmp_dir, ' '.join(reqd_files))

        tortugaSubprocess.executeCommand(cmd)

        return tmp_dir
Exemple #8
0
    def _install_puppet_module(self, module_name):
        """
        Installs a puppet module from the kit puppet_modules directory.

        :param module_name: The name of the puppet module to install.

        """
        files = glob.glob(
            os.path.join(
                self.kit_installer.puppet_modules_path,
                '{}-*.tar.gz'.format(module_name)
            )
        )
        if not files:
            errmsg = f'Unable to find Puppet module {module_name}'

            logger.error(errmsg)

            raise ConfigurationError(errmsg)

        logger.info('Installing Puppet module {}'.format(module_name))

        cmd = ('/opt/puppetlabs/bin/puppet module install --color false'
               ' {}'.format(files[0]))

        tortugaSubprocess.executeCommand(cmd)
Exemple #9
0
    def reload(cls, force=False):
        reload_file_path = os.path.join(cls.hostsdir, cls.reload_flag)
        if not force and not os.path.exists(reload_file_path):
            logger.debug('Reload flag not found, skipping dnsmasq reload')

        cmd = 'systemctl kill -s HUP dnsmasq.service'
        tortugaSubprocess.executeCommand(cmd)
        logger.debug('dnsmasq service reloaded')

        if os.path.exists(reload_file_path):
            os.remove(reload_file_path)
Exemple #10
0
    def _updateNetworkConfig(self, session: Session, dbNode: Node) -> bool:
        """
        Returns True if configuration files were changed.
        """

        bUpdated = False

        if self._componentEnabled(session, dbNode.softwareprofile, 'dhcpd'):
            print('Updating dhcpd configuration...')

            if dbNode.hardwareprofile.nics:
                print('Restarting dhcpd...')

                tortugaSubprocess.executeCommand('genconfig dhcpd')

                tortugaSubprocess.executeCommand('service dhcpd restart')
            else:
                print('Last provisioning NIC removed. Stopping dhcpd...')

                tortugaSubprocess.executeCommand('service dhcpd stop')

            bUpdated = True

        if self._componentEnabled(session, dbNode.softwareprofile, 'dns'):
            print('Updating DNS configuration...')

            tortugaSubprocess.executeCommand('genconfig dns')

            bUpdated = True

        return bUpdated
Exemple #11
0
    def _run_command(self, command):
        """
        Runs an external command.

        :param command:        string the command to run
        :raises KitBuildError: if the command failed

        """
        logger.info('    {}'.format(command))

        try:
            executeCommand(command)
        except CommandFailed as e:
            raise KitBuildError(str(e))
Exemple #12
0
    def execute(self, cmd, echo: bool = False):         \
            # pylint: disable=unused-argument
        """
        Raises:
            TortugaException
        """

        return tortugaSubprocess.executeCommand(cmd)
Exemple #13
0
    def create(self, relativePath, cacheDir=None):
        repoPath = self.__getRepoPath(relativePath)

        if not os.path.exists(repoPath):
            os.makedirs(repoPath)

        # Make sure nothing happens here for non-native os.
        if not osUtility.isNativeOsName(self.getOsInfo()):
            return

        # Build 'createrepo' command-line
        cmd = 'createrepo -q'
        if cacheDir is not None:
            cmd += ' --cachedir %s' % (cacheDir)
        cmd += ' %s' % (repoPath)

        tortugaSubprocess.executeCommand(cmd)
Exemple #14
0
    def pre_init_db(self):
        # If using 'mysql' as the database backend, we need to install the
        # puppetlabs-mysql Puppet module prior to bootstrapping. This used to
        # be done in 'install-tortuga.sh'

        if self._settings['database']['engine'] == 'mysql':
            logmsg = 'Installing \'puppetlabs-mysql\' module'

            self._logger.debug(logmsg)

            sys.stdout.write('\n' + logmsg + '... ')
            sys.stdout.flush()

            cmd = ('/opt/puppetlabs/bin/puppet module install'
                   ' --color false puppetlabs-mysql')
            tortugaSubprocess.executeCommand(cmd)

            sys.stdout.write('done.\n')
Exemple #15
0
    def cleanup(self):
        files_to_delete = []

        clonezilla_files_path = os.path.join(
            self.kit_installer.config_manager.getRoot(),
            'var/lib/clonezilla_files.txt')
        if os.path.exists(clonezilla_files_path):
            with open(
                    os.path.join(self.kit_installer.config_manager.getRoot(),
                                 'lib/clonezilla_files.txt')) as fp:
                for line in fp.readlines():
                    files_to_delete.append(line.rstrip())

        for tmp_file_name in files_to_delete:
            tortugaSubprocess.executeCommand('rm -f {}'.format(tmp_file_name))

        tortugaSubprocess.executeCommand(
            'rm -f %s'.format(clonezilla_files_path))
Exemple #16
0
    def execute(self, cmd, echo=False):
        """
        Raises:
            TortugaException
        """

        if echo:
            return tortugaSubprocess.executeCommandAndLogToStdOut(cmd)
        else:
            return tortugaSubprocess.executeCommand(cmd)
Exemple #17
0
    def installPuppetModule(self, modulePath):
        """
        Install "standard" Puppet module using "puppet module install --force"

        Raises:
            ConfigurationError
        """

        if not os.path.exists(modulePath):
            errmsg = ('Error: unable to install puppet module [%s].'
                      ' Module does not exist' % (modulePath))

            self.getLogger().error(errmsg)

            raise ConfigurationError(errmsg)

        cmd = ('/opt/puppetlabs/bin/puppet module install --color false'
               ' --force %s' % (modulePath))

        tortugaSubprocess.executeCommand(cmd)
    def pre_init_db(self):
        # If using 'mysql' as the database backend, we need to install the
        # puppetlabs-mysql Puppet module prior to bootstrapping. This used
        # to be done in 'install-tortuga.sh'

        if self._settings['database']['engine'] == 'mysql':
            print('\nUsing MySQL as backing database.')

            puppet_module = 'puppetlabs-mysql'

            logmsg = f'Installing \'{puppet_module}\' module'

            self._logger.debug(logmsg)

            print(f'\n{logmsg}...', end='')

            cmd = ('/opt/puppetlabs/bin/puppet module install'
                   f' --color false {puppet_module}')
            tortugaSubprocess.executeCommand(cmd)

            print('done.')
Exemple #19
0
    def action_delete_host(self, hardware_profile_name, software_profile_name,
                           nodes, *args, **kwargs):
        for node in nodes:
            short_host_name = node.getName().split('.')[0]

            #
            # Remove ssh keymapping for node
            #
            logger.debug('Removing ssh public key for node {}'.format(node))

            #
            # Remove fullname
            #
            tortugaSubprocess.executeCommand(
                'ssh-keygen -R {} >/dev/null 2>&1 ||:'.format(node))

            # Remove short name
            tortugaSubprocess.executeCommand(
                'ssh-keygen -R {} >/dev/null 2>&1 ||:'.format(short_host_name))

            #
            # Remove nic entries
            #
            for nic in node.getNics():
                tortugaSubprocess.executeCommand(
                    'ssh-keygen -R {} >/dev/null 2>&1 ||:'.format(nic.getIp()))

        self.configure()
Exemple #20
0
    def _get_navops_token(self) -> str:
        cmd = '{} token'.format(self.navops_cli)

        try:
            p = executeCommand(cmd)
        except Exception as ex:
            logger.info(str(ex))
            raise ConfigException(str(ex))

        if p.getExitStatus() != 0:
            raise ConfigException(p.getStdErr())

        return p.getStdOut().decode()
Exemple #21
0
    def runCommand(self):
        self.parseArgs()

        self._loadDNSConfig()

        # Remove remnants
        oldDnsZone = self._getOldDnsZone()

        if not self.getArgs().zone:
            # Output current DNS zone and exit
            print(f'{oldDnsZone}')

            sys.exit(0)

        dnsZone = self.getArgs().zone.lower()

        if oldDnsZone == dnsZone and not self.getArgs().bForce:
            # Nothing changed. Nothing to do!
            sys.exit(0)

        # Update database
        self._updateDatabase(dnsZone)

        # Update dns-component.conf
        self._updateDnsComponentConf(dnsZone)

        # Update Puppet extdata file
        self._updatePuppetExtData(dnsZone)

        if 'type' in self.dns_conf and self.dns_conf['type'] == 'named':
            oldZoneFileName = '/var/named/%s.zone' % (oldDnsZone.lower())

            if os.path.exists(oldZoneFileName):
                # Attempt to remove old named configuration
                os.unlink(oldZoneFileName)

        bDnsComponentEnabled = self.isDnsComponentEnabled()

        # TODO: update (genconfig dns)
        if bDnsComponentEnabled:
            tortugaSubprocess.executeCommand('genconfig dns')

        # TODO: schedule puppet update
        tortugaSubprocess.executeCommand(
            'schedule-update "DNS zone changed from \"%s\" to \"%s\""' %
            (oldDnsZone, dnsZone))

        if bDnsComponentEnabled and 'type' in self.dns_conf:
            if self.dns_conf['type'] == 'named':
                cmd = 'service named restart'
            else:
                cmd = 'service dnsmasq restart'

            tortugaSubprocess.executeCommand(cmd)
Exemple #22
0
    def getInitiatorName(self, target):
        '''Gets the iSCSI Initiator name of the specified target host/IP'''

        cmd = 'ssh root@%s cat /etc/iscsi/initiatorname.iscsi' % (target)

        stdout = executeCommand(cmd).getStdOut()

        pattern = re.compile(r'^\s*InitiatorName=["\']?([^"\' ]+)[^\'"]?',
                             re.M)

        match = pattern.search(stdout)

        if not match:
            raise InternalError('Target [%s] unknown iSCSI initiator name' %
                                (target))

        initiator = match.group(1).strip()

        self.getLogger().debug('Target [%s] iSCSI initiator name: [%s]' %
                               (target, initiator))

        return initiator
Exemple #23
0
    def ping_all_nodes(self) -> List[NodePingReply]:
        p = executeCommand(self._command)

        replies: List[NodePingReply] = []
        for line in p.getStdOut().decode().splitlines():
            #
            # A typical ping response from the mco ping command looks like
            # this:
            #
            # execd-01-hioqz    time=52.88 ms
            #
            parts = re.split(r"\s+", line.strip())
            if len(parts) != 3:
                continue
            if not parts[1].startswith("time="):
                continue
            replies.append(
                NodePingReply(name=parts[0],
                              reply=True,
                              response_time=float(parts[1].replace(
                                  "time=", ""))))

        return replies
Exemple #24
0
    def _updateNetworkConfig(self, session, dbInstallerNode):
        """
        Returns True if configuration files were changed.
        """

        bUpdated = False

        bin_dir = os.path.dirname(sys.argv[0])

        # Update dhcpd configuration
        if self._componentEnabled(session, dbInstallerNode.softwareprofile,
                                  'dhcpd'):
            print('Updating dhcpd configuration...')

            tortugaSubprocess.executeCommand('{} {}'.format(
                os.path.join(bin_dir, 'genconfig'), 'dhcpd'))

            tortugaSubprocess.executeCommand('service dhcpd restart')

            bUpdated = True

        # Update DNS configuration after adding a provisioning NIC
        if self._componentEnabled(session, dbInstallerNode.softwareprofile,
                                  'dns'):
            print('Updating DNS configuration...')

            tortugaSubprocess.executeCommand('{} {}'.format(
                os.path.join(bin_dir, 'genconfig'), 'dns'))

            # Because the entire configuration changes between before and
            # after there was a provisioning NIC installed, it is necessary
            # to restart the server. An 'rndc reload' will *NOT* suffice.
            tortugaSubprocess.executeCommandAndIgnoreFailure(
                'service named restart')

            bUpdated = True

        return bUpdated
    def cleanup(self):
        # If possible, remove any package sources we added
        self._removePackageSources()

        osUtility.removeFile(self._lockFilePath)

        osUtility.removeFile(self._cm.getProfileNiiFile())

        # Turn off the webservice daemon
        self._disableTortugaws()

        # Restore resolv.conf
        if osUtility.haveBackupFile('/etc/resolv.conf'):
            osUtility.restoreFile('/etc/resolv.conf')

        # Drop database
        dbManager = self._osObjectFactory.getOsApplicationManager(
            self._settings['database']['engine'])

        try:
            dbSchema = self._cm.getDbSchema()

            self.out('  * Removing database [%s]\n' % (dbSchema))

            dbManager.destroyDb(dbSchema)
        except Exception as ex:   # pylint: disable=broad-except
            self._logger.exception(
                'Could not destroy existing db: {}'.format(ex))

        # Remove DB password file
        osUtility.removeFile(self._cm.getDbPasswordFile())

        # Remove CFM secret
        cfmSecretFile = self._cm.getCfmSecretFile()
        if os.path.exists(cfmSecretFile):
            osUtility.removeFile(self._cm.getCfmSecretFile())

        # Generic cleanup
        osUtility.removeLink('/etc/tortuga-release')

        # Cleanup or remove depot directory
        errmsg = 'Removing contents of [%s]' % (self._settings['depotpath'])

        self._logger.debug(errmsg)

        if self._depotCreated:
            self.out('  * %s\n' % (errmsg))

            osUtility.removeDir(self._settings['depotpath'])
        else:
            if self._settings['depotpath']:
                self.out('  * %s\n' % (errmsg))

                tortugaSubprocess.executeCommand(
                    'rm -rf %s/*' % (self._settings['depotpath']))

                self.out('\n')

        if not self._forceCleaning:
            self.out('Consult log(s) for further details.\n')

            self._logger.error('Installation failed')
    def prepDepot(self):
        depotpath = None

        if not self._settings['defaults']:
            self.out(
                _('Tortuga requires a directory for storage of OS'
                  ' distribution media and other files required for'
                  ' node provisioning.\n\n'))

        while not depotpath:
            if self._settings['defaults']:
                response = self._settings['depotpath']
            else:
                try:
                    response = input(
                        'Please enter a depot path (Ctrl-C to interrupt)'
                        ' [%s]: ' % (self._settings['depotpath']))
                except KeyboardInterrupt:
                    raise InvalidArgument(_('Aborted by user.'))

                if not response:
                    response = self._settings['depotpath']

            if not response.startswith('/'):
                errmsg = 'Depot path must be fully-qualified'

                if not self._settings['defaults']:
                    self.out('Error: %s\n' % (errmsg))

                    continue

                raise InvalidArgument(errmsg)

            if response == '/':
                errmsg = 'Depot path cannot be system root directory'

                if not self._settings['defaults']:
                    self.out(_('Error: %s\n' % (errmsg)))

                    continue

                raise InvalidArgument(errmsg)

            if os.path.exists(response):
                if not self._settings['force']:
                    if not self._settings['defaults']:
                        self.out(
                            _('Directory [%s] already exists. Do you wish to'
                              ' remove it [N/y]? ') % (response))

                        remove_response = input('')

                        if not remove_response or \
                                remove_response[0].lower() == 'n':
                            continue_response = input(
                                'Do you wish to continue [N/y]? ')

                            if continue_response and \
                                    continue_response[0].lower() == 'y':
                                continue

                            raise InvalidArgument(_('Aborted by user.'))
                    else:
                        raise InvalidArgument(
                            _('Existing depot directory [%s] will not be'
                              ' removed.') % (response))
                else:
                    self.out(
                        _('\nRemoving existing depot directory [%s]... ') % (
                            response))

                    depotpath = response

                    tortugaSubprocess.executeCommand(
                        'rm -rf %s/*' % (depotpath))

                    self.out(_('done.\n'))
            else:
                depotpath = response

        self._settings['depotpath'] = depotpath

        self._cm.setDepotDir(self._settings['depotpath'])
    def __process(self):
        self._logger.debug('[%s] Begin processing timer' %
                           (self.__class__.__name__))

        while True:
            qSize = self._receiveQ.qsize()

            self._logger.debug('[%s] Current receive Q size: %s' %
                               (self.__class__.__name__, qSize))

            if qSize == 0:
                break

            applicationName, applicationData = self._receiveQ.get()

            self._logger.debug('[%s] Processing data for [%s]' %
                               (self.__class__.__name__, applicationName))

            monitorXmlDoc = self.__parseMonitorData(applicationData)

            for ruleId in self._receiveRuleDict.keys():
                rule = self._receiveRuleDict.get(ruleId)

                # Rule might have been cancelled before we use it.
                if not rule:
                    continue

                # Check if this is appropriate for the data.
                if rule.getApplicationName() != applicationName:
                    continue

                self._logger.debug('[%s] Processing data using rule [%s]' %
                                   (self.__class__.__name__, ruleId))

                rule.ruleInvoked()

                appMonitor = rule.getApplicationMonitor()

                actionCmd = appMonitor.getActionCommand()

                self._logger.debug('[%s] Action command: [%s]' %
                                   (self.__class__.__name__, actionCmd))

                try:
                    xPathReplacementDict = self.__evaluateXPathVariables(
                        monitorXmlDoc, rule.getXPathVariableList())

                    invokeAction = self.__evaluateConditions(
                        rule, monitorXmlDoc, xPathReplacementDict)

                    if invokeAction:
                        try:
                            actionCmd = self.__replaceXPathVariables(
                                actionCmd, xPathReplacementDict)

                            self._logger.debug(
                                '[%s] About to invoke: [%s]' %
                                (self.__class__.__name__, actionCmd))

                            tortugaSubprocess.executeCommand(
                                'source %s/tortuga.sh && ' %
                                (self._cm.getEtcDir()) + actionCmd)

                            appMonitor.actionInvocationSucceeded()

                            self._logger.debug(
                                '[%s] Done with command: [%s]' %
                                (self.__class__.__name__, actionCmd))

                            maxActionInvocations = \
                                appMonitor.getMaxActionInvocations()

                            successfulActionInvocations = \
                                appMonitor.getSuccessfulActionInvocations()

                            if maxActionInvocations:
                                if int(maxActionInvocations) <= \
                                        successfulActionInvocations:
                                    # Rule must be disabled.
                                    self._logger.debug(
                                        '[%s] Max. number of successful'
                                        ' invocations (%s) reached for'
                                        ' rule [%s]' %
                                        (self.__class__.__name__,
                                         maxActionInvocations, ruleId))

                                    self.disableRule(rule.getApplicationName(),
                                                     rule.getName())
                        except Exception as ex:
                            appMonitor.actionInvocationFailed()
                    else:
                        self._logger.debug(
                            '[%s] Will skip action: [%s]' %
                            (self.__class__.__name__, actionCmd))
                except TortugaException as ex:
                    self._logger.error('[%s] %s' %
                                       (self.__class__.__name__, ex))

            self._logger.debug('[%s] No more rules appropriate for [%s]' %
                               (self.__class__.__name__, applicationName))

        # No more data to process, exit timer.
        self._logger.debug('[%s] No more data to process' %
                           (self.__class__.__name__))

        self.__cancelProcessingTimer()
    def __execute(self, rule):
        ruleId = self.__getRuleId(rule.getApplicationName(), rule.getName())

        self._logger.debug('[%s] Begin execution for [%s]' %
                           (self.__class__.__name__, ruleId))

        rule.ruleInvoked()

        appMonitor = rule.getApplicationMonitor()

        queryCmd = appMonitor.getQueryCommand()

        self._logger.debug('[%s] Query command: [%s]' %
                           (self.__class__.__name__, queryCmd))

        actionCmd = appMonitor.getActionCommand()

        self._logger.debug('[%s] Action command: [%s]' %
                           (self.__class__.__name__, actionCmd))

        xPathReplacementDict = {}

        try:
            invokeAction = True
            queryStdOut = None

            if queryCmd:
                self._logger.debug('[%s] About to invoke: [%s]' %
                                   (self.__class__.__name__, queryCmd))

                try:
                    p = tortugaSubprocess.executeCommand(
                        'source %s/tortuga.sh && ' % (self._cm.getEtcDir()) +
                        queryCmd)

                    queryStdOut = p.getStdOut()

                    appMonitor.queryInvocationSucceeded()
                except Exception as ex:
                    appMonitor.queryInvocationFailed()
                    raise

                monitorXmlDoc = self.__parseMonitorData(queryStdOut)

                xPathReplacementDict = self.__evaluateXPathVariables(
                    monitorXmlDoc, rule.getXPathVariableList())

                invokeAction = self.__evaluateConditions(
                    rule, monitorXmlDoc, xPathReplacementDict)

            if invokeAction:
                try:
                    actionCmd = self.__replaceXPathVariables(
                        actionCmd, xPathReplacementDict)

                    self._logger.debug('[%s] About to invoke: [%s]' %
                                       (self.__class__.__name__, actionCmd))

                    p = tortugaSubprocess.executeCommand(
                        'source %s/tortuga.sh && ' % (self._cm.getEtcDir()) +
                        actionCmd)

                    appMonitor.actionInvocationSucceeded()

                    self._logger.debug('[%s] Done with command: [%s]' %
                                       (self.__class__.__name__, actionCmd))
                except Exception as ex:
                    appMonitor.actionInvocationFailed()
                    raise
            else:
                self._logger.debug('[%s] Will skip action: [%s]' %
                                   (self.__class__.__name__, actionCmd))
        except TortugaException as ex:
            self._logger.error('[%s] %s' % (self.__class__.__name__, ex))

        if self.hasRule(ruleId):
            # Check if we need to stop invoking this rule.
            maxActionInvocations = appMonitor.getMaxActionInvocations()

            successfulActionInvocations = \
                appMonitor.getSuccessfulActionInvocations()

            if maxActionInvocations:
                if int(maxActionInvocations) <= successfulActionInvocations:
                    # Rule must be disabled.
                    self._logger.debug(
                        '[%s] Max. number of successful invocations (%s)'
                        ' reached for rule [%s]' %
                        (self.__class__.__name__, maxActionInvocations,
                         ruleId))

                    self.disableRule(rule.getApplicationName(), rule.getName())
Exemple #29
0
 def action_post_uninstall(self, *args, **kwargs):
     tortugaSubprocess.executeCommand(
         'rm -rf /var/cache/tortuga/pkgs/ganglia')
Exemple #30
0
 def __scheduleUpdate(self):
     tortugaSubprocess.executeCommand(
         os.path.join(self._cm.getRoot(), 'bin/schedule-update'))