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
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
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)
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
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
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