def __postActivation(self, service, manifest, curProg): """ place to run post activation operations 1. customize application configuration files based on metadata 2. install upstart service """ # replace application config files based on lcm_meta.env, "env" valeu set in post request for package in packagesInManifest(service, manifest): self._LOG.info('check map config files in %s' % (package)) pkgRoot = packagePath(service, ACTIVE_MANIFEST, package) pkgCfg = PkgInitConfig(pkgRoot) # read cfgfilemap from cronus.ini env = serviceutil.getEnv(service) if env: cfgFiles = pkgCfg.getConfig(PkgInitConfig.KEY_CFGFILES, []) for cfgFile in cfgFiles: srcFile = os.path.join(pkgRoot, '%s.%s' % (cfgFile, env.lower())) destFile = os.path.join(pkgRoot, cfgFile) if os.path.exists(srcFile): self._LOG.info('copy cfg file %s to %s' % (srcFile, destFile)) cmd = utils.sudoCmd(['cp', '-f', srcFile, destFile], configutil.getAppUser()) execThread = ExecThread(self._threadMgr, cmd, None, self.getUuid()) self._runExecThreads([execThread], curProg, curProg+1) # install daemon based on metadata.lcm_meta.daemon isDaemon, daemonType = serviceutil.isDaemonServiceWisb(service) if isDaemon: installed = False self._LOG.info('daemon enabled, setup service in %s' % daemonType) for package in packagesInManifest(service, manifest): pkgRoot = packagePath(service, ACTIVE_MANIFEST, package) appUser = configutil.getAppUser() if (os.path.exists(os.path.join(pkgRoot, 'cronus', 'upstart.conf')) or os.path.exists(os.path.join(pkgRoot, 'cronus', 'systemd.service'))): self._LOG.info('found daemon config in %s' % (package)) script = manifestutil.getActiveScriptPath('agent', 'agent', 'setupserviced') cmd = utils.sudoCmd([script, pkgRoot, appUser, service, daemonType]) execThread = ExecThread(self._threadMgr, cmd, None, self.getUuid()) self._runExecThreads([execThread], curProg+1, curProg+2) installed = True break if not installed: self._LOG.info('daemon config not found, service not installed') serviceutil.setDaemonServiceWisb(service, None)
def testPkgInitConfig(self): createManifest(self, manifest='bar', service='foo') activateManifest(self, manifest='bar', service='foo') inifilepath = manifestutil.packagePath( 'foo', 'bar', 'perlserver') + os.path.sep + 'cronus' inifilename = os.path.join(inifilepath, 'cronus.ini') uname = pylons.config['app_user_account'] utils.runsyscmd(utils.sudoCmd('chmod -R ga+w %s' % inifilepath, uname)) data = {"key": "value", "key2": "value2"} # test json format with open(inifilename, 'w') as propFile: json.dump(data, propFile) pkgPath = packagePath('foo', 'bar', 'perlserver') pkgInitConfig = manifestutil.PkgInitConfig(pkgPath) configs = pkgInitConfig.getConfigs() assert configs is not None assert isinstance(configs, dict) print configs assert configs['key'] == 'value' assert configs['key2'] == 'value2' # test eval() format with open(inifilename, 'wb+') as fp: jsonStr = json.dumps(data) fp.write(jsonStr) fp.write("\n") pkgInitConfig = manifestutil.PkgInitConfig(pkgPath) configs = pkgInitConfig.getConfigs() assert configs is not None assert isinstance(configs, dict) print configs assert configs['key'] == 'value' assert configs['key2'] == 'value2'
def testPkgInitConfig(self): createManifest(self, manifest = 'bar', service = 'foo') activateManifest(self, manifest = 'bar', service = 'foo') inifilepath = manifestutil.packagePath('foo', 'bar', 'perlserver') + os.path.sep + 'cronus' inifilename = os.path.join(inifilepath, 'cronus.ini') uname = pylons.config['app_user_account'] utils.runsyscmd(utils.sudoCmd('chmod -R ga+w %s' % inifilepath, uname)) data = {"key":"value","key2":"value2"} # test json format with open(inifilename, 'w') as propFile: json.dump(data, propFile) pkgPath = packagePath('foo', 'bar', 'perlserver') pkgInitConfig = manifestutil.PkgInitConfig(pkgPath) configs = pkgInitConfig.getConfigs() assert configs is not None assert isinstance(configs, dict) print configs assert configs['key'] == 'value' assert configs['key2'] == 'value2' # test eval() format with open(inifilename, 'wb+') as fp: jsonStr = json.dumps(data) fp.write(jsonStr) fp.write("\n") pkgInitConfig = manifestutil.PkgInitConfig(pkgPath) configs = pkgInitConfig.getConfigs() assert configs is not None assert isinstance(configs, dict) print configs assert configs['key'] == 'value' assert configs['key2'] == 'value2'
def __stopServiceDaemon(self, curProg): """ stop upstart service """ script = manifestutil.getActiveScriptPath('agent', 'agent', 'shutdownserviced') startupCmd = utils.sudoCmd([script, self.__service]) teardownThread = ExecThread(self._threadMgr, startupCmd, None, self.getUuid()) self._runExecThreads([teardownThread], curProg, curProg+1) self._LOG.info('stop daemon service %s' % (self.__service))
def removeAgentRoot(): agentRoot = pylons.config['agent_root'] assert (agentRoot != None and pylons.config['agent_root'] != '/') file_stat = os.stat(agentRoot) assert file_stat.st_uid == os.getuid(), 'Agent root dir %s owner mismatch ' % os.path.abspath(agentRoot) cmd = utils.sudoCmd('rm -r %s' % pylons.config['agent_root']) os.system(cmd) return True
def removeDirectory(path, onlyChildren): """ remove directory """ if onlyChildren: path = os.path.join(path, '*') cmd = utils.sudoCmd('rm -rf %s' % path) LOG.debug("running command %s" % cmd) ret = os.system(cmd) if (ret != 0): raise AgentException(error = Errors.SERVICE_DELETE_FAILED, errorMsg = 'Path (%s) delete failed' % path)
def __preDeactivation(self, service, manifest, curProg): """ additional operations post deactivation script 1. uninstall upstart config """ isDaemon, daemonType = serviceutil.isDaemonServiceWisb(service) if isDaemon: self._LOG.info('daemon enabled, teardown service in %s' % daemonType) script = manifestutil.getActiveScriptPath('agent', 'agent', 'teardownserviced') teardownCmd = utils.sudoCmd([script, service]) teardownThread = ExecThread(self._threadMgr, teardownCmd, None, self.getUuid()) self._runExecThreads([teardownThread], curProg, curProg+1) self._LOG.info('uninstalled upstart service %s' % (daemonType))
def _getBuiltThread(self, scriptName): """ build lcm script exec thread """ # figure out the path to the cronus scripts uname = pylons.config['app_user_account'] execPath = os.path.join(manifestutil.modulePath(self.__service, self.__module), self.__package, 'cronus', 'scripts', scriptName) if (isHigherPrivilegeService(self.__service)): cmd = execPath else: cmd = utils.sudoCmd([execPath], uname) dummy = not os.path.exists(execPath) execThread = ExecThread(self._threadMgr, cmd) copycontexts(self, execThread, ['service', 'guid']) return execThread, dummy
def _getBuiltThread(self, service, manifest, package, exeName): """ here """ # figure out the path to the cronus scripts uname = pylons.config['app_user_account'] execPath = os.path.join(ManifestController.manifestPath(service, manifest), package, 'cronus', 'scripts', exeName) if (isHigherPrivilegeService(service)): cmd = execPath else: cmd = utils.sudoCmd([execPath], uname) dummy = not os.path.exists(execPath) execThread = ExecThread(self._threadMgr, cmd) copycontexts(self, execThread, contextutils.CTX_NAMES) return execThread, dummy
def __stopProcesses(self): """ stop all processes that run as app_user_account refers to http://stackoverflow.com/questions/4669754/python-kill-all-processes-owned-by-user """ self._updateStatus(progress=10) uname = pylons.config['app_user_account'] import pwd uid = pwd.getpwnam(uname).pw_uid pids = filter(lambda pid: pid.isdigit(), os.listdir('/proc')) execThreads = [] # test if PID is owned by user for pid in pids: # check if PID still exist if not os.path.exists(os.path.join('/proc', pid)): LOG.debug("pid doesn't exist any more: %s" % pid) continue puid = os.stat(os.path.join('/proc', pid)).st_uid if puid == uid: cmd = utils.sudoCmd(['kill', '-9', pid], uname) execThread = ExecThread(self._threadMgr, cmd) execThread.setTimeout(self.__killTimeout) execThread.start() execThreads.append(execThread) while (True): self._checkStop() running = False for execThread in execThreads: status = execThread.getStatus() if (status['error'] != None): raise AgentException(status['error'], status['errorMsg']) if (execThread.isAlive()): LOG.debug("process is still alive: %s" % execThread.getCmd()) running = True if (not running): LOG.debug( "stop processes finished: %s" % [execThread.getCmd()[-1] for execThread in execThreads]) break time.sleep(0.1) self._updateStatus(progress=50)
def _getBuiltThread(self, service, manifest, package, exeName): """ here """ # figure out the path to the cronus scripts uname = pylons.config['app_user_account'] execPath = os.path.join( ManifestController.manifestPath(service, manifest), package, 'cronus', 'scripts', exeName) if (isHigherPrivilegeService(service)): cmd = execPath else: cmd = utils.sudoCmd([execPath], uname) dummy = not os.path.exists(execPath) execThread = ExecThread(self._threadMgr, cmd) copycontexts(self, execThread, contextutils.CTX_NAMES) return execThread, dummy
def _getBuiltThread(self, scriptName): """ build lcm script exec thread """ # figure out the path to the cronus scripts uname = pylons.config['app_user_account'] execPath = os.path.join( manifestutil.modulePath(self.__service, self.__module), self.__package, 'cronus', 'scripts', scriptName) if (isHigherPrivilegeService(self.__service)): cmd = execPath else: cmd = utils.sudoCmd([execPath], uname) dummy = not os.path.exists(execPath) execThread = ExecThread(self._threadMgr, cmd) copycontexts(self, execThread, ['service', 'guid']) return execThread, dummy
def __stopProcesses(self): """ stop all processes that run as app_user_account refers to http://stackoverflow.com/questions/4669754/python-kill-all-processes-owned-by-user """ self._updateStatus(progress = 10) uname = configutil.getAppUser() uid, _ = utils.getUidGid(uname) pids = filter(lambda pid: pid.isdigit(), os.listdir('/proc')) execThreads = [] # test if PID is owned by user for pid in pids: # check if PID still exist if not os.path.exists(os.path.join('/proc', pid)): LOG.debug("pid doesn't exist any more: %s" % pid) continue puid = os.stat(os.path.join('/proc', pid)).st_uid if puid == uid: cmd = utils.sudoCmd(['kill', '-9', pid], uname) execThread = ExecThread(self._threadMgr, cmd) execThread.setTimeout(self.__killTimeout) execThread.start() execThreads.append(execThread) self._addChildExeThreadId(execThread.getUuid()) while(True): self._checkStop() running = False for execThread in execThreads: status = execThread.getStatus() if (status['error'] != None): raise AgentException(status['error'], status['errorMsg']) if (execThread.isAlive()): LOG.debug("process is still alive: %s" % execThread.getCmd()) running = True if (not running): LOG.debug("stop processes finished: %s" % [execThread.getCmd()[-1] for execThread in execThreads]) break time.sleep(0.1) self._updateStatus(progress = 50)
def removeAgentRoot(): agentRoot = pylons.config['agent_root'] assert (agentRoot != None and pylons.config['agent_root'] != '/') if (not os.name == 'nt'): file_stat = os.stat(agentRoot) assert file_stat.st_uid == os.getuid(), 'Agent root dir %s owner mismatch ' % os.path.abspath(agentRoot) cmd = utils.sudoCmd('rm -r %s' % pylons.config['agent_root']) os.system(cmd) return True else: try: #shutil.rmtree(pylons.config['agent_root']) cmd = 'rm -rf %s' % pylons.config['agent_root'] os.system(cmd) return True except Exception as e: print e return False
def removeAgentRoot(): agentRoot = pylons.config['agent_root'] assert (agentRoot != None and pylons.config['agent_root'] != '/') if (not os.name == 'nt'): file_stat = os.stat(agentRoot) assert file_stat.st_uid == os.getuid( ), 'Agent root dir %s owner mismatch ' % os.path.abspath(agentRoot) cmd = utils.sudoCmd('rm -r %s' % pylons.config['agent_root']) os.system(cmd) return True else: try: #shutil.rmtree(pylons.config['agent_root']) cmd = 'rm -rf %s' % pylons.config['agent_root'] os.system(cmd) return True except Exception as e: print e return False
def kill(self, cmdProcess, cmd): ''' Kills the given process if its alive in os independent way (in *nix kills it as super user) ''' if (self.__cmdProcess != None and self.__cmdProcess.poll() == None): needSudo, sudoTarget = self.__needSudo() killCmd = 'kill -9 %s' % cmdProcess.pid if needSudo: killCmd = utils.sudoCmd(killCmd, sudoTarget) self.__LOG.info('cleanup incomplete process by %s ' % killCmd) retcode = os.system(killCmd) if retcode != 0: # even if process had actually gotten killed at the time of us killing it, we should get 0 self.__LOG.error('Unable to kill exec process (that ran cmd %s) at time of exit; return code %s' % (cmd, cmdProcess.pid)) try: # if the killed process had become a zombie, then lets collect the exit status so that it can be removed from process table os.waitpid(cmdProcess.pid, os.WNOHANG) # in case if kill failed and if process is still active, lets not hanf forever except OSError: pass #ok, looks like the process had not become a zombie and hence not in process table
def runScript(self, script, timeout, progressTimeout): ''' @param script: script name @param timeout: total script timeout @param progressTimeout: progress timeout @return: ExecThread instance @throws PackageScriptNotFound: if script does not exist ''' if not self.hasScript(script): raise PackageScriptNotFound('missing package script: ' + self.__scriptPath(script)) cmd = utils.sudoCmd([], self.__userName) if self.__userName else [] cmd.append(self.__scriptPath(script)) execThread = ExecThread(self.__threadMgr, cmd) execThread.setTimeout(timeout) execThread.setProgressTimeout(progressTimeout) copycontexts(self, execThread, ['guid', 'service']) execThread.start() return execThread
def removeDirectory(path, onlyChildren): """ remove directory """ if onlyChildren: path = os.path.join(path, '*') if (not os.name == 'nt'): cmd = utils.sudoCmd('rm -rf %s' % path) LOG.debug("running command %s" % cmd) ret = os.system(cmd) if (ret != 0): raise AgentException(error = Errors.SERVICE_DELETE_FAILED, errorMsg = 'Path (%s) delete failed' % path) else: try: shutil.rmtree(path, False, handleRemoveReadonly) except OSError: cmd = 'rm -rf %s' % path LOG.debug("running command %s" % cmd) os.system(cmd)
def removeDirectory(path, onlyChildren): """ remove directory """ if onlyChildren: path = os.path.join(path, '*') if (not os.name == 'nt'): cmd = utils.sudoCmd('rm -rf %s' % path) LOG.debug("running command %s" % cmd) ret = os.system(cmd) if (ret != 0): raise AgentException(error=Errors.SERVICE_DELETE_FAILED, errorMsg='Path (%s) delete failed' % path) else: try: shutil.rmtree(path, False, handleRemoveReadonly) except OSError: cmd = 'rm -rf %s' % path LOG.debug("running command %s" % cmd) os.system(cmd)
def kill(self, cmdProcess, cmd): ''' Kills the given process if its alive in os independent way (in *nix kills it as super user) ''' if (self.__cmdProcess != None and self.__cmdProcess.poll() == None): if(os.name == 'nt'): cmdProcess.kill() else: needSudo, sudoTarget = self.__needSudo() killCmd = 'kill -9 %s' % cmdProcess.pid if needSudo: killCmd = utils.sudoCmd(killCmd, sudoTarget) self.__LOG.info('cleanup incomplete process by %s ' % killCmd) retcode = os.system(killCmd) if retcode != 0: # even if process had actually gotten killed at the time of us killing it, we should get 0 self.__LOG.error('Unable to kill exec process (that ran cmd %s) at time of exit; return code %s' % (cmd, cmdProcess.pid)) try: # if the killed process had become a zombie, then lets collect the exit status so that it can be removed from process table os.waitpid(cmdProcess.pid, os.WNOHANG) # in case if kill failed and if process is still active, lets not hanf forever except OSError: pass #ok, looks like the process had not become a zombie and hence not in process table
def _getBuiltThread(self, service, manifest, package, exeName): """ here """ # figure out the path to the cronus scripts uname = configutil.getAppUser() execPath = os.path.join(manifestutil.manifestPath(service, manifest), package, 'cronus', 'scripts', exeName) if (isHigherPrivilegeService(service)) or not uname: cmd = execPath else: cmd = utils.sudoCmd([execPath], uname) dummy = not os.path.exists(execPath) if not dummy: execThread = ExecThread(self._threadMgr, cmd, parentId = self.getUuid()) contextutils.copyJobContexts(self, execThread) # issue 17, not inject ctx for startup and shutdown script if exeName == 'startup' or exeName == 'shutdown': execThread.setInjectctx(False) return execThread else: return None
def startTestProcess(): cmd = utils.sudoCmd(["sleep", "5"], pylons.config['app_user_account']) return Popen(cmd)