def test_multiple_manifest_create(self): """ when a manifest creation is in progress for a service, another creation should block """ packages = ["http://www.stackscaling.com/agentrepo/pkgA-1.2.0.unix.cronus"] service = 'foo' manifest1 = 'bar' manifest2 = 'car' try: for pkg in packages: mockDownloadPkg(pkg) path = ServiceController.manifestPath(service) os.makedirs(path) path = ServiceController.installedPkgPath(service) os.makedirs(path) except Exception as excep: LOG.warning('got an OS Exception - %s' % str(excep)) body = json.dumps({'package' : packages}) response1 = self.app.post(url(controller = 'manifest', action = 'post', service = service, manifest = manifest1), headers = {'Content-Type' : 'application/json'}, params = body) self.assertEquals(response1.status_int, 200, 'Manifest1 Post assert - should go through') try: response2 = self.app.post(url(controller = 'manifest', action = 'post', service = service, manifest = manifest2), headers = {'Content-Type' : 'application/json'}, params = body) self.assertFalse(True, 'Expected an exception but did not get one!') except AppError: pass checkStatus(self, 'create manifest bar', response1, timeout = 25) self.assertTrue(islink(os.path.join(manifestutil.manifestPath('foo', 'bar'), 'pkgA'))) self.assertFalse(islink(os.path.join(manifestutil.manifestPath('foo', 'car'), 'pkgA')))
def log(self, service, manifest): """ Get manifest logs """ LOG.info('Get for service (%s) and manifest (%s)', service, manifest) try: # first check that the manifest directory exists 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) packageList = manifestutil.packagesInManifest(service, manifest) return ModulelogController.prepareOutput( packageList, ("/log/list/applog?service=%s&manifest=%s&package=" % (service, manifest)), manifestutil.manifestPath(service), "List Of Packages") except OSError as excp: return errorResult(request, response, Errors.MANIFEST_PATH_ERROR, 'Manifest(%s, %s) path error: %s' % (service, manifest, str(excp)), 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 test_post3_pkg_already_installed(self): createManifest(self) # now lets remove the manifest path path = os.path.join(manifestutil.manifestPath('foo', 'bar')) shutil.rmtree(path) # now create the manifest again createManifest(self) self.assertTrue(os.path.exists(os.path.join(PackageMgr.packagePath(), 'perlserver-1.0.0.unix.cronus'))) self.assertTrue(os.path.exists(os.path.join(ServiceController.installedPkgPath('foo'), 'perlserver', '1.0.0.unix', 'cronus', 'scripts', 'activate'))) self.assertTrue(islink(os.path.join(manifestutil.manifestPath('foo', 'bar'), 'perlserver')))
def log(self, service): """ Get service logs """ if service == "": return errorResult(request, response, Errors.LOG_PARAM_REQUIRED, "Missing service", controller=self) if not os.path.isdir(manifestutil.manifestPath(service)): return errorResult( request, response, Errors.SERVICE_NOT_FOUND, "Service specified is not found", controller=self ) packageList = manifestutil.packagesInManifest(service) return ModulelogController.prepareOutput( packageList, "/log/list/applog?service=" + service + "&package=", manifestutil.manifestPath(service), "List Of Packages", )
def test_delete(self): createManifest(self) response = self.app.delete(url(controller = 'manifest', action = 'delete', service = "foo", manifest = "bar"), expect_errors = True) print '*************** = ' + response.body self.assertEquals(200, response.status_int) for _ in range(10): if not os.path.isdir(manifestutil.manifestPath('foo', 'bar')): break else: time.sleep(0.1) self.assertFalse(os.path.isdir(manifestutil.manifestPath('foo', 'bar')))
def buildTokenCache(authztoken): """ build in memory cache for security tokens """ # find all pub keys in agent and encrypt the security token with them appGlobal = config['pylons.app_globals'] pubKeyDir = os.path.join(manifestutil.manifestPath('agent'), 'agent', 'cronus', 'keys') LOG.info('key directory %s' % pubKeyDir) if os.path.exists(pubKeyDir): try: import pki from M2Crypto import X509 pubKeyFiles = [ f for f in os.listdir(pubKeyDir) if re.match(r'.*\.cert', f) ] LOG.info('key files %s' % pubKeyFiles) for pubKeyFile in pubKeyFiles: # reload the certs from disk certf = open(os.path.join(pubKeyDir, pubKeyFile), 'r') ca_cert_content = certf.read() certf.close() cert = X509.load_cert_string(ca_cert_content) # pub = RSA.load_pub_key(os.path.join(pubKeyDir, pubKeyFile)) encryptedToken = pki.encrypt(cert.get_pubkey(), authztoken) appGlobal.encryptedtokens[pubKeyFile] = encryptedToken LOG.info('token %s=%s' % (pubKeyFile, encryptedToken)) except BaseException as excep: LOG.error('Error loading pki keys %s - %s' % (str(excep), traceback.format_exc(2)))
def __activateManifest(self): """ activate a manifest """ LOG.info("Activate Manifest %s - %s" % (self.__service, self.__manifest)) # make sure manifest to be activated exist manifestPath = manifestutil.manifestPath(self.__service, self.__manifest) if (not os.path.exists(manifestPath)): LOG.error('Manifest %s does not exist, fail activation' % self.__manifest) raise AgentException( Errors.MANIFEST_NOT_FOUND, 'Manifest %s does not exist' % self.__manifest) # check to see if the manifest already active activeManifest = manifestutil.activeManifestPath(self.__service) if activeManifest == self.__manifest: LOG.info('Manifest %s already active, skip activation' % self.__manifest) return from agent.lib.agent_thread.activate_manifest import ActivateManifest activateThread = ActivateManifest(self._threadMgr, self.__service, self.__manifest) contextutils.copycontexts(self, activateThread, contextutils.CTX_NAMES) activateThread.run() status = activateThread.getStatus() if (status.has_key('error') and status['error']): raise AgentException(status['error'], status['errorMsg'])
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 buildTokenCache(authztoken): """ build in memory cache for security tokens """ # find all pub keys in agent and encrypt the security token with them appGlobal = config['pylons.app_globals'] pubKeyDir = os.path.join(manifestutil.manifestPath('agent'), 'agent', 'cronus', 'keys') LOG.info('key directory %s' % pubKeyDir) if os.path.exists(pubKeyDir): try: import pki from M2Crypto import X509 pubKeyFiles = [f for f in os.listdir(pubKeyDir) if re.match(r'.*\.cert', f)] LOG.info('key files %s' % pubKeyFiles) for pubKeyFile in pubKeyFiles: # reload the certs from disk certf = open(os.path.join(pubKeyDir, pubKeyFile), 'r') ca_cert_content = certf.read() certf.close() cert = X509.load_cert_string(ca_cert_content) # pub = RSA.load_pub_key(os.path.join(pubKeyDir, pubKeyFile)) encryptedToken = pki.encrypt(cert.get_pubkey(), authztoken) appGlobal.encryptedtokens[pubKeyFile] = encryptedToken LOG.info('token %s=%s' % (pubKeyFile, encryptedToken)) except BaseException as excep: LOG.error('Error loading pki keys %s - %s' % (str(excep), traceback.format_exc(2)))
def doRun(self): """ Main body of the thread """ errorMsg = "" errorCode = None failed = False activeManifest = None try: activePath = manifestutil.manifestPath(self._service, 'active') # make sure that the active path exists and it is a link # Should we check this again since we already have a check in action controller if not os.path.exists(activePath) or not islink(activePath): raise AgentException(error = Errors.ACTIVEMANIFEST_MANIFEST_MISSING, errorMsg = 'No active manifest - cannot restart service') activeManifest = os.path.basename(readlink(activePath)) self.__lcmActionManifest(self._service, activeManifest, self.__action) self._LOG.info('Done: %s service for (%s/%s)' % (self.__action, self._service, activeManifest)) self._updateStatus(progress = 100) except AgentException as exc: failed = True errorMsg = '%s Service - Agent Exception - %s' % (self.__action, exc.getMsg()) errorCode = exc.getCode() except Exception as exc: failed = True errorMsg = '%s Service - Unknown error - (%s/%s) - %s - %s' \ % (self.__action, self._service, self._manifest, str(exc), traceback.format_exc(5)) errorCode = Errors.UNKNOWN_ERROR finally: if failed: self._LOG.error(errorMsg) self._updateStatus(httpStatus = 500, error = errorCode, errorMsg = errorMsg)
def __activateManifest(self): """ activate a manifest """ LOG.info("Activate Manifest %s - %s" % (self.__service, self.__manifest)) # make sure manifest to be activated exist manifestPath = manifestutil.manifestPath(self.__service, self.__manifest) if (not os.path.exists(manifestPath)): LOG.error('Manifest %s does not exist, fail activation' % self.__manifest) raise AgentException(Errors.MANIFEST_NOT_FOUND, 'Manifest %s does not exist' % self.__manifest) # check to see if the manifest already active activeManifest = manifestutil.activeManifestPath(self.__service) if activeManifest == self.__manifest: LOG.info('Manifest %s already active, skip activation' % self.__manifest) return from agent.lib.agent_thread.activate_manifest import ActivateManifest activateThread = ActivateManifest(self._threadMgr, self.__service, self.__manifest) contextutils.copycontexts(self, activateThread, contextutils.CTX_NAMES) activateThread.run() status = activateThread.getStatus() if (status.has_key('error') and status['error']): raise AgentException(status['error'], status['errorMsg'])
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 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 __activateManifest(self): """ activate a manifest """ LOG.info("Activate Manifest %s - %s" % (self.__service, self.__manifest)) # make sure manifest to be activated exist manifestPath = manifestutil.manifestPath(self.__service, self.__manifest) if (not os.path.exists(manifestPath)): LOG.error('Manifest %s does not exist, fail activation' % self.__manifest) raise AgentException(Errors.MANIFEST_NOT_FOUND, 'Manifest %s does not exist' % self.__manifest) # check to see if the manifest already active activeManifest = manifestutil.activeManifestPath(self.__service) if activeManifest == self.__manifest: LOG.info('Manifest %s already active, skip activation' % self.__manifest) return # activating new agent is going to kill agent process, update progress to 100% and flush all progress now self._updateProgress(100) status = self.status2msg() msg = json.dumps(status) UUIDLOG.info('%s output start %s %s output end' % (self.getUuid(), msg, self.getUuid())) from agent.lib.agent_thread.activate_manifest import ActivateManifest activateThread = ActivateManifest(self._threadMgr, self.__service, self.__manifest, parentId = self.getUuid()) contextutils.copycontexts(self, activateThread, contextutils.CTX_NAMES) activateThread.run() self._addChildExeThreadId(activateThread.getChildExeThreadIds()) status = activateThread.getStatus() if (status.has_key('error') and status['error']): raise AgentException(status['error'], status['errorMsg'])
def testGet(self): path = manifestutil.manifestPath('foo', 'bar') os.makedirs(path) path = manifestutil.manifestPath('foo', 'baz') os.makedirs(path) activePath = os.path.join(ServiceController.manifestPath('foo'), 'active') symlink('bar', activePath) response = self.app.get(url(controller='service', service='foo', action='get'), expect_errors = True) body = json.loads(response.body) print "************** response = %s" % body assert body['progress'] == 100 assert body['result']['activemanifest'] == 'bar' assert body['result']['manifest'] == ['bar', 'baz']
def listPackages(self): """ listPackages """ service = request.params.get('service', '') package = request.params.get('package', '') manifest = request.params.get('manifest', 'active') if (service == ''): c.errorMsg = 'missing service parameter from request' c.errorCode = Errors.LOG_PARAM_REQUIRED return render('/derived/error.html') if (package != ''): return ModulelogController.doAppLogFile('list') if (not os.path.isdir(manifestPath(service, manifest))): return ModulelogController.doListManifests(service) packageList = packagesInManifest(service, manifest) return ModulelogController.prepareOutput( packageList, "/log/list/applog?service=" + service + "&manifest=" + manifest + "&package=", manifestPath(service, manifest), "List Of Packages")
def test_post2(self): # successful post createManifest(self) self.assertTrue(os.path.exists(os.path.join(PackageMgr.packagePath(), 'perlserver-1.0.0.unix.cronus'))) self.assertTrue(os.path.exists(os.path.join(manifestutil.installedPkgRootPath('foo'), 'perlserver', '1.0.0.unix', 'cronus', 'scripts', 'activate'))) self.assertTrue(islink(os.path.join(manifestutil.manifestPath('foo', 'bar'), 'perlserver'))) self.assertTrue(islink(os.path.join(manifestutil.installedPkgRootPath('foo'), 'perlserver', '1.0.0.unix', '.appdata')))
def test_package_reuse(self): createManifest(self) body = json.dumps({'package' : ['/packages/perlserver']}) body = self.app.post(url(controller = 'manifest', action = 'post', service = "foo", manifest = "baz"), headers = {'Content-Type' : 'application/json'}, params = body, expect_errors = True) self.assertTrue(os.path.exists(os.path.join(PackageMgr.packagePath(), 'perlserver-1.0.0.unix.cronus'))) self.assertTrue(os.path.exists(os.path.join(ServiceController.installedPkgPath('foo'), 'perlserver', '1.0.0.unix', 'cronus', 'scripts', 'activate'))) self.assertTrue(islink(os.path.join(manifestutil.manifestPath('foo', 'bar'), 'perlserver'))) for _ in range(10): if islink(os.path.join(manifestutil.manifestPath('foo', 'baz'), 'perlserver')): break time.sleep(1) self.assertTrue(islink(os.path.join(manifestutil.manifestPath('foo', 'baz'), 'perlserver')))
def log(self, service): """ Get service logs """ if (service == ''): return errorResult(request, response, Errors.LOG_PARAM_REQUIRED, 'Missing service', controller=self) if (not os.path.isdir(manifestutil.manifestPath(service))): return errorResult(request, response, Errors.SERVICE_NOT_FOUND, 'Service specified is not found', controller=self) packageList = manifestutil.packagesInManifest(service) return ModulelogController.prepareOutput( packageList, "/log/list/applog?service=" + service + "&package=", manifestutil.manifestPath(service), "List Of Packages")
def test_post_without_service(self): body = json.dumps({'package' : ['http://github.com/yubin154/cronusagent/blob/master/agent/agent/tests/unit/packages/perlserver-1.0.0.unix.cronus']}) response = self.app.post(url(controller = 'manifest', action = 'post', service = "foo", manifest = "bar"), headers = {'Content-Type' : 'application/json'}, params = body) assert response.status_int == 200, 'Manifest Post assert' time.sleep(1) self.assertFalse(os.path.exists(manifestutil.manifestPath('foo', 'bar')))
def testServiceFromPath(self): servicepath = manifestutil.servicePath('foo') print servicepath, manifestutil.serviceFromPath(servicepath) assert 'foo' == manifestutil.serviceFromPath(servicepath) servicepath = manifestutil.servicePath('.envfoo.poolbar.machinebaz') assert '.envfoo.poolbar.machinebaz' == manifestutil.serviceFromPath(servicepath) manifestpath = manifestutil.manifestPath('foo', 'bar') assert 'foo' == manifestutil.serviceFromPath(manifestpath) manifestpaths = ['somedummypath', manifestpath] assert 'foo' == manifestutil.serviceFromPath(manifestpaths)
def test_same_pkg_download_parallel(self): packages = ['http://www.stackscaling.com/agentrepo/pkgA-1.2.0.unix.cronus'] manifest1 = 'bar' manifest2 = 'blah' service1 = 'foo' service2 = 'lah' try: for pkg in packages: mockDownloadPkg(pkg) path = ServiceController.manifestPath(service1) os.makedirs(path) path = ServiceController.installedPkgPath(service1) os.makedirs(path) path = ServiceController.downloadedPkgPath(service1) os.makedirs(path) path = ServiceController.manifestPath(service2) os.makedirs(path) path = ServiceController.installedPkgPath(service2) os.makedirs(path) path = ServiceController.downloadedPkgPath(service2) os.makedirs(path) except Exception as excep: LOG.warning('got an OS Exception - %s' % str(excep)) body = json.dumps({'package' : packages}) response1 = self.app.post(url(controller = 'manifest', action = 'post', service = service1, manifest = manifest1), headers = {'Content-Type' : 'application/json'}, params = body) assert response1.status_int == 200, 'Manifest Post assert' response2 = self.app.post(url(controller = 'manifest', action = 'post', service = service2, manifest = manifest2), headers = {'Content-Type' : 'application/json'}, params = body) assert response2.status_int == 200, 'Manifest Post assert' checkStatus(self, 'create manifest bar', response1, timeout = 25) checkStatus(self, 'create manifest baz', response2, timeout = 25) self.assertTrue(os.path.exists(os.path.join(PackageMgr.packagePath(), 'pkgA-1.2.0.unix.cronus'))) self.assertTrue(islink(os.path.join(manifestutil.manifestPath('foo', 'bar'), 'pkgA'))) self.assertTrue(islink(os.path.join(manifestutil.manifestPath('lah', 'blah'), 'pkgA')))
def testServiceFromPath(self): servicepath = manifestutil.servicePath('foo') print servicepath, manifestutil.serviceFromPath(servicepath) assert 'foo' == manifestutil.serviceFromPath(servicepath) servicepath = manifestutil.servicePath('.envfoo.poolbar.machinebaz') assert '.envfoo.poolbar.machinebaz' == manifestutil.serviceFromPath( servicepath) manifestpath = manifestutil.manifestPath('foo', 'bar') assert 'foo' == manifestutil.serviceFromPath(manifestpath) manifestpaths = ['somedummypath', manifestpath] assert 'foo' == manifestutil.serviceFromPath(manifestpaths)
def test_post_manifest_inprogress_ok(self): service = 'foo' manifest = 'blahblah' try: path = ServiceController.servicePath(service) if os.path.exists(path): shutil.rmtree(path) path = ServiceController.manifestPath(service) os.makedirs(path) path = ServiceController.installedPkgPath(service) os.makedirs(path) inProgressPath = ManifestCreate.inProgress(manifestutil.manifestPath(service, manifest)) os.makedirs(inProgressPath) path = ServiceController.downloadedPkgPath(service) os.makedirs(path) except Exception as excep: LOG.warning('got an OS Exception - %s' % str(excep)) createManifest(self, ["http://github.com/yubin154/cronusagent/blob/master/agent/agent/tests/unit/packages/pkgA-1.2.0.unix.cronus"], manifest = 'blahblah', createDirs = False) self.assertTrue(islink(os.path.join(manifestutil.manifestPath('foo', 'blahblah'), 'pkgA')))
def doRun(self): """ Main body of the thread """ errorMsg = "" errorCode = None failed = False activeManifest = None try: activePath = manifestutil.manifestPath(self._service, 'active') # make sure that the active path exists and it is a link # Should we check this again since we already have a check in action controller if not os.path.exists(activePath) or not islink(activePath): raise AgentException(error = Errors.ACTIVEMANIFEST_MANIFEST_MISSING, errorMsg = 'Service %s has no active manifest' % self._service) activeManifest = os.path.basename(readlink(activePath)) if self.__action == StartStopService.ACTION_SHUTDOWN: self._shutdownManifest(self._service, activeManifest, 50, 90) elif self.__action == StartStopService.ACTION_STARTUP: self._startupManifest(self._service, activeManifest, 50, 90) elif self.__action == StartStopService.ACTION_RESTART: self._restartManifest(self._service, activeManifest, 10, 90) else: raise AgentException(error = Errors.INVALID_LIFECYCLE_ACTION, errorMsg = 'Invalid life cycle action - %s' % self.__action) self._LOG.info('Done: %s service for (%s/%s)' % (self.__action, self._service, activeManifest)) self._updateStatus(progress = 100) except AgentException as exc: failed = True errorMsg = '%s Service - Agent Exception - %s' % (self.__action, exc.getMsg()) errorCode = exc.getCode() except Exception as exc: failed = True errorMsg = '%s Service - Unknown error - (%s/%s) - %s - %s' \ % (self.__action, self._service, self._manifest, str(exc), traceback.format_exc(5)) errorCode = Errors.UNKNOWN_ERROR finally: if failed: self._LOG.error(errorMsg) if not self._skipCleanupOnFailure() and self.__action != StartStopService.ACTION_SHUTDOWN and self._service and activeManifest: try: self._LOG.info('%s Service %s failed, shutdown to cleanup' % (self.__action, self._service)) self._shutdownManifest(self._service, activeManifest, 91, 99) except BaseException as excep: self._LOG.error('Cleanup failed - %s' % str(excep)) self._updateStatus(httpStatus = 500, error = errorCode, errorMsg = errorMsg)
def __delAllExceptActiveManifests(self, service): ''' Delete all manifests in the given service except active link and corresponding manifest (if one exists). Doesn't delete the corresponding dir in installed-packages (similar to 'delete manifest') ''' manifests = manifestutil.getManifests(service) active = manifestutil.getActiveManifest(service) if active and len(active) != 0: # 'active' can be none manifests.remove(active) for mft in manifests: mf_path = manifestutil.manifestPath(service, mft) ServiceDelete.deleteFolderContents(mf_path)
def doRun(self): """ Main body of the thread """ try: # now try to delete the manifest directory shutil.rmtree(manifestutil.manifestPath(self.service, self.manifest)) self._updateStatus(progress = 100) except OSError as excp: msg = 'Manifest(%s, %s) path error: %s' % (self.service, self.manifest, str(excp)) self._updateStatus(httpStatus = 500, error = Errors.MANIFEST_PATH_ERROR, errorMsg = msg) except Exception as exc: msg = 'Unknown error when deleting service %s - %s' % (self.service, str(exc)) errCode = Errors.UNKNOWN_ERROR self._updateStatus(httpStatus = 500, error = errCode, errorMsg = msg)
def doRun(self): """ Main body of the thread """ errorMsg = "" errorCode = None failed = False activeManifest = None try: activePath = manifestutil.manifestPath(self._service, 'active') # make sure that the active path exists and it is a link # Should we check this again since we already have a check in action controller if not os.path.exists(activePath) or not islink(activePath): raise AgentException(error = Errors.ACTIVEMANIFEST_MANIFEST_MISSING, errorMsg = 'No active manifest - cannot restart service') activeManifest = os.path.basename(readlink(activePath)) if self.__action == StartStopService.ACTION_SHUTDOWN: self.__shutdownManifest(self._service, activeManifest) elif self.__action == StartStopService.ACTION_STARTUP: self.__startupManifest(self._service, activeManifest) elif self.__action == StartStopService.ACTION_RESTART: self.__restartManifest(self._service, activeManifest) elif self.__action == StartStopService.ACTION_REBOOT: self.__rebootManifest(self._service, activeManifest) else: raise AgentException(error = Errors.INVALID_LIFECYCLE_ACTION, errorMsg = 'Invalid life cycle action - %s' % self.__action) self.__LOG.info('Done: %s service for (%s/%s)' % (self.__action, self._service, activeManifest)) self._updateStatus(progress = 100) except AgentException as exc: failed = True errorMsg = '%s Service - Agent Exception - %s' % (self.__action, exc.getMsg()) errorCode = exc.getCode() except Exception as exc: failed = True errorMsg = '%s Service - Unknown error - (%s/%s) - %s - %s' \ % (self.__action, self._service, self._manifest, str(exc), traceback.format_exc(5)) errorCode = Errors.UNKNOWN_ERROR finally: if failed: self.__LOG.error(errorMsg) if not self._skipCleanupOnFailure() and self.__action != StartStopService.ACTION_SHUTDOWN and self._service and activeManifest: try: self.__LOG.info('%s Service %s failed, shutdown to cleanup' % (self.__action, self._service)) self.__shutdownManifest(self._service, activeManifest) except BaseException as excep: self.__LOG.error('Cleanup failed - %s' % str(excep)) self._updateStatus(httpStatus = 500, error = errorCode, errorMsg = errorMsg)
def get(self, service, manifest): """ Get a new service object """ LOG.info('Get for service (%s) and manifest (%s)', service, manifest) try: # first check that the manifest directory exists 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) # now go through the list of packages in the manifest packages = [] packageLinkNames = glob.glob(os.path.join(manifestutil.manifestPath(service, manifest), '*')) for packageLink in packageLinkNames: package = readlink(packageLink) LOG.debug('Get package (%s) in manifest (%s)', package, manifest) # deal with the case where the package has a / or \ (for windoz) at the end package = package.rstrip('/') package = package.rstrip('\\') # the name of the package can be constructed from the last two path components (head, version) = os.path.split(package) (head, name) = os.path.split(head) LOG.debug('Add package %s-%s.cronus' % (name, version)) packages.append('%s-%s.cronus' % (name, version)) except OSError as excp: return errorResult(request, response, Errors.MANIFEST_PATH_ERROR, 'Manifest(%s, %s) path error: %s' % (service, manifest, str(excp)), controller=self) return doneResult(request, response, result=packages, controller=self)
def dumpMemory(self): """ dump what's in the class in memory """ dumpFile = os.path.join(manifestutil.manifestPath('agent'), 'agent', 'logs', 'memory.pickle') with open(dumpFile, 'w') as dump: for obj in gc.get_objects(): i = id(obj) size = sys.getsizeof(obj, 0) referents = [id(o) for o in gc.get_referents(obj) if hasattr(o, '__class__')] if hasattr(obj, '__class__'): cls = str(obj.__class__) cPickle.dump({'id': i, 'class': cls, 'size': size, 'referents': referents}, dump) return doneResult(request, response, controller = self)
def listPackages(self): """ list packages """ service = request.params.get('service', '') package = request.params.get('package', '') manifest = request.params.get('manifest', 'active') if (service == ''): c.errorMsg = 'missing service parameter from request' c.errorCode = Errors.LOG_PARAM_REQUIRED return render('/derived/error.html') if (package != ''): return ApplogController.doAppLogFile() if (not os.path.isdir(manifestPath(service, manifest))): return self.listManifests() packageList = packagesInManifest(service, manifest) return ApplogController.prepareOutput( packageList, "/applog/applog?service=%s&manifest=%s&package=" % (service, manifest), manifestPath(service, manifest), "List Of Packages")
def getLocalPyPkg(): """ reuse of local python package instead of download it again from source of truth, this should be the common use case for selfupdate without needing to update the python package """ activeManifest = manifestutil.getActiveManifest('agent') activePyLink = os.path.join(manifestutil.manifestPath('agent', activeManifest), 'python_package') if (os.path.exists(activePyLink)): activePyPath = readlink(activePyLink) pyVersion = os.path.basename(activePyPath) pyPkgName = ('python_package-%s' % pyVersion) if AgentUpdate.nameRe.match(pyPkgName): return ('http://localhost:12020/%s.cronus' % pyPkgName) else: raise AgentException(Errors.PACKAGE_SCHEME_ERROR, 'package name %s is not valid' % pyPkgName)
def test_post3_already_installed_manifest(self): createManifest(self) self.assertTrue(os.path.exists(os.path.join(PackageMgr.packagePath(), 'perlserver-1.0.0.unix.cronus'))) self.assertTrue(os.path.exists(os.path.join(ServiceController.installedPkgPath('foo'), 'perlserver', '1.0.0.unix', 'cronus', 'scripts', 'activate'))) self.assertTrue(islink(os.path.join(manifestutil.manifestPath('foo', 'bar'), 'perlserver'))) body = json.dumps({'package' : ['http://github.com/yubin154/cronusagent/blob/master/agent/agent/tests/unit/packages/perlserver-1.0.0.unix.cronus']}) response = self.app.post(url(controller = 'manifest', action = 'post', service = "foo", manifest = "bar"), headers = {'Content-Type' : 'application/json'}, params = body, expect_errors = True) self.assertEquals(201, response.status_int, 'Manifest Post assert') body = json.loads(response.body) assert response.status_int == 201, 'Manifest Post assert'
def log(self, service, manifest): """ Get manifest logs """ LOG.info('Get for service (%s) and manifest (%s)', service, manifest) try: # first check that the manifest directory exists 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) packageList = manifestutil.packagesInManifest(service, manifest) return ApplogController.prepareOutput(packageList, ("/log/list/applog?service=%s&manifest=%s&package=" % (service, manifest)), manifestutil.manifestPath(service), "List Of Packages") except OSError as excp: return errorResult(request, response, Errors.MANIFEST_PATH_ERROR, 'Manifest(%s, %s) path error: %s' % (service, manifest, str(excp)), controller=self)
def __createManifest(self): """ create a manifest """ service = 'agent' LOG.info("Create Manifest %s - %s - %s" % (service, self.__manifest, str(self.__packages))) path = manifestutil.manifestPath(service, self.__manifest) # check to see if the manifest already exists if (os.path.isdir(path)): LOG.info('Manifest %s already exist, skip creating' % self.__manifest) return from agent.lib.agent_thread.manifest_create import ManifestCreate manThread = ManifestCreate(self._threadMgr, service, self.__manifest, self.__packages, skipProp = self.__skipProp) contextutils.copycontexts(self, manThread, contextutils.CTX_NAMES) manThread.run() status = manThread.getStatus() if (status.has_key('error') and status['error']): raise AgentException(status['error'], status['errorMsg'])
def doRun(self): """ Main body of the thread """ try: # now try to delete the manifest directory shutil.rmtree( manifestutil.manifestPath(self.service, self.manifest)) self._updateStatus(progress=100) except OSError as excp: msg = 'Manifest(%s, %s) path error: %s' % ( self.service, self.manifest, str(excp)) self._updateStatus(httpStatus=500, error=Errors.MANIFEST_PATH_ERROR, errorMsg=msg) except Exception as exc: msg = 'Unknown error when deleting service %s - %s' % ( self.service, str(exc)) errCode = Errors.UNKNOWN_ERROR self._updateStatus(httpStatus=500, error=errCode, errorMsg=msg)
def getLocalPyPkg(): """ reuse of local python package instead of download it again from source of truth, this should be the common use case for selfupdate without needing to update the python package """ activeManifest = manifestutil.getActiveManifest('agent') activePyLink = os.path.join( manifestutil.manifestPath('agent', activeManifest), 'python_package') if (os.path.exists(activePyLink)): activePyPath = readlink(activePyLink) pyVersion = os.path.basename(activePyPath) pyPkgName = ('python_package-%s' % pyVersion) if AgentUpdate.nameRe.match(pyPkgName): return ('http://localhost:12020/%s.cronus' % pyPkgName) else: raise AgentException( Errors.PACKAGE_SCHEME_ERROR, 'package name %s is not valid' % pyPkgName)
def test_inprogress_pkg_download(self): service = 'foo' try: path = ServiceController.manifestPath(service) os.makedirs(path) path = ServiceController.installedPkgPath(service) os.makedirs(path) path = ServiceController.downloadedPkgPath(service) os.makedirs(path) inprogressPath = os.path.join(PackageMgr.packagePath(), 'perlserver-1.0.0.unix.cronus.inprogress') inprogressFile = open(inprogressPath, 'w') inprogressFile.write('somegarbage') inprogressFile.close() except Exception as excep: LOG.warning('got an OS Exception - %s' % str(excep)) createManifest(self) self.assertTrue(os.path.exists(os.path.join(PackageMgr.packagePath(), 'perlserver-1.0.0.unix.cronus'))) self.assertTrue(islink(os.path.join(manifestutil.manifestPath('foo', 'bar'), 'perlserver')))
def getExecOutput(self, uuid): """ get script output with an uuid """ LOG.info('get ouput for %s' % uuid) try: script = os.path.join(manifestutil.manifestPath('agent'), 'agent', 'cronus', 'scripts', 'execoutput') LOG.info('execoutput script %s' % script) if not uuid or uuid == '': raise AgentException(Errors.INVALID_REQUEST, 'uuid cannot be empty') tmp = [script, uuid] cmds = [] for cmd in tmp: cmds.append(cmd.encode('ascii', 'ignore')) cmdout = utils.runsyscmdwstdout(cmds) return cmdout except Exception as excep: return errorResult(request, response, error = Errors.UNKNOWN_ERROR, errorMsg = 'Error when get execoutput %s - %s' % (str(excep), traceback.format_exc(2)), controller = self)
def getTaskSlaReport(self, task, threshold=0, starttime=0, fmt='raw'): """ get task SLA report """ LOG.info('generating task SLA report') try: script = os.path.join(manifestutil.manifestPath('agent'), 'agent', 'cronus', 'scripts', 'perfmetric') LOG.info('task sla report script %s' % script) if not task or task == '': raise AgentException(Errors.INVALID_REQUEST, 'task name cannot be empty') tmp = [script, task, str(threshold), str(starttime), fmt] cmds = [] for cmd in tmp: cmds.append(cmd.encode('ascii', 'ignore')) cmdout = utils.runsyscmdwstdout(cmds) result = json.loads(cmdout) return doneResult(request, response, result=result, controller = self) except Exception as excep: return errorResult(request, response, error = Errors.UNKNOWN_ERROR, errorMsg = 'Error when getting task sla report %s - %s' % (str(excep), traceback.format_exc(2)), controller = self)
def __createManifest(self): """ create a manifest """ service = 'agent' LOG.info("Create Manifest %s - %s - %s" % (service, self.__manifest, str(self.__packages))) path = manifestutil.manifestPath(service, self.__manifest) # check to see if the manifest already exists if (os.path.isdir(path)): LOG.info('Manifest %s already exist, skip creating' % self.__manifest) return from agent.lib.agent_thread.manifest_create import ManifestCreate manThread = ManifestCreate(self._threadMgr, service, self.__manifest, self.__packages, skipProp=self.__skipProp) contextutils.copycontexts(self, manThread, contextutils.CTX_NAMES) manThread.run() status = manThread.getStatus() if (status.has_key('error') and status['error']): raise AgentException(status['error'], status['errorMsg'])
def testManifestPath(self): assert manifestutil.manifestPath( 'foo', 'bar').endswith('foo' + os.path.sep + 'manifests' + os.path.sep + 'bar')
def doRun(self): """ Main body of the thread """ spath = manifestutil.servicePath(self._service) self._updateProgress(1) errorMsg = "" errorCode = None failed = False ctxNames = ['guid', 'service'] try: # create service if not already exist if not os.path.exists(spath): os.makedirs(spath) os.makedirs(os.path.join(spath, 'manifests')) os.makedirs(os.path.join(spath, 'installed-packages')) os.makedirs(os.path.join(spath, 'modules')) os.makedirs(os.path.join(spath, 'downloaded-packages')) os.makedirs(os.path.join(spath, '.appdata')) os.makedirs(os.path.join(spath, '.data')) import pwd uname = pylons.config['app_user_account'] uid = pwd.getpwnam(uname).pw_uid gid = pwd.getpwnam(uname).pw_gid utils.rchown(os.path.join(spath, '.appdata'), uid, gid) # verify that the path exists if (not os.path.isdir(spath)): raise AgentException(Errors.UNKNOWN_ERROR, "Service(%s) was not created" % self._service) self._updateProgress(20) # create manifest if not already exist mpath = manifestutil.manifestPath(self._service, self._manifest) if (not os.path.exists(mpath) or not os.path.isdir(mpath)): self.__LOG.debug('pkgs = %s', self.__packages) # parse the package list for idx, package in enumerate(self.__packages): if package.startswith('/'): packageRef = package tokens = package.split('/') pkgnamePrefix = tokens[-1].rstrip() fullPkgLoc = manifestutil.getPackageByName(self._service, manifest = None, pkgnamePrefix = pkgnamePrefix) if fullPkgLoc is None: raise AgentException(Errors.MANIFEST_PACKAGE_DOES_NOT_EXIST, 'manifest (%s/%s) package (%s) does not exist' % (self._service, self._manifest, self.__packages)) else: self.__LOG.info('expanding package reuse ref %s with full package location %s' % (packageRef, fullPkgLoc)) self.__packages[idx] = fullPkgLoc # start a thread to create the package manThread = ManifestCreate(threadmgr.NULL_THREADMGR, self._service, self._manifest, self.__packages, skipProp = self.__skipProp) contextutils.copycontexts(self, manThread, ctxNames) manThread.run() status = manThread.getStatus() if (status['error'] != None): raise AgentException(status['error'], status['errorMsg']) self._updateProgress(60) if (not os.path.exists(mpath)): raise AgentException(Errors.ACTIVEMANIFEST_MANIFEST_MISSING, 'Manifest(%s, %s) path missing' % (self._service, self._manifest)) if not self.__skipActivation: activateThread = ActivateManifest(threadmgr.NULL_THREADMGR, self._service, self._manifest) contextutils.copycontexts(self, activateThread, ctxNames) activateThread.run() status = activateThread.getStatus() if (status['error'] != None): raise AgentException(status['error'], status['errorMsg']) # activte manifest if not already activated if manifestutil.getActiveManifest(self._service) != self._manifest: raise AgentException(Errors.ACTIVEMANIFEST_MANIFEST_MISSING, 'Manifest(%s, %s) path missing' % (self._service, self._manifest)) except SystemExit as exc: failed = True if (len(exc.args) == 2): # ok we got {err code, err msg} errorCode = exc.args[0] errorMsg = exc.args[1] except AgentException as exc: failed = True errorMsg = 'Deploy Service - Agent Exception - %s' % exc.getMsg() errorCode = exc.getCode() except Exception as exc: failed = True errorMsg = 'Deploy Service - Unknown error - (%s/%s) - %s - %s' \ % (self._service, self._manifest, str(exc), traceback.format_exc(5)) errorCode = Errors.UNKNOWN_ERROR finally: if failed: self.__LOG.warning(errorMsg) self._updateStatus(httpStatus = 500, error = errorCode, errorMsg = errorMsg) else: self._updateProgress(100)