def selfupdate(self): """ agent selfupdate through api """ LOG.info('selfupdate agent with body: %s', request.body) try: appGlobal = config['pylons.app_globals'] wisbVersion = None wisbSource = None if request.body: requestjson = json.loads(request.body) if 'version' not in requestjson: raise AgentException(Errors.INVALID_REQUEST, 'version is required') wisbVersion = requestjson['version'] wisbSource = requestjson['wisbSource'] if 'wisbSource' in requestjson else configutil.getConfig('selfupdate_source') updateThread = AgentUpdate(appGlobal.threadMgr, wisbVersion, wisbSource) self.injectJobCtx(updateThread) updateThread.start() updateThread.threadMgrEvent.wait() return statusResult(request, response, updateThread, controller = self) except AgentException as aexcep: return errorResult(request, response, error = aexcep.getCode(), errorMsg = aexcep.getMsg(), controller = self) except Exception as excep: msg = 'Unknown error for agent update(%s) - %s - %s' % (wisbVersion, str(excep), traceback.format_exc(2)) return errorResult(request, response, error = Errors.UNKNOWN_ERROR, errorMsg = msg, controller = self)
def delete(self, service, manifest): """ Delete a new service object """ try: path = manifestutil.manifestPath(service, manifest) if (not os.path.isdir(path)): return errorResult(request, response, Errors.MANIFEST_NOT_FOUND, 'manifest (%s/%s) missing service' % (service, manifest), controller=self) # first check that this isn't the active manifest path = manifestutil.manifestPath(service) if (os.path.exists(path)): activePath = os.path.basename(readlink(path)) deletePath = os.path.basename(manifestutil.manifestPath(service, manifest)) if (activePath == deletePath): return errorResult(request, response, Errors.MANIFEST_DELETING_ACTIVE_MANIFEST, 'Manifest(%s, %s) attempting to delete active manifest' % (service, manifest), controller=self) # now try to delete the manifest directory appGlobal = config['pylons.app_globals'] manThread = ManifestDelete(appGlobal.threadMgr, service, manifest) self.injectJobCtx(manThread) manThread.start() manThread.threadMgrEvent.wait() return statusResult(request, response, manThread, controller=self) except Exception as excep: return errorResult(request, response, error=Errors.UNKNOWN_ERROR, errorMsg='Unknown error for delete manifest(%s/%s) - %s - %s' % (service, manifest, str(excep), traceback.format_exc(2)), controller=self)
def selfupdate(self): """ agent selfupdate through api """ LOG.info('selfupdate agent with body: %s', request.body) try: appGlobal = config['pylons.app_globals'] wisbVersion = None wisbSource = None if request.body: requestjson = json.loads(request.body) if 'version' not in requestjson: raise AgentException(Errors.INVALID_REQUEST, 'version is required') wisbVersion = requestjson['version'] wisbSource = requestjson['wisbSource'] if 'wisbSource' in requestjson else configutil.getConfig('selfupdate_source') skipProp = asbool(requestjson['skipProp']) if 'skipProp' in requestjson else True updateThread = AgentUpdate(appGlobal.threadMgr, wisbVersion, wisbSource, skipProp = skipProp) self.injectJobCtx(updateThread) updateThread.start() updateThread.threadMgrEvent.wait() return statusResult(request, response, updateThread, controller = self) except AgentException as aexcep: return errorResult(request, response, error = aexcep.getCode(), errorMsg = aexcep.getMsg(), controller = self) except Exception as excep: msg = 'Unknown error for agent update(%s) - %s - %s' % (wisbVersion, str(excep), traceback.format_exc(2)) return errorResult(request, response, error = Errors.UNKNOWN_ERROR, errorMsg = msg, controller = self)
def post(self, module): """ Create a new module object """ try: LOG.info('Got a post request for module ' + module) if (request.body == ""): return errorResult(request, response, Errors.MODULE_PACKAGE_PARSING_ERROR, 'No body found in post command', controller = self) body = json.loads(request.body) package = body['package'] LOG.debug('pkgs = %s', package) appGlobal = config['pylons.app_globals'] # start a thread to create the package moduleThread = ModuleCreate(appGlobal.threadMgr, module, package) self.injectJobCtx(moduleThread) moduleThread.start() moduleThread.threadMgrEvent.wait() return statusResult(request, response, moduleThread, controller = self) except AgentException as excep: return errorResult(request, response, error = excep.getCode(), errorMsg = excep.getMsg(), controller = self) except Exception as excep: return errorResult(request, response, error = Errors.UNKNOWN_ERROR, errorMsg = 'Unknown error for create module(%s/%s) - %s - %s' % ('agent', module, str(excep), traceback.format_exc(2)), controller = self)
def delete(self, module): """ Delete a new service object """ try: LOG.info('Got a delete request for module ' + module) path = manifestutil.modulePath('agent', module) if (not os.path.exists(path) and not os.path.isdir(path)): return doneResult(request, response, controller=self) # start the delete thread appGlobal = config['pylons.app_globals'] deleteThread = ModuleDelete(appGlobal.threadMgr, module) self.injectJobCtx(deleteThread) deleteThread.start() deleteThread.threadMgrEvent.wait() return statusResult(request, response, deleteThread, controller=self) except Exception as excep: return errorResult( request, response, error=Errors.UNKNOWN_ERROR, errorMsg='Unknown error when deleting module(%s) %s - %s' % (module, str(excep), traceback.format_exc(2)), controller=self)
def activate(self, service, manifest): """ activate manifest, if already active then skip """ from agent.lib.agent_thread.activate_manifest import ActivateManifest LOG.info('activateManifest for service(%s) with body: %s', service, request.body) try: appGlobal = config['pylons.app_globals'] if manifestutil.getActiveManifest(service) == manifest: return doneResult(request, response, controller=self) else: if request.body: pushedData = json.loads(request.body) serviceutil.updateLcmMeta(service, pushedData) mf_path = os.path.join(manifestutil.manifestPath(service, manifest)) if (not os.path.exists(mf_path)): return errorResult(request, response, Errors.ACTIVEMANIFEST_MANIFEST_MISSING, 'Manifest(%s, %s) path missing' % (service, manifest), controller=self) LOG.debug('Manifest path exists: %s' % (mf_path)) activateThread = ActivateManifest(appGlobal.threadMgr, service, manifest, action=ActivateManifest.ACTION_ACTIVATION) self.injectJobCtx(activateThread) activateThread.start() activateThread.threadMgrEvent.wait() return statusResult(request, response, activateThread, controller=self) except Exception as excep: msg = 'Unknown error for activateManifest(%s/%s) - %s - %s' % (service, manifest, str(excep), traceback.format_exc(2)) return errorResult(request, response, error=Errors.UNKNOWN_ERROR, errorMsg=msg, controller=self)
def startdownload(self): """ Download using http. The protocol is chosen based on package uri. Target folder is packageloc relative to repo_root. """ try: utils.checkDiskFull() reqjson = json.loads(request.body) package = str(reqjson['package']) packageloc = str(reqjson['packageloc']) skipProp = asbool(reqjson['skipProp']) if 'skipProp' in reqjson else configutil.getConfigAsBool('download_skip_prop') LOG.info('Request received for StartDownload %s' % packageloc) appGlobal = config['pylons.app_globals'] downloadThread = None cat = 'DIST_SD' + packageloc if not downloadThread: LOG.info('Starting a new StartDownload Thread %s' % packageloc) downloadThread = DownloadThread(appGlobal.threadMgr, package, packageloc, category = [cat], skipProp = skipProp) downloadThread.setMergeOnFound(True) self.injectJobCtx(downloadThread) downloadThread.start() downloadThread.threadMgrEvent.wait() return statusResult(request, response, downloadThread, controller = self) except AgentException as excep: return errorResult(request, response, error = excep.getCode(), errorMsg = excep.getMsg(), controller = self) except Exception as excp: errorMsg = 'Exception downloading %s - traceback %s' % (str(excp), traceback.format_exc(2)) return errorResult(request, response, error = Errors.UNKNOWN_ERROR, errorMsg = errorMsg, controller = self)
def activatemanifest(self, service): """ activate manifest, if already active then skip """ LOG.info('activateManifest for service(%s) with body: %s', service, request.body) try: appGlobal = config['pylons.app_globals'] manifest = '' requestjson = json.loads(request.body) manifest = requestjson['manifest'] force = asbool(requestjson['force']) if 'force' in requestjson else False if not force and manifestutil.getActiveManifest(service) == manifest: return doneResult(request, response, controller=self) else: mf_path = os.path.join(ManifestController.manifestPath(service, manifest)) if (not os.path.exists(mf_path)): return errorResult(request, response, Errors.ACTIVEMANIFEST_MANIFEST_MISSING, 'Manifest(%s, %s) path missing' % (service, manifest), controller = self) LOG.debug('Manifest path exists: %s' % (mf_path)) activateThread = ActivateManifest(appGlobal.threadMgr, service, manifest) self.injectJobCtx(activateThread) activateThread.start() activateThread.threadMgrEvent.wait() return statusResult(request, response, activateThread, controller = self) except Exception as excep: msg = 'Unknown error for activateManifest(%s/%s) - %s - %s' % (service, manifest, str(excep), traceback.format_exc(2)) return errorResult(request, response, error = Errors.UNKNOWN_ERROR, errorMsg = msg, controller = self)
def delete(self, service): """ Delete a new service object """ from agent.lib.agent_thread.service_delete import ServiceDelete try: LOG.info('Got a delete request for service ' + service) path = ServiceController.servicePath(service) if (not os.path.exists(path) and not os.path.isdir(path)): return errorResult(request, response, Errors.SERVICE_NOT_FOUND, "No service(%s) found" % service, controller = self) # see if active manifest exist for the service if manifestutil.hasActiveManifest(service): return errorResult(request, response, Errors.MANIFEST_DELETING_ACTIVE_MANIFEST, 'Active manifest exists for service %s, deactivate the manifest first before deleting service' % (service), controller = self) # start the delete thread appGlobal = config['pylons.app_globals'] deleteThread = ServiceDelete(appGlobal.threadMgr, service, path) self.injectJobCtx(deleteThread) deleteThread.start() deleteThread.threadMgrEvent.wait() return statusResult(request, response, deleteThread, controller = self) except Exception as excep: return errorResult(request, response, error = Errors.UNKNOWN_ERROR, errorMsg = 'Unknown error when deleting service(%s) %s - %s' % (service, str(excep), traceback.format_exc(2)), controller = self)
def reset(self, service): ''' Controller to reset service ''' LOG.info('reset for service(%s)', service) try: appGlobal = config['pylons.app_globals'] if not os.path.exists(manifestutil.manifestPath(service, 'active')): return errorResult(request, response, Errors.ACTIVEMANIFEST_MANIFEST_MISSING, 'Active Manifest(%s) path missing' % (service), controller = self) resetThread = ActivateManifest(appGlobal.threadMgr, service, manifestutil.ACTIVE_MANIFEST, action = ActivateManifest.ACTION_RESET) self.injectJobCtx(resetThread) resetThread.start() resetThread.threadMgrEvent.wait() return statusResult(request, response, resetThread, controller = self) except Exception as excep: return errorResult(request, response, error = Errors.UNKNOWN_ERROR, errorMsg = 'Unknown error for restart service(%s) - %s - %s' % (service, str(excep), traceback.format_exc(2)), controller = self)
def shutdown(self, service): ''' Controller to shutdown service ''' LOG.info('shutdown for service(%s)', service) try: appGlobal = config['pylons.app_globals'] if not os.path.exists(manifestutil.manifestPath(service, 'active')): return errorResult(request, response, Errors.ACTIVEMANIFEST_MANIFEST_MISSING, 'Active Manifest(%s) path missing' % (service), controller=self) shutdownThread = StartStopService(appGlobal.threadMgr, service, StartStopService.ACTION_SHUTDOWN) self.injectJobCtx(shutdownThread) shutdownThread.start() shutdownThread.threadMgrEvent.wait() return statusResult(request, response, shutdownThread, controller=self) except Exception as excep: return errorResult( request, response, error=Errors.UNKNOWN_ERROR, errorMsg='Unknown error for shutdown service(%s) - %s - %s' % (service, str(excep), traceback.format_exc(2)), controller=self)
def post(self, service, manifest): """ Create a new service object """ from agent.lib.agent_thread.manifest_create import ManifestCreate try: LOG.info('Post for service (%s) and manifest (%s) with body: %s', service, manifest, request.body) # check to see if the manifest already exists path = ManifestController.manifestPath(service, manifest) if (os.path.isdir(path)): return doneResult(request, response, httpStatus = 201, controller = self) # parse the body if (request.body == ""): return errorResult(request, response, Errors.MANIFEST_PACKAGE_PARSING_ERROR, 'No body found in post command', controller = self) body = json.loads(request.body) packages = body['package'] forcedPackages = body['forcePackageName'] if 'forcePackageName' in body else None skipProp = asbool(body['skipProp']) if 'skipProp' in body else configutil.getConfigAsBool('download_skip_prop') LOG.debug('pkgs = %s, %s', packages, forcedPackages) # parse the package list for idx, package in enumerate(packages): # to support reuse of an package from an existing manifest (active if possible) # without sending the complete package location in request body if package.startswith('/'): packageRef = package tokens = package.split('/') pkgnamePrefix = tokens[-1].rstrip() fullPkgLoc = manifestutil.getPackageByName(service, manifest = None, pkgnamePrefix = pkgnamePrefix) if fullPkgLoc is None: return errorResult(request, response, Errors.MANIFEST_PACKAGE_DOES_NOT_EXIST, 'manifest (%s/%s) package (%s) does not exist' % (service, manifest, packages), controller = self) else: LOG.info('expanding package reuse ref %s with full package location %s' % (packageRef, fullPkgLoc)) packages[idx] = fullPkgLoc appGlobal = config['pylons.app_globals'] # start a thread to create the package manThread = ManifestCreate(appGlobal.threadMgr, service, manifest, packages, forcePackages = forcedPackages, skipProp = skipProp) self.injectJobCtx(manThread) manThread.start() manThread.threadMgrEvent.wait() return statusResult(request, response, manThread, controller = self) except AgentException as excep: return errorResult(request, response, error = excep.getCode(), errorMsg = excep.getMsg(), controller = self) except Exception as excep: return errorResult(request, response, error = Errors.UNKNOWN_ERROR, errorMsg = 'Unknown error for activateManifest(%s/%s) - %s - %s' % (service, manifest, str(excep), traceback.format_exc(2)), controller = self)
def deployservice(self, service): """ activate manifest, if already active then skip """ LOG.info('deploy service for service(%s) with body: %s', service, request.body) try: appGlobal = config['pylons.app_globals'] # parse the body if (request.body == ""): return errorResult(request, response, Errors.INVALID_REQUEST, 'No body found in post command', controller = self) requestjson = json.loads(request.body) manifest = requestjson['manifest'] packages = requestjson['package'] skipProp = asbool(requestjson['skipProp']) if 'skipProp' in requestjson else configutil.getConfigAsBool('download_skip_prop') skipActivation = asbool(requestjson['skipActivation']) if 'skipActivation' in requestjson else False # activate manifest if not already activated if manifestutil.getActiveManifest(service) == manifest: return doneResult(request, response, controller=self) deployServiceThread = DeployService(appGlobal.threadMgr, service, manifest, packages, skipProp = skipProp, skipActivation = skipActivation) self.injectJobCtx(deployServiceThread) deployServiceThread.start() deployServiceThread.threadMgrEvent.wait() return statusResult(request, response, deployServiceThread, controller = self) except Exception as excep: msg = 'Unknown error for activateManifest(%s/%s) - %s - %s' % (service, manifest, str(excep), traceback.format_exc(2)) return errorResult(request, response, error = Errors.UNKNOWN_ERROR, errorMsg = msg, controller = self)
def get(self, uuid): """ Get the status of this particular thread. Use the uuid to grab the correct thread. return the progress and status of the thread. """ try: appGlobal = config['pylons.app_globals'] thread = appGlobal.threadMgr.getThreadByUuid(uuid) if (thread == None): script = manifestutil.getPackageScriptPath('agent', 'active', 'agent', 'uuid') tmp = [script, uuid] cmds = [] for cmd in tmp: cmds.append(cmd.encode('ascii', 'ignore')) cmdout = utils.runsyscmdwstdout(cmds) if cmdout: # make sure it's a valid json result = json.loads(cmdout) # return status as raw return statusResultRaw(request, response, result) else: return errorResult(request, response, Errors.STATUS_UUID_NOT_FOUND, 'Unable to find thread with uuid(%s)' % uuid, controller = self) except Exception as excep: return errorResult(request, response, error = Errors.UNKNOWN_ERROR, errorMsg = 'Unknown error for get status(%s) - %s, %s' % (uuid, str(excep), traceback.format_exc()), controller = self) return statusResult(request, response, thread, controller = self, maxProgress = 99 if thread.isAlive() else 100)
def delete(self, module): """ Delete a new service object """ try: LOG.info("Got a delete request for module " + module) path = manifestutil.modulePath("agent", module) if not os.path.exists(path) and not os.path.isdir(path): return doneResult(request, response, controller=self) # start the delete thread appGlobal = config["pylons.app_globals"] deleteThread = ModuleDelete(appGlobal.threadMgr, module) self.injectJobCtx(deleteThread) deleteThread.start() deleteThread.threadMgrEvent.wait() return statusResult(request, response, deleteThread, controller=self) except Exception as excep: return errorResult( request, response, error=Errors.UNKNOWN_ERROR, errorMsg="Unknown error when deleting module(%s) %s - %s" % (module, str(excep), traceback.format_exc(2)), controller=self, )
def startdownload(self): """ Download using http. The protocol is chosen based on package uri. Target folder is packageloc relative to repo_root. """ try: utils.checkDiskFull() reqjson = json.loads(request.body) package = reqjson['package'] packageloc = str(reqjson['packageloc']) LOG.info('Request received for StartDownload %s' % packageloc) appGlobal = config['pylons.app_globals'] LOG.info('Starting a new StartDownload Thread %s' % package) if type(package) == list: downloadThread = PackageDownload(appGlobal.threadMgr, package) else: cat = PackageUtil.getPackageKey(package) downloadThread = DownloadThread(appGlobal.threadMgr, package, packageloc, category = [cat]) self.injectJobCtx(downloadThread) downloadThread.start() downloadThread.threadMgrEvent.wait() return statusResult(request, response, downloadThread, controller = self) except AgentException as excep: return errorResult(request, response, error = excep.getCode(), errorMsg = excep.getMsg(), controller = self) except Exception as excp: errorMsg = 'Exception downloading %s - traceback %s' % (str(excp), traceback.format_exc(2)) return errorResult(request, response, error = Errors.UNKNOWN_ERROR, errorMsg = errorMsg, controller = self)
def deactivatemanifest(self, service): """ deactivate a manifest """ LOG.info('activateManifest for service(%s) with body: %s', service, request.body) try: appGlobal = config['pylons.app_globals'] if not os.path.exists(manifestutil.manifestPath(service, 'active')): return errorResult(request, response, Errors.ACTIVEMANIFEST_MANIFEST_MISSING, 'Deactivate Manifest(%s) path missing' % (service), controller=self) deactivateThread = DeactivateManifest(appGlobal.threadMgr, service) self.injectJobCtx(deactivateThread) deactivateThread.start() deactivateThread.threadMgrEvent.wait() return statusResult(request, response, deactivateThread, controller=self) except Exception as excep: msg = 'Unknown error for deactivateManifest(%s) - %s - %s' % ( service, str(excep), traceback.format_exc(2)) return errorResult(request, response, error=Errors.UNKNOWN_ERROR, errorMsg=msg, controller=self)
def rollbackservice(self, service): """ rollback an existing service """ LOG.info('rollback to last active manifest for service(%s) ', service) manifest = None try: appGlobal = config['pylons.app_globals'] manifest = serviceutil.getPastManifest(service, 1) if manifest: activateThread = ActivateManifest(appGlobal.threadMgr, service, manifest, action=ActivateManifest.ACTION_ACTIVATION) self.injectJobCtx(activateThread) activateThread.start() activateThread.threadMgrEvent.wait() else: raise AgentException(Errors.MANIFEST_NOT_FOUND, "No rollback manifest found") return statusResult(request, response, activateThread, controller=self) except AgentException as excep: return errorResult(request, response, error=excep.getCode(), errorMsg=excep.getMsg(), controller=self) except Exception as excep: msg = 'Unknown error for rollback service(%s) - %s - %s' % (service, str(excep), traceback.format_exc(2)) return errorResult(request, response, error=Errors.UNKNOWN_ERROR, errorMsg=msg, controller=self)
def executeScript(self, service, scriptname): """ execute a script from remote location""" scriptpath = None try: # parse the body if (not request.body or request.body == ""): LOG.error('invalid body found in post command') return errorResult(request, response, Errors.INVALID_REQUEST, 'No body found in post command', controller=self) body = json.loads(request.body) paramobj = body['params'] if 'params' in body else [] params = paramobj if type(paramobj) == list else paramobj.split() LOG.info('%s' % (params)) scriptpath = None for package in manifestutil.packagesInManifest(service): scriptpathtmp = os.path.join( manifestutil.packagePath(service, 'active', package), 'cronus', 'scripts', scriptname) if os.path.exists(scriptpathtmp): scriptpath = scriptpathtmp break if not scriptpath: return errorResult(request, response, Errors.INVALID_REQUEST, 'script %s not found' % scriptname, controller=self) cmd = ['sudo', '-u', 'cronusapp', scriptpath] for param in params: param = param.encode('ascii', 'ignore') cmd.append(param) LOG.info('cmd = %s' % cmd) appGlobal = config['pylons.app_globals'] execThread = ExecThread(appGlobal.threadMgr, cmd) execThread.setLogLevel('info') execThread.start() execThread.threadMgrEvent.wait() return statusResult(request, response, execThread, controller=self) except Exception as excp: return errorResult( request, response, error=Errors.UNKNOWN_ERROR, errorMsg='Unknown error when executing cmd %s, %s - %s' % (scriptpath, str(excp), traceback.format_exc(2)), controller=self)
def executeCmd(self): """ execute a command synchronously """ try: # parse the body if (not request.body or request.body == ""): LOG.error('invalid body found in post command') return errorResult(request, response, 10001, 'No body found', controller=self) body = json.loads(request.body) cmd0 = body['cmd'] if 'cmd' in body else None needsudo = asbool( body['need-sudo']) if 'need-sudo' in body else False sudotgt = body['sudo-target'] if 'sudo-target' in body else None paramobj = body['params'] if 'params' in body else [] params = paramobj if type(paramobj) == list else paramobj.split() LOG.info('%s %s %s %s' % (cmd0, needsudo, sudotgt, params)) if cmd0 is None or cmd0 == '': return errorResult(request, response, 10002, 'No command found', controller=self) cmd = [cmd0.encode('ascii', 'ignore')] if needsudo: cmd.insert(0, 'sudo') if sudotgt is not None: sudotgt = sudotgt.encode('ascii', 'ignore') cmd.insert(1, sudotgt) cmd.insert(1, '-u') for param in params: param = param.encode('ascii', 'ignore') cmd.append(param) appGlobal = config['pylons.app_globals'] execThread = ExecThread(appGlobal.threadMgr, cmd) execThread.setLogLevel('info') execThread.start() return statusResult(request, response, execThread, controller=self) except Exception as excp: return errorResult( request, response, error=Errors.UNKNOWN_ERROR, errorMsg='Unknown error when executing cmd %s, %s - %s' % (cmd, str(excp), traceback.format_exc(2)), controller=self)
def deployservice(self, service): """ activate manifest, if already active then skip """ LOG.info('deploy service for service(%s) with body: %s', service, request.body) try: appGlobal = config['pylons.app_globals'] # parse the body if (request.body == ""): return errorResult(request, response, Errors.INVALID_REQUEST, 'No body found in post command', controller=self) requestjson = json.loads(request.body) manifest = requestjson['manifest'] packages = requestjson['package'] skipProp = asbool( requestjson['skipProp'] ) if 'skipProp' in requestjson else configutil.getConfigAsBool( 'download_skip_prop') skipActivation = asbool( requestjson['skipActivation'] ) if 'skipActivation' in requestjson else False # activate manifest if not already activated if manifestutil.getActiveManifest(service) == manifest: return doneResult(request, response, controller=self) deployServiceThread = DeployService(appGlobal.threadMgr, service, manifest, packages, skipProp=skipProp, skipActivation=skipActivation) self.injectJobCtx(deployServiceThread) deployServiceThread.start() deployServiceThread.threadMgrEvent.wait() return statusResult(request, response, deployServiceThread, controller=self) except Exception as excep: msg = 'Unknown error for activateManifest(%s/%s) - %s - %s' % ( service, manifest, str(excep), traceback.format_exc(2)) return errorResult(request, response, error=Errors.UNKNOWN_ERROR, errorMsg=msg, controller=self)
def cleanupProcess(self): """ cleanup services """ try: LOG.info('cleanup all application services') appGlobal = config['pylons.app_globals'] cleanupThread = ServicesCleanup(appGlobal.threadMgr, stopOnly=True) self.injectJobCtx(cleanupThread) cleanupThread.start() cleanupThread.threadMgrEvent.wait() return statusResult(request, response, cleanupThread, controller = self) except Exception as excp: return errorResult(request, response, error = Errors.UNKNOWN_ERROR, errorMsg = 'Unknown error when deleting services %s - %s' % (str(excp), traceback.format_exc(2)), controller = self)
def activatemanifest(self, service): """ activate manifest, if already active then skip """ LOG.info('activateManifest for service(%s) with body: %s', service, request.body) try: appGlobal = config['pylons.app_globals'] manifest = '' requestjson = json.loads(request.body) manifest = requestjson['manifest'] force = asbool( requestjson['force']) if 'force' in requestjson else False if not force and manifestutil.getActiveManifest( service) == manifest: return doneResult(request, response, controller=self) else: mf_path = os.path.join( ManifestController.manifestPath(service, manifest)) if (not os.path.exists(mf_path)): return errorResult(request, response, Errors.ACTIVEMANIFEST_MANIFEST_MISSING, 'Manifest(%s, %s) path missing' % (service, manifest), controller=self) LOG.debug('Manifest path exists: %s' % (mf_path)) activateThread = ActivateManifest(appGlobal.threadMgr, service, manifest) self.injectJobCtx(activateThread) activateThread.start() activateThread.threadMgrEvent.wait() return statusResult(request, response, activateThread, controller=self) except Exception as excep: msg = 'Unknown error for activateManifest(%s/%s) - %s - %s' % ( service, manifest, str(excep), traceback.format_exc(2)) return errorResult(request, response, error=Errors.UNKNOWN_ERROR, errorMsg=msg, controller=self)
def delete(self, service, manifest): """ Delete a new service object """ try: path = ManifestController.manifestPath(service, manifest) if (not os.path.isdir(path)): return errorResult(request, response, Errors.MANIFEST_NOT_FOUND, 'manifest (%s/%s) missing service' % (service, manifest), controller=self) # first check that this isn't the active manifest path = os.path.join(ServiceController.manifestPath(service), 'active') if (os.path.exists(path)): activePath = os.path.basename(readlink(path)) deletePath = os.path.basename( ManifestController.manifestPath(service, manifest)) if (activePath == deletePath): return errorResult( request, response, Errors.MANIFEST_DELETING_ACTIVE_MANIFEST, 'Manifest(%s, %s) attempting to delete active manifest' % (service, manifest), controller=self) # now try to delete the manifest directory appGlobal = config['pylons.app_globals'] manThread = ManifestDelete(appGlobal.threadMgr, service, manifest) self.injectJobCtx(manThread) manThread.start() manThread.threadMgrEvent.wait() return statusResult(request, response, manThread, controller=self) except Exception as excep: return errorResult( request, response, error=Errors.UNKNOWN_ERROR, errorMsg='Unknown error for delete manifest(%s/%s) - %s - %s' % (service, manifest, str(excep), traceback.format_exc(2)), controller=self)
def executeScript(self, service, scriptname): """ execute a script from remote location""" scriptpath = None try: # parse the body if (not request.body or request.body == ""): LOG.error('invalid body found in post command') return errorResult(request, response, Errors.INVALID_REQUEST, 'No body found in post command', controller = self) body = json.loads(request.body) paramobj = body['params'] if 'params' in body else [] params = paramobj if type(paramobj) == list else paramobj.split() LOG.info('%s' % (params)) scriptpath = None for package in manifestutil.packagesInManifest(service): scriptpathtmp = os.path.join(manifestutil.packagePath(service, 'active', package), 'cronus', 'scripts', scriptname) if os.path.exists(scriptpathtmp): scriptpath = scriptpathtmp break if not scriptpath: return errorResult(request, response, Errors.INVALID_REQUEST, 'script %s not found' % scriptname, controller = self) cmd = ['sudo', '-u', 'cronusapp', scriptpath] for param in params: param = param.encode('ascii', 'ignore') cmd.append(param) LOG.info('cmd = %s' % cmd) appGlobal = config['pylons.app_globals'] execThread = ExecThread(appGlobal.threadMgr, cmd) execThread.setLogLevel('info') execThread.start() execThread.threadMgrEvent.wait() return statusResult(request, response, execThread, controller = self) except Exception as excp: return errorResult(request, response, error = Errors.UNKNOWN_ERROR, errorMsg = 'Unknown error when executing cmd %s, %s - %s' % (scriptpath, str(excp), traceback.format_exc(2)), controller = self)
def post(self, module): """ Create a new module object """ try: LOG.info('Got a post request for module ' + module) if (request.body == ""): return errorResult(request, response, Errors.MODULE_PACKAGE_PARSING_ERROR, 'No body found in post command', controller=self) body = json.loads(request.body) package = body['package'] LOG.debug('pkgs = %s', package) appGlobal = config['pylons.app_globals'] # start a thread to create the package moduleThread = ModuleCreate(appGlobal.threadMgr, module, package) self.injectJobCtx(moduleThread) moduleThread.start() moduleThread.threadMgrEvent.wait() return statusResult(request, response, moduleThread, controller=self) except AgentException as excep: return errorResult(request, response, error=excep.getCode(), errorMsg=excep.getMsg(), controller=self) except Exception as excep: return errorResult( request, response, error=Errors.UNKNOWN_ERROR, errorMsg='Unknown error for create module(%s/%s) - %s - %s' % ('agent', module, str(excep), traceback.format_exc(2)), controller=self)
def deployservice(self, service): """ activate manifest, if already active then skip """ LOG.info('deploy service for service(%s) with body: %s', service, request.body) manifest = None try: appGlobal = config['pylons.app_globals'] # parse the body if (request.body == ""): return errorResult(request, response, Errors.INVALID_REQUEST, 'No body found in post command', controller = self) requestjson = json.loads(request.body) packages = requestjson['package'] if 'manifest' in requestjson: manifest = requestjson['manifest'] else: manifest = PackageUtil.getPackageVersion(packages[-1]) serviceutil.createServiceIfNeeded(service) # activate manifest if not already activated if manifestutil.getActiveManifest(service) == manifest: return doneResult(request, response, controller=self) else: # save metadata from payload pushedData = {} pushedData.update(requestjson) for key in ['manifest', 'package']: if key in pushedData: del pushedData[key] serviceutil.updateLcmMeta(service, pushedData) # deploy deployServiceThread = DeployService(appGlobal.threadMgr, service, manifest, packages) self.injectJobCtx(deployServiceThread) deployServiceThread.start() deployServiceThread.threadMgrEvent.wait() return statusResult(request, response, deployServiceThread, controller = self) except Exception as excep: msg = 'Unknown error for deployService(%s/%s) - %s - %s' % (service, manifest, str(excep), traceback.format_exc(2)) return errorResult(request, response, error = Errors.UNKNOWN_ERROR, errorMsg = msg, controller = self)
def delete(self, service): """ Delete a new service object """ from agent.lib.agent_thread.service_delete import ServiceDelete try: LOG.info('Got a delete request for service ' + service) path = ServiceController.servicePath(service) if (not os.path.exists(path) and not os.path.isdir(path)): return errorResult(request, response, Errors.SERVICE_NOT_FOUND, "No service(%s) found" % service, controller=self) # see if active manifest exist for the service if manifestutil.hasActiveManifest(service): return errorResult( request, response, Errors.MANIFEST_DELETING_ACTIVE_MANIFEST, 'Active manifest exists for service %s, deactivate the manifest first before deleting service' % (service), controller=self) # start the delete thread appGlobal = config['pylons.app_globals'] deleteThread = ServiceDelete(appGlobal.threadMgr, service, path) self.injectJobCtx(deleteThread) deleteThread.start() deleteThread.threadMgrEvent.wait() return statusResult(request, response, deleteThread, controller=self) except Exception as excep: return errorResult( request, response, error=Errors.UNKNOWN_ERROR, errorMsg='Unknown error when deleting service(%s) %s - %s' % (service, str(excep), traceback.format_exc(2)), controller=self)
def cleanupservice(self, service): """ cleanup an existing service """ LOG.info('cleanup service for service(%s) ', service) manifest = None try: appGlobal = config['pylons.app_globals'] # cleanup cleanupServiceThread = CleanupService(appGlobal.threadMgr, service) self.injectJobCtx(cleanupServiceThread) cleanupServiceThread.start() cleanupServiceThread.threadMgrEvent.wait() return statusResult(request, response, cleanupServiceThread, controller = self) except Exception as excep: msg = 'Unknown error for deployService(%s/%s) - %s - %s' % (service, manifest, str(excep), traceback.format_exc(2)) return errorResult(request, response, error = Errors.UNKNOWN_ERROR, errorMsg = msg, controller = self)
def safeshutdown(self): """ This controller shutdown the agent. This should not be exposed to external usage. This should only be used for testing and also for self update. """ LOG.info('[AGENT_SUICIDE] safe shutdown called. exiting the agent. This is an expected behavior when rest api shutdown is called. ') try: appGlobal = config['pylons.app_globals'] shutdownThread = SafeShutdown(appGlobal.threadMgr) self.injectJobCtx(shutdownThread) shutdownThread.start() shutdownThread.threadMgrEvent.wait() return statusResult(request, response, shutdownThread, controller = self) except Exception as excep: msg = 'Unknown error for safeshutdown %s - %s' % (str(excep), traceback.format_exc(2)) return errorResult(request, response, error = Errors.UNKNOWN_ERROR, errorMsg = msg, controller = self)
def get(self, uuid): """ Get the status of this particular thread. Use the uuid to grab the correct thread. return the progress and status of the thread. """ try: appGlobal = config['pylons.app_globals'] thread = appGlobal.threadMgr.getThreadByUuid(uuid) if (thread == None): return errorResult(request, response, Errors.STATUS_UUID_NOT_FOUND, 'Unable to find thread with uuid(%s)' % uuid, controller = self) except Exception as excep: return errorResult(request, response, error = Errors.UNKNOWN_ERROR, errorMsg = 'Unknown error for get status(%s) - %s, %s' % (uuid, str(excep), traceback.format_exc()), controller = self) return statusResult(request, response, thread, controller = self, maxProgress = 99 if thread.isAlive() else 100)
def deactivatemanifest(self, service): """ deactivate a manifest """ LOG.info('activateManifest for service(%s) with body: %s', service, request.body) try: appGlobal = config['pylons.app_globals'] if not os.path.exists(manifestutil.manifestPath(service, 'active')): return errorResult(request, response, Errors.ACTIVEMANIFEST_MANIFEST_MISSING, 'Deactivate Manifest(%s) path missing' % (service), controller = self) deactivateThread = DeactivateManifest(appGlobal.threadMgr, service) self.injectJobCtx(deactivateThread) deactivateThread.start() deactivateThread.threadMgrEvent.wait() return statusResult(request, response, deactivateThread, controller = self) except Exception as excep: msg = 'Unknown error for deactivateManifest(%s) - %s - %s' % (service, str(excep), traceback.format_exc(2)) return errorResult(request, response, error = Errors.UNKNOWN_ERROR, errorMsg = msg, controller = self)
def cleanupProcess(self): """ cleanup services """ try: LOG.info('cleanup all application services') appGlobal = config['pylons.app_globals'] cleanupThread = ServicesCleanup(appGlobal.threadMgr, stopOnly=True) self.injectJobCtx(cleanupThread) cleanupThread.start() cleanupThread.threadMgrEvent.wait() return statusResult(request, response, cleanupThread, controller=self) except Exception as excp: return errorResult( request, response, error=Errors.UNKNOWN_ERROR, errorMsg='Unknown error when deleting services %s - %s' % (str(excp), traceback.format_exc(2)), controller=self)
def validatePackage(self): """ Validate a given package, read prop file, do md5 checksum. Target folder is packageloc relative to repo_root. """ try: body = json.loads(request.body) package = str(body['package']) async = False if 'async' in body: async = asbool(body['async']) LOG.info('Request received for Validate Package %s' % package) appGlobal = config['pylons.app_globals'] vThread = ValidatePackage(appGlobal.threadMgr, package) if not async: vThread.join() return statusResult(request, response, vThread, controller = self) except Exception as excp: errorMsg = 'Error validating package %s' + excp.getMsg return errorResult(request, response, error = Errors.UNKNOWN_ERROR, errorMsg = errorMsg, controller = self)
def executeCmd(self): """ execute a command synchronously """ try: # parse the body if not request.body: LOG.error('invalid body found in post command') return errorResult(request, response, Errors.INVALID_REQUEST, 'No body found', controller = self) body = json.loads(request.body.encode('ascii', 'ignore')) if 'cmd' not in body: return errorResult(request, response, Errors.INVALID_REQUEST, 'No cmd found', controller = self) cmd0 = body['cmd'] hasSudo = ('sudoUser' in body and body['sudoUser']) sudoUser = body['sudoUser'] if ('sudoUser' in body and body['sudoUser'] != 'root') else None LOG.info('%s %s %s' % (cmd0, hasSudo, sudoUser)) cmd = cmd0.split() if hasSudo: cmd.insert(0, 'sudo') if sudoUser is not None: cmd.insert(1, sudoUser) cmd.insert(1, '-u') appGlobal = config['pylons.app_globals'] execThread = ExecThread(appGlobal.threadMgr, cmd) execThread.setLogLevel('info') contextutils.copyJobContexts(self, execThread) execThread.start() return statusResult(request, response, execThread, controller = self) except Exception as excp: return errorResult(request, response, error = Errors.UNKNOWN_ERROR, errorMsg = 'Unknown error when executing cmd %s, %s - %s' % (cmd, str(excp), traceback.format_exc(2)), controller = self)
def shutdown(self, service): ''' Controller to shutdown service ''' LOG.info('shutdown for service(%s)', service) try: appGlobal = config['pylons.app_globals'] if not os.path.exists(manifestutil.manifestPath(service, 'active')): return errorResult(request, response, Errors.ACTIVEMANIFEST_MANIFEST_MISSING, 'Active Manifest(%s) path missing' % (service), controller = self) shutdownThread = StartStopService(appGlobal.threadMgr, service, StartStopService.ACTION_SHUTDOWN) self.injectJobCtx(shutdownThread) shutdownThread.start() shutdownThread.threadMgrEvent.wait() return statusResult(request, response, shutdownThread, controller = self) except Exception as excep: return errorResult(request, response, error = Errors.UNKNOWN_ERROR, errorMsg = 'Unknown error for shutdown service(%s) - %s - %s' % (service, str(excep), traceback.format_exc(2)), controller = self)
def executeScript(self): """ execute a script from remote location""" scriptpath = None try: # parse the body if (not request.body or request.body == ""): LOG.error('invalid body found in post command') return errorResult(request, response, 10001, 'No body found in post command', controller=self) body = json.loads(request.body) scriptloc = body['script-location'].encode( 'ascii', 'ignore') if 'script-location' in body else None scriptname = body['script-name'].encode( 'ascii', 'ignore') if 'script-name' in body else None needsudo = asbool( body['need-sudo']) if 'need-sudo' in body else False sudotgt = body['sudo-target'].encode( 'ascii', 'ignore') if 'sudo-target' in body else None paramobj = body['params'] if 'params' in body else [] params = paramobj if type(paramobj) == list else paramobj.split() LOG.info('%s %s %s %s %s' % (scriptloc, scriptname, needsudo, sudotgt, params)) if scriptloc is None or scriptloc == '': return errorResult(request, response, 10003, 'Script location not found', controller=self) if scriptname is None or scriptname == '': return errorResult(request, response, 10003, 'Script name not found', controller=self) scriptpath = os.path.join(self.dataPath(), scriptname) LOG.info('scriptpath = %s' % scriptpath) os.system('wget %s -O %s' % (scriptloc, scriptpath)) if scriptpath is None or not os.path.exists(scriptpath): return errorResult(request, response, 10003, 'Failed to get script %s' % scriptpath, controller=self) rchmod(scriptpath, '+rx') cmd = [scriptpath] if needsudo: cmd.insert(0, 'sudo') if sudotgt is not None: cmd.insert(1, sudotgt) cmd.insert(1, '-u') for param in params: param = param.encode('ascii', 'ignore') cmd.append(param) LOG.info('cmd = %s' % cmd) appGlobal = config['pylons.app_globals'] execThread = ExecThread(appGlobal.threadMgr, cmd) execThread.setLogLevel('info') execThread.start() execThread.threadMgrEvent.wait() return statusResult(request, response, execThread, controller=self) except Exception as excp: return errorResult( request, response, error=Errors.UNKNOWN_ERROR, errorMsg='Unknown error when executing cmd %s, %s - %s' % (scriptpath, str(excp), traceback.format_exc(2)), controller=self)
def executeScript(self): """ execute a script from remote location""" scriptpath = None try: # parse the body if (not request.body or request.body == ""): LOG.error('invalid body found in post command') return errorResult(request, response, 10001, 'No body found in post command', controller = self) body = json.loads(request.body.encode('ascii', 'ignore')) scriptloc = body['scriptLocation'] if 'scriptLocation' in body else None scriptname = body['scriptName'] if 'scriptName' in body else None hasSudo = ('sudoUser' in body and body['sudoUser']) sudoUser = body['sudoUser'] if ('sudoUser' in body and body['sudoUser'] != 'root') else None paramobj = body['params'] if 'params' in body else [] params = paramobj if type(paramobj) == list else paramobj.split() LOG.info('%s %s %s %s %s' % (scriptloc, scriptname, hasSudo, sudoUser, params)) if not scriptloc: return errorResult(request, response, Errors.INVALID_REQUEST, 'Script location not found', controller = self) if not scriptname: return errorResult(request, response, Errors.INVALID_REQUEST, 'Script name not found', controller = self) scriptpath = os.path.join(self.dataPath(), scriptname) LOG.info('scriptpath = %s' % scriptpath) utils.runsyscmd('wget %s -O %s' % (scriptloc, scriptpath)) if not os.path.exists(scriptpath): return errorResult(request, response, Errors.FILE_NOT_FOUND_ERROR, 'Failed to get script %s' % scriptpath, controller = self) utils.rchmod(scriptpath, '+rx') cmd = [scriptpath] if hasSudo: cmd.insert(0, 'sudo') if sudoUser: cmd.insert(1, sudoUser) cmd.insert(1, '-u') for param in params: cmd.append(param) LOG.info('cmd = %s' % cmd) appGlobal = config['pylons.app_globals'] execThread = ExecThread(appGlobal.threadMgr, cmd) execThread.setLogLevel('info') contextutils.copyJobContexts(self, execThread) execThread.start() execThread.threadMgrEvent.wait() return statusResult(request, response, execThread, controller = self) except Exception as excp: return errorResult(request, response, error = Errors.UNKNOWN_ERROR, errorMsg = 'Unknown error when executing cmd %s, %s - %s' % (scriptpath, str(excp), traceback.format_exc(2)), controller = self)
def post(self, service, manifest): """ Create a new service object """ from agent.lib.agent_thread.manifest_create import ManifestCreate try: LOG.info('Post for service (%s) and manifest (%s) with body: %s', service, manifest, request.body) # check to see if the manifest already exists path = ManifestController.manifestPath(service, manifest) if (os.path.isdir(path)): return doneResult(request, response, httpStatus=201, controller=self) # parse the body if (request.body == ""): return errorResult(request, response, Errors.MANIFEST_PACKAGE_PARSING_ERROR, 'No body found in post command', controller=self) body = json.loads(request.body) packages = body['package'] forcedPackages = body[ 'forcePackageName'] if 'forcePackageName' in body else None skipProp = asbool( body['skipProp'] ) if 'skipProp' in body else configutil.getConfigAsBool( 'download_skip_prop') LOG.debug('pkgs = %s, %s', packages, forcedPackages) # parse the package list for idx, package in enumerate(packages): # to support reuse of an package from an existing manifest (active if possible) # without sending the complete package location in request body if package.startswith('/'): packageRef = package tokens = package.split('/') pkgnamePrefix = tokens[-1].rstrip() fullPkgLoc = manifestutil.getPackageByName( service, manifest=None, pkgnamePrefix=pkgnamePrefix) if fullPkgLoc is None: return errorResult( request, response, Errors.MANIFEST_PACKAGE_DOES_NOT_EXIST, 'manifest (%s/%s) package (%s) does not exist' % (service, manifest, packages), controller=self) else: LOG.info( 'expanding package reuse ref %s with full package location %s' % (packageRef, fullPkgLoc)) packages[idx] = fullPkgLoc appGlobal = config['pylons.app_globals'] # start a thread to create the package manThread = ManifestCreate(appGlobal.threadMgr, service, manifest, packages, forcePackages=forcedPackages, skipProp=skipProp) self.injectJobCtx(manThread) manThread.start() manThread.threadMgrEvent.wait() return statusResult(request, response, manThread, controller=self) except AgentException as excep: return errorResult(request, response, error=excep.getCode(), errorMsg=excep.getMsg(), controller=self) except Exception as excep: return errorResult( request, response, error=Errors.UNKNOWN_ERROR, errorMsg='Unknown error for activateManifest(%s/%s) - %s - %s' % (service, manifest, str(excep), traceback.format_exc(2)), controller=self)