Beispiel #1
0
    def __loadResources(self, _sConfigFile, _bBootstrap = False, _bAutostart = False):
        """
        Load resources configuration from file

        @param str  _sConfigFile  Configuration file (path)
        @param bool _bBootstrap   Bootstrap (host startup) configuration
        @param bool _bAutostart   Automatically start bootstrap resources

        @return list  Empty if resource is successfully started, (ordered) error messages otherwise
        """
        if self._iVerbose: self._DEBUG('Loading resources configuration from file (%s)' % _sConfigFile)
        lsErrors = list()

        try:

            # Load configuration from file
            with open(_sConfigFile, 'r') as oFile:
                oConfig = configparser.RawConfigParser()
                oConfig.optionxform = lambda sOption: sOption  # do not lowercase option (key) name
                oConfig.read_file(oFile, _sConfigFile)

            # Loop through sections/resources (IDs)
            for sId in oConfig.sections():
                if sId == 'KiSC': continue
                dsConfig = {tOption[0]: tOption[1] for tOption in oConfig.items(sId)}
                if 'TYPE' not in dsConfig:
                    lsErrors.append('<%s> [%s] Invalid configuration section; missing "TYPE" parameter' % (_sConfigFile, sId))
                    continue

                if dsConfig['TYPE'] == 'include':
                    # Include configuration file(s)
                    bBootstrap_sub = KiscRuntime.parseBool(dsConfig.get('BOOTSTRAP', False))
                    bAutostart_sub = KiscRuntime.parseBool(dsConfig.get('AUTOSTART', False))
                    if 'file' in dsConfig:
                        lsErrors_sub = self.__loadResources(dsConfig['file'], bBootstrap_sub, bAutostart_sub)
                        if lsErrors_sub:
                            lsErrors.extend(['<%s> %s' % (_sConfigFile, sError) for sError in lsErrors_sub])
                    if 'directory' in dsConfig:
                        import glob
                        for sFile in glob.glob('%s/%s' % (dsConfig['directory'], dsConfig.get('glob', '*.cfg'))):
                            lsErrors_sub = self.__loadResources(sFile, bBootstrap_sub, bAutostart_sub)
                            if lsErrors_sub:
                                lsErrors.extend(['<%s> %s' % (_sConfigFile, sError) for sError in lsErrors_sub])

                else:

                    if _bBootstrap:
                        lsErrors_sub = self.__createResource_bootstrap(dsConfig['TYPE'], sId, dsConfig, _bAutostart)
                    else:
                        lsErrors_sub = self.__createResource(dsConfig['TYPE'], sId, dsConfig)
                    if lsErrors_sub:
                        lsErrors.extend(['<%s> %s' % (_sConfigFile, sError) for sError in lsErrors_sub])

        except (OSError, configparser.Error, RuntimeError) as e:
            if self._iVerbose: self._ERROR(str(e))
            lsErrors.append('<%s> %s' % (_sConfigFile, str(e)))

        # Done
        return lsErrors
Beispiel #2
0
    def start(self):
        if self._iVerbose: self._INFO('Starting')
        lsErrors = list()

        # Restart ?
        bRestart = KiscRuntime.parseBool(self._dsConfig.get('restart', False))

        # Be idempotent
        if self.status(True, KiscRuntime.STATUS_STARTED) == KiscRuntime.STATUS_STARTED:
            if not bRestart:
                if self._iVerbose: self._INFO('Already started')
                return lsErrors
            else:
                if self._iVerbose: self._INFO('Restarting')
        else:
            bRestart = False

        # Start the resource
        try:
            if bRestart:
                KiscRuntime.shell(['systemctl', '-q', 'restart', self._dsConfig['name']], _bTrace = self._iVerbose >= KiscRuntime.VERBOSE_TRACE)
            else:
                KiscRuntime.shell(['systemctl', '-q', 'start', self._dsConfig['name']], _bTrace = self._iVerbose >= KiscRuntime.VERBOSE_TRACE)
            self._iStatus = KiscRuntime.STATUS_STARTED
            if self._iVerbose: self._INFO('Started')
        except OSError as e:
            if self._iVerbose: self._ERROR(str(e))
            self._iStatus = KiscRuntime.STATUS_ERROR
            lsErrors.append(str(e))

        # Done
        return lsErrors
Beispiel #3
0
 def _cleanup(self):
     if KiscRuntime.parseBool(self._dsConfig.get('cleanup', False)):
         if 'constraint_file' in self._dsConfig:
             KiscRuntime.shell(
                 [
                     'cibadmin', '-o', 'constraints', '-d', '-f', '-A',
                     '//rsc_location[@rsc=\'%s\']' % self._dsConfig['name']
                 ],
                 _bTrace=self._iVerbose >= KiscRuntime.VERBOSE_TRACE)
             time.sleep(3)
         if 'resource_file' in self._dsConfig:
             KiscRuntime.shell(
                 [
                     'cibadmin', '-o', 'resources', '-D', '-A',
                     '//primitive[@id=\'%s\'] | //group[@id=\'%s\']' %
                     (self._dsConfig['name'], self._dsConfig['name'])
                 ],
                 _bTrace=self._iVerbose >= KiscRuntime.VERBOSE_TRACE)
             time.sleep(3)
Beispiel #4
0
    def start(self):
        if self._iVerbose: self._INFO('Starting')
        lsErrors = list()

        # Be idempotent
        if self.status(
                True,
                KiscRuntime.STATUS_STARTED) == KiscRuntime.STATUS_STARTED:
            if self._iVerbose: self._INFO('Already started')
            return lsErrors

        # Start the resource
        try:

            # ... mkdir ?
            if KiscRuntime.parseBool(self._dsConfig.get('mkdir', True)):
                os.makedirs(self._dsConfig['mountpoint'], exist_ok=True)

            # ... mount device
            lsCommand = ['mount', '-t', self._dsConfig['fstype']]
            if 'options' in self._dsConfig:
                lsCommand.extend(['-o', self._dsConfig['options']])
            lsCommand.extend(
                [self._dsConfig['device'], self._dsConfig['mountpoint']])
            KiscRuntime.shell(
                lsCommand, _bTrace=self._iVerbose >= KiscRuntime.VERBOSE_TRACE)
            self._iStatus = KiscRuntime.STATUS_STARTED
            if self._iVerbose: self._INFO('Started')

        except OSError as e:
            if self._iVerbose: self._ERROR(str(e))
            self._iStatus = KiscRuntime.STATUS_ERROR
            lsErrors.append(str(e))

        # Done
        return lsErrors
Beispiel #5
0
    def start(self):
        if self._iVerbose: self._INFO('Starting')
        lsErrors = list()

        # Be idempotent
        if self.status(
                True,
                KiscRuntime.STATUS_STARTED) == KiscRuntime.STATUS_STARTED:
            if self._iVerbose: self._INFO('Already started')
            return lsErrors

        # Start the resource
        try:

            # ... mkdir ?
            if KiscRuntime.parseBool(self._dsConfig.get('mkdir', True)):
                os.makedirs(os.path.dirname(self._dsConfig['destination']),
                            exist_ok=True)

            # ... pre-cache command ?
            if 'command_pre' in self._dsConfig:
                KiscRuntime.shell(
                    self._dsConfig['command_pre'].split(' '),
                    _bTrace=self._iVerbose >= KiscRuntime.VERBOSE_TRACE)

            # ... permissions
            mUser = self._dsConfig.get('user', None)
            mGroup = self._dsConfig.get('group', None)
            try:
                mMode = int(self._dsConfig['mode'], 8)
            except KeyError:
                mMode = None

            # ... cache file
            if 'config_file' in self._dsConfig:
                oClusterConfig = KiscCluster_config(
                    self._dsConfig['config_file'])
                sHost_id = oClusterConfig.getHostByHostname().id()
                oClusterConfig.resolveFile(self._dsConfig['source'],
                                           self._dsConfig['destination'],
                                           _sHost_id=sHost_id,
                                           _tPermissions=(mUser, mGroup,
                                                          mMode))
            else:
                if self._iVerbose:
                    self._DEBUG('Reading file (%s)' % self._dsConfig['source'])
                with open(self._dsConfig['source'], 'r') as oFile:
                    sFile = oFile.read()
                if self._iVerbose:
                    self._DEBUG('Writing file (%s)' %
                                self._dsConfig['destination'])
                iUmask = os.umask(0o077)
                oFile = None
                try:
                    oFile = open(self._dsConfig['destination'], 'w')
                    KiscRuntime.perms(
                        oFile.fileno(),
                        mUser,
                        mGroup,
                        mMode,
                        _bTrace=self._iVerbose >= KiscRuntime.VERBOSE_TRACE)
                    oFile.write(sFile)
                finally:
                    if oFile: oFile.close()
                    os.umask(iUmask)

            # ... post-cache command ?
            if 'command_post' in self._dsConfig:
                KiscRuntime.shell(
                    self._dsConfig['command_post'].split(' '),
                    _bTrace=self._iVerbose >= KiscRuntime.VERBOSE_TRACE)

            # ... done
            self._iStatus = KiscRuntime.STATUS_STARTED
            if self._iVerbose: self._INFO('Started')

        except (OSError, RuntimeError) as e:
            if self._iVerbose: self._ERROR(str(e))
            self._iStatus = KiscRuntime.STATUS_ERROR
            lsErrors.append(str(e))

        # Done
        return lsErrors
Beispiel #6
0
    def stop(self, _bForce=False):
        """
        Stop the host

        @param bool _bForce  Forcefully stop the host, ignoring non-critical errors

        @return list  Empty if host is successfully stopped, (ordered) error messages otherwise
        """
        if self._iVerbose: self._INFO('Stopping')
        lsErrors = list()

        # Stop the host
        try:

            # ... virtual ?
            bVirtual = self._oHost.isVirtual()

            # ... localhost ?
            sHost_id = self._oHost.id()
            sLocalhost_id = self._oClusterConfig.getHostByHostname().id()
            if not bVirtual:
                if sHost_id != sLocalhost_id:
                    raise RuntimeError('Cannot stop remote host')
            else:
                dsConfig = self._oHost.config()
                if 'HOSTS' in dsConfig and not self._oClusterConfig.isHostAllowed(
                        dsConfig['HOSTS'], sLocalhost_id):
                    raise RuntimeError(
                        'Local host (%s) not allowed to handle this (virtual) host'
                        % sLocalhost_id)

            # ... runtime status check
            bHost_runtime_file = self.existsRuntime()
            if not bHost_runtime_file and not _bForce:
                raise RuntimeError('Host not started')

            # ... load runtime configuration and status from file
            if bHost_runtime_file:
                self.loadRuntime()

            # ... check/stop the host's (regular) resources
            if len(self._oHost.getResourcesIDs(_bBootstrap=False)):
                if not _bForce:
                    raise RuntimeError('Resources are running on host')
                from KiSC.Cluster.resource import KiscCluster_resource
                for sResource_id in reversed(
                        self._oHost.getResourcesIDs(_bBootstrap=False)):
                    if not self._oClusterConfig.isHostResource(
                            sHost_id, sResource_id, _bBootstrap=False):
                        continue
                    oClusterResource = KiscCluster_resource(
                        self._oClusterConfig,
                        sHost_id,
                        sResource_id,
                        _bBootstrap=False)
                    oClusterResource.VERBOSE(self._iVerbose)
                    lsErrors_sub = oClusterResource.stop(_bForce)
                    if lsErrors_sub:
                        lsErrors.extend(lsErrors_sub)
                        raise RuntimeError(
                            'Failed to stop host\'s resource (%s)' %
                            sResource_id)

            # ... stop the host resource
            lsErrors_sub = self._oHost.stop()
            if lsErrors_sub and not _bForce:
                lsErrors.extend(lsErrors_sub)
                raise RuntimeError('Failed to stop host resource')

            # ... update runtime configuration and status from file
            if bHost_runtime_file:
                self.saveRuntime()

            # ... stop the host's bootstrap resources
            if not bVirtual:
                from KiSC.Cluster.resource import KiscCluster_resource
                for sResource_id in reversed(
                        self._oHost.getResourcesIDs(_bBootstrap=True)):
                    if not self._oClusterConfig.isHostResource(
                            sHost_id, sResource_id, _bBootstrap=True):
                        continue
                    oClusterResource = KiscCluster_resource(
                        self._oClusterConfig,
                        sHost_id,
                        sResource_id,
                        _bBootstrap=True)
                    oClusterResource.VERBOSE(self._iVerbose)
                    if not KiscRuntime.parseBool(
                            oClusterResource.resource().config().get(
                                'PERSISTENT', False)):
                        lsErrors_sub = oClusterResource.stop(_bForce)
                        if lsErrors_sub:
                            lsErrors.extend(lsErrors_sub)
                            raise RuntimeError(
                                'Failed to stop host\'s bootstrap resource (%s)'
                                % sResource_id)

            # ... delete runtime file
            if bHost_runtime_file:
                os.unlink(self._dsPaths['runtime_file'])

            # ... done
            if self._iVerbose: self._INFO('Stopped')

        except (OSError, RuntimeError) as e:
            if self._iVerbose: self._ERROR(str(e))
            lsErrors.append(str(e))

        # Done
        return lsErrors