def getManifests(service): """ return the list of manifests under a specific service """ from agent.lib.agent_thread.manifest_create import ManifestCreate manifests = [] dirContent = os.listdir(ServiceController.manifestPath(service)) for item in dirContent: path = os.path.join(ServiceController.manifestPath(service), item) if (os.path.isdir(path) and not ManifestCreate.isInProgress(path)): if (not islink(path)): manifests.append(item) return sorted(manifests)
def getAllSymLinks(service): """ return all the symlinks from manifests to packages for a given service""" LOG.debug('calling getAllSymLinks %s' % service) linkedPaths = [] manPath = ServiceController.manifestPath(service) LOG.debug('manifestPath is %s' % manPath) for path in os.listdir(manPath): LOG.debug('path is %s' % path) if not islink(os.path.join(manPath, path)): LOG.debug('path is dir not a link') pkgPaths = [ packageDir for packageDir in os.listdir(os.path.join(manPath, path)) ] LOG.debug('pkgPaths is %s' % pkgPaths) for pkgPath in pkgPaths: try: LOG.debug('pkgPath is %s' % pkgPath) if not os.path.isfile( os.path.join( manPath, path, pkgPath)) and islink( os.path.join(manPath, path, pkgPath)): LOG.debug('pkgPaths is %s' % pkgPath) targetPath = os.path.abspath( readlink(os.path.join(manPath, path, pkgPath))) linkedPaths.append(targetPath) LOG.debug('targetPath is %s ' % targetPath) except BaseException as exc: LOG.error('failed to read link for the pkg path %s' % str(exc)) return linkedPaths
def activateManifest(testController, manifest = 'bar', service = 'foo'): body = json.dumps({'manifest':manifest}) response = testController.app.post(url(controller = 'manifest', action = 'activate', service = service, manifest = manifest), headers = {'Content-Type' : 'application/json'}, params = body) assert response.status_int == 200, 'Action get assert' body = json.loads(response.body) tm = time.time() while (tm + 120 > time.time()): response = testController.app.get(body['status']) body = json.loads(response.body) LOG.debug("activateManifest ********** progress = %s" % body['progress']) if (int(body['progress']) == 100): break time.sleep(0.1) LOG.debug('status = ' + str(response.status_int)) assert response.status_int == 200, "HTTP response != 200" LOG.debug ('Status response body = %s' % str(body)) assert body['progress'] == 100 # let's make sure the link is there correctly activePath = os.path.join(ServiceController.manifestPath(service), 'active') LOG.debug ('active path = ' + activePath) assert islink(activePath) link = readlink(activePath) LOG.debug ('link = ' + link) assert link == manifest
def test_delete_active_manifest(self): createManifest(self) self.assertTrue(os.path.isdir(ServiceController.manifestPath('foo'))) currentPath = os.getcwd() os.chdir(ServiceController.manifestPath('foo')) manifestPath = 'bar' #ManifestController.manifestPath('foo', 'bar'); use short manifest name instead of full path symlink(manifestPath, 'active') os.chdir(currentPath) response = self.app.delete(url(controller = 'manifest', action = 'delete', service = "foo", manifest = "bar"), expect_errors = True) self.assertEquals(500, response.status_int) body = json.loads(response.body) self.assertEquals(Errors.MANIFEST_DELETING_ACTIVE_MANIFEST, body['error'])
def test_post_manifest_inprogress_ok(self): service = 'foo' manifest = 'blahblah' try: path = ServiceController.servicePath(service) if os.path.exists(path): if os.name == 'nt': cmd = 'rm -r %s' % path LOG.debug("running command %s" % cmd) os.system(cmd) else: shutil.rmtree(path) path = ServiceController.manifestPath(service) os.makedirs(path) path = ServiceController.installedPkgPath(service) os.makedirs(path) inProgressPath = ManifestCreate.inProgress(ManifestController.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(ManifestController.manifestPath('foo', 'blahblah'), 'pkgA')))
def manifestPath(service, manifest): """ compute the path to this manifest @param service: name of the service @param manifest: name of the manifest """ return os.path.join(ServiceController.manifestPath(service), manifest)
def test_post_manifest_inprogress_errorout(self): packages = ['http://github.com/yubin154/cronusagent/blob/master/agent/agent/tests/unit/packages/perlserver-1.0.0.unix.cronus'] manifest = 'bar' service = 'foo' try: path = ServiceController.manifestPath(service) os.makedirs(path) path = ServiceController.installedPkgPath(service) os.makedirs(path) path = ServiceController.downloadedPkgPath(service) os.makedirs(path) except Exception as excep: LOG.warning('got an OS Exception - %s' % str(excep)) body = json.dumps({'package' : packages}) response = self.app.post(url(controller = 'manifest', action = 'post', service = service, manifest = manifest), headers = {'Content-Type' : 'application/json'}, params = body) assert response.status_int == 200, 'Manifest Post assert' try: response = self.app.post(url(controller = 'manifest', action = 'post', service = service, manifest = manifest), headers = {'Content-Type' : 'application/json'}, params = body) #should error out! raise Exception('Oops! Expected AppError but did not get any') except AppError: pass
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 test_multiple_manifest_create(self): """ when a manifest creation is in progress for a service, another creation should block """ packages = ["http://repository.qa.ebay.com/cronus/test-data/agent/pkgA-1.2.0.unix.cronus"] service = 'foo' manifest1 = 'bar' manifest2 = 'car' try: 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(ManifestController.manifestPath('foo', 'bar'), 'pkgA'))) self.assertFalse(islink(os.path.join(ManifestController.manifestPath('foo', 'car'), 'pkgA')))
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 activateManifest(testController, manifest='bar', service='foo'): body = json.dumps({'manifest': manifest}) response = testController.app.post( url(controller='action', action='activatemanifest', service=service), headers={'Content-Type': 'application/json'}, params=body) assert response.status_int == 200, 'Action get assert' body = json.loads(response.body) tm = time.time() while (tm + 120 > time.time()): response = testController.app.get(body['status']) body = json.loads(response.body) LOG.debug("activateManifest ********** progress = %s" % body['progress']) if (int(body['progress']) == 100): break time.sleep(0.1) LOG.debug('status = ' + str(response.status_int)) assert response.status_int == 200, "HTTP response != 200" LOG.debug('Status response body = %s' % str(body)) assert body['progress'] == 100 # let's make sure the link is there correctly activePath = os.path.join(ServiceController.manifestPath(service), 'active') LOG.debug('active path = ' + activePath) assert islink(activePath) link = readlink(activePath) LOG.debug('link = ' + link) if os.name == 'nt': manifestPath = os.path.join(ServiceController.manifestPath(service), manifest) assert (link == manifestPath or link == manifest) else: assert link == manifest
def doRun(self): """ Main body of the thread """ errorMsg = "" errorCode = None failed = False try: activePath = os.path.join( ServiceController.manifestPath(self._service), 'active') oldManifest = None # make sure that if the active path exists, it's a link # if not log that and delete the link if (os.path.exists(activePath) and not os.name == 'nt' and not islink(activePath)): self.__LOG.error('%s is not a link. Attempted to delete' % activePath) shutil.rmtree(activePath) if (os.path.exists(activePath)): oldManifest = os.path.basename(readlink(activePath)) else: raise AgentException( error=Errors.ACTIVEMANIFEST_MANIFEST_MISSING, errorMsg='No active manifest - cannot deactivate service') self.__deactivateManifest(self._service, oldManifest) self.__removeSymlink(self._service) 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] raise exc except AgentException as exc: failed = True errorMsg = 'Deactivate Manifest - Agent Exception - %s' % exc.getMsg( ) errorCode = exc.getCode() except Exception as exc: failed = True errorMsg = 'Deactivate Manifest - Unknown error - (%s) - %s - %s' \ % (self._service, 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) self.__LOG.debug('Done: activate manifest for (%s)' % (self._service)) self._updateProgress(100)
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 getActiveManifestPath(service): """ return the name of the active manifest under a specific service @param service: name of service @return: path of active manifest, or empty string if no active manifest """ activePath = os.path.join(ServiceController.manifestPath(service), 'active') if (not os.path.exists(activePath)): return '' return readlink(activePath)
def doRun(self): """ Main body of the thread """ errorMsg = "" errorCode = None failed = False activeManifest = None try: activePath = os.path.join( ServiceController.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 reset service') activeManifest = os.path.basename(readlink(activePath)) self.__shutdownManifest(self._service, activeManifest) self.__deactivateManifest(self._service, activeManifest) self.__activateManifest(self._service, activeManifest) self.__startupManifest(self._service, activeManifest) self.__LOG.info('Done: reset service for (%s/%s)' % (self._service, activeManifest)) self._updateStatus(progress=100) except AgentException as exc: failed = True errorMsg = 'Activate Manifest - Agent Exception - %s' % exc.getMsg( ) errorCode = exc.getCode() except Exception as exc: failed = True errorMsg = 'Activate Manifest - 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.error(errorMsg) if self._service and activeManifest: try: self.__LOG.info( 'Reset service %s failed, shutdown to cleanup' % 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 test_same_pkg_download_parallel(self): packages = ['http://repository.qa.ebay.com/cronus/test-data/agent/perlserver-1.0.0.unix.cronus'] manifest1 = 'bar' manifest2 = 'blah' service1 = 'foo' service2 = 'lah' try: 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(), 'perlserver-1.0.0.unix.cronus'))) self.assertTrue(islink(os.path.join(ManifestController.manifestPath('foo', 'bar'), 'perlserver'))) self.assertTrue(islink(os.path.join(ManifestController.manifestPath('lah', 'blah'), 'perlserver')))
def doRun(self): """ Main body of the thread """ errorMsg = "" errorCode = None failed = False try: activePath = os.path.join(ServiceController.manifestPath(self._service), 'active') oldManifest = None # make sure that if the active path exists, it's a link # if not log that and delete the link if (os.path.exists(activePath) and not os.name == 'nt' and not islink(activePath)): self.__LOG.error('%s is not a link. Attempted to delete' % activePath) shutil.rmtree(activePath) if (os.path.exists(activePath)): oldManifest = os.path.basename(readlink(activePath)) else: raise AgentException(error = Errors.ACTIVEMANIFEST_MANIFEST_MISSING, errorMsg = 'No active manifest - cannot deactivate service') self.__deactivateManifest(self._service, oldManifest) self.__removeSymlink(self._service) 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] raise exc except AgentException as exc: failed = True errorMsg = 'Deactivate Manifest - Agent Exception - %s' % exc.getMsg() errorCode = exc.getCode() except Exception as exc: failed = True errorMsg = 'Deactivate Manifest - Unknown error - (%s) - %s - %s' \ % (self._service, 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) self.__LOG.debug('Done: activate manifest for (%s)' % (self._service)) self._updateProgress(100)
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 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 doRun(self): """ Main body of the thread """ errorMsg = "" errorCode = None failed = False activeManifest = None try: activePath = os.path.join(ServiceController.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 reset service') activeManifest = os.path.basename(readlink(activePath)) self.__shutdownManifest(self._service, activeManifest) self.__deactivateManifest(self._service, activeManifest) self.__activateManifest(self._service, activeManifest) self.__startupManifest(self._service, activeManifest) self.__LOG.info('Done: reset service for (%s/%s)' % (self._service, activeManifest)) self._updateStatus(progress = 100) except AgentException as exc: failed = True errorMsg = 'Activate Manifest - Agent Exception - %s' % exc.getMsg() errorCode = exc.getCode() except Exception as exc: failed = True errorMsg = 'Activate Manifest - 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.error(errorMsg) if self._service and activeManifest: try: self.__LOG.info('Reset service %s failed, shutdown to cleanup' % 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 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(ManifestController.manifestPath('foo', 'bar'), 'perlserver')))
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 testGet(self): path = ManifestController.manifestPath('foo', 'bar') os.makedirs(path) path = ManifestController.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 getAllSymLinks(service): """ return all the symlinks from manifests to packages for a given service""" LOG.debug('calling getAllSymLinks %s' % service) linkedPaths = [] manPath = ServiceController.manifestPath(service) LOG.debug('manifestPath is %s' % manPath) for path in os.listdir(manPath): LOG.debug('path is %s' % path) if not islink(os.path.join(manPath, path)): LOG.debug('path is dir not a link') pkgPaths = [ packageDir for packageDir in os.listdir(os.path.join(manPath, path)) ] LOG.debug('pkgPaths is %s' % pkgPaths) for pkgPath in pkgPaths: try: LOG.debug('pkgPath is %s' % pkgPath) if not os.path.isfile(os.path.join(manPath, path, pkgPath)) and islink(os.path.join(manPath, path, pkgPath)): LOG.debug('pkgPaths is %s' % pkgPath) targetPath = os.path.abspath(readlink(os.path.join(manPath, path, pkgPath))) linkedPaths.append(targetPath) LOG.debug('targetPath is %s ' % targetPath) except BaseException as exc: LOG.error('failed to read link for the pkg path %s' % str(exc)) return linkedPaths
def doRun(self): """ Main body of the thread """ errorMsg = "" errorCode = None symlinkSwitched = False failed = False try: activePath = os.path.join(ServiceController.manifestPath(self._service), 'active') oldManifest = None appGlobal = pylons.config['pylons.app_globals'] # make sure that if the active path exists, it's a link # if not log that and delete the link if (os.path.exists(activePath) and not os.name == 'nt' and not islink(activePath)): self.__LOG.error('%s is not a link. Attempted to delete' % activePath) shutil.rmtree(activePath) if (os.path.exists(activePath)): oldManifest = os.path.basename(readlink(activePath)) self.__installManifest(self._service, self._manifest) self.__deactivateManifest(self._service, oldManifest) symlinkSwitched = self.__switchSymlink(self._service, self._manifest) appGlobal = pylons.config['pylons.app_globals'] if self._service == 'agent': # START Jeff 09 19 2012: save the timestamp and old manifestPath to .recover: only for agent service. recoveryInfo = {} beforeKillTimeHuman = strftime("%Y-%m-%d %H:%M:%S", localtime()) beforeKillTimeStamp = int(time.time()) recoveryInfo['beforeKillTimeHuman'] = str(beforeKillTimeHuman) recoveryInfo['beforeKillTimeStamp'] = str(beforeKillTimeStamp) # make sure there is always quote: even if null. easy for json parsing in startup if self._manifest: recoveryInfo['newManifest'] = self._manifest else: recoveryInfo['newManifest'] = 'null' if oldManifest: recoveryInfo['oldManifest'] = oldManifest else: recoveryInfo['oldManifest'] = 'null' manifestutil.writeJson('agent', '.recovery', recoveryInfo) # END Jeff 09 19 2012: save the timestamp and .recover files with # persist threads result before shutting down if (hasattr(appGlobal, 'threadMgr') and appGlobal.threadMgr != None): killStatus = {} killStatus['httpStatus'] = 500 killStatus['error'] = Errors.THREAD_KILLED_AGENT_RESTART killStatus['errorMsg'] = 'thread killed, agent restart' appGlobal.threadMgr.snapshot(killStatus, True) self.__activateManifest(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] raise exc except AgentException as exc: failed = True errorMsg = 'Activate Manifest - Agent Exception - %s' % exc.getMsg() errorCode = exc.getCode() except Exception as exc: failed = True errorMsg = 'Activate Manifest - Unknown error - (%s/%s) - %s - %s' \ % (self._service, self._manifest, str(exc), traceback.format_exc(5)) errorCode = Errors.UNKNOWN_ERROR finally: if failed: if not self._skipCleanupOnFailure(): self.__cleanup(symlinkSwitched, errorMsg, errorCode) self.__LOG.warning(errorMsg) self._updateStatus(httpStatus = 500, error = errorCode, errorMsg = errorMsg) else: self._updateProgress(100)
def doRun(self): """ Main body of the thread Progress Info: Look at the list of packages this manifest has and figure out the progress of this manifest Progress 1 = manifest directory created Progress 2-80 = all packages downloaded Progress 81-99 = all packages untarred Progress 100 = all links done """ inProgressPath = ManifestCreate.inProgress(ManifestController.manifestPath(self.__service, self.__manifest)) try: if self.__service != 'agent': utils.checkDiskFull() installedPkgPath = ServiceController.installedPkgPath(self.__service) # This shouldn'trn happen but make sure there isn'trn already a manifest directory in progress if (os.path.isdir(inProgressPath)): # probably another manifest create thread died out half way. # Cleanup and reattempt manifest creation LOG.debug('Manifest inprogress found for service/manifest (%s/%s). Will cleanup and retry' % (self.__service, self.__manifest)) shutil.rmtree(inProgressPath) # make sure that the service path and installed package path exists if (not os.path.isdir(ServiceController.manifestPath(self.__service)) or not os.path.isdir(ServiceController.installedPkgPath(self.__service))): errCode = Errors.SERVICE_NOT_FOUND msg = 'Service (%s) for manifest (%s) not found' % (self.__service, self.__manifest) self._updateStatus(httpStatus = 500, error = errCode, errorMsg = msg) return # ok create the manifest path os.mkdir(inProgressPath) self._updateProgress(1) # figure out which of the packages are already there remainingPackages = {} for pkgUri in self.__packages: pkgDict = PackageUtil.parseUri(pkgUri) pkgPath = os.path.join(installedPkgPath, pkgDict['packageName'], pkgDict['packageVersion']) pkgName = pkgDict['packageName'] if (not os.path.exists(pkgPath)) or ((self.__forcePackages is not None) and pkgName in self.__forcePackages): remainingPackages[pkgUri] = pkgDict else: symlink(pkgPath, os.path.join(inProgressPath, pkgDict['packageName'])) if self.__attemptDownload: # now make sure all the packages are downloaded try: self._downloadPackages(remainingPackages.keys(), skipProp = self.__skipProp) except AgentException as exc: # check if it is download error, then modify exception appropriately if exc.getCode() == Errors.DC_FAILED_DOWNLOAD: exc = AgentException(Errors.MANIFEST_PACKAGE_DOWNLOAD_FAILED, 'Manifest (%s/%s) failed downloading package - %s' % (self.__service, self.__manifest, exc.getMsg())) raise exc else: if len(remainingPackages) > 0: raise AgentException(Errors.MANIFEST_PACKAGE_DOES_NOT_EXIST, 'Create Manifest (%s/%s) failed since package is not present and download has been disabled' % (self.__service, self.__manifest)) LOG.info('Completed download all packages for (%s/%s)' % (self.__service, self.__manifest)) # now untar the packages import re pkgSuffix = '.%s' % re.sub(r"\W", "", self.__manifest) self._untarPackages(remainingPackages, self.__service, ServiceController.installedPkgPath(self.__service), 0, self.__forcePackages, pkgSuffix) LOG.info('Completed untar all packages for (%s/%s)' % (self.__service, self.__manifest)) # now create the links for pkgDict in remainingPackages.itervalues(): pkgPath = os.path.join(installedPkgPath, pkgDict['packageName'], pkgDict['packageVersion']) linkPath = os.path.join(inProgressPath, pkgDict['packageName']) # validate target folder does exist if not os.path.exists(pkgPath): raise AgentException(Errors.PACKAGE_PATH_ERROR, 'invalid untarred package at %s' % pkgPath) symlink(pkgPath, linkPath) # now move the inProgressPath to the final path manifestContentPath = ManifestController.manifestContentPath(self.__service, self.__manifest) os.rename(inProgressPath, ManifestController.manifestPath(self.__service, self.__manifest)) mfContentsFile = file(manifestContentPath, 'w') for pkgUri in self.__packages: mfContentsFile.write(('%s%s') % (pkgUri, os.linesep)) mfContentsFile.close() LOG.info('Completed create manifest directories for (%s/%s)' % (self.__service, self.__manifest)) LOG.info('Completed create manifest for (%s/%s)' % (self.__service, self.__manifest)) self._updateStatus(progress = 100) except AgentException as exc: LOG.info(exc.getMsg()) self._updateStatus(httpStatus = 500, error = exc.getCode(), errorMsg = exc.getMsg()) except Exception as exc: errCode = Errors.UNKNOWN_ERROR msg = 'Unknown error for (%s/%s) - %s - %s' % (self.__service, self.__manifest, str(exc), traceback.format_exc(2)) LOG.info(msg) self._updateStatus(httpStatus = 500, error = errCode, errorMsg = msg) finally: # clean up intermediate progress try: shutil.rmtree(inProgressPath) except OSError: pass
def testDelete(self): def deleteTestDir(service): LOG.debug('************ service = %s' % service) response = self.app.delete(url(controller='service', service=service, action='delete'), expect_errors=True) # make sure the responses are correct LOG.debug('status = ' + str(response.status_int)) # assert response.status_int == 500, "HTTP response != 500" def makeTestDir(path): os.makedirs(path) os.makedirs(os.path.join(path, 'manifests')) os.makedirs(os.path.join(path, 'installed-packages')) def createManifests(mf_path): os.makedirs(os.path.join(mf_path, 'm1.0', 'dummy_dir1.0')) os.makedirs(os.path.join(mf_path, 'm2.0', 'dummy_dir2.0')) latest = os.path.join(mf_path, 'm3.0') os.makedirs(os.path.join(latest, 'dummy_dir3.0')) utils.symlink(latest, os.path.join(mf_path, 'active')) return (['m1.0', 'm2.0', 'm3.0'], 'm3.0') def makePackageContent(path, pkgPath, pkgPropPath): pkgFile = file(pkgPath, 'w') for index in range(10): pkgFile.write(('%s%s') % (index, index)) pkgFile.close() pkgFile = file(pkgPropPath, 'w') for index in range(10): pkgFile.write(('%s%s') % (index, index)) pkgFile.close() uname = pylons.config['agent_user_account'] TestCleanupController.rchown(path, uname) def createTestThread(serviceName): appGlobal = config['pylons.app_globals'] testTh = WaitThread(appGlobal.threadMgr, ServiceController.serviceCat(serviceName)) testTh.start() return testTh def startTestProcess(): cmd = utils.sudoCmd(["sleep", "5"], pylons.config['app_user_account']) return Popen(cmd) if os.name == 'nt': LOG.warning( 'Services cleanup not supported on windows. Skipping test...') return path1 = os.path.join(pylons.config['agent_root'], 'service_nodes', 'foo') path2 = os.path.join(pylons.config['agent_root'], 'service_nodes', 'bar') path3 = os.path.join(pylons.config['agent_root'], 'service_nodes', 'agent') deleteTestDir('foo') deleteTestDir('bar') deleteTestDir('agent') # make dirs makeTestDir(path1) makeTestDir(path2) makeTestDir(path3) all_mf, active_mf = createManifests( ServiceController.manifestPath('agent')) uname = pylons.config['agent_user_account'] TestCleanupController.rchown(ServiceController.serviceRootPath(), uname) pkgDir = PackageMgr.packagePath() pkgPath = os.path.join(pkgDir, "foo.cronus") pkgPropPath = os.path.join(pkgDir, "foo.cronus.prop") makePackageContent(pkgDir, pkgPath, pkgPropPath) # create threads testThFoo = createTestThread('foo') testThBar = createTestThread('bar') testThAgent = createTestThread('agent') # start process process = startTestProcess() # start testing LOG.debug('************ start cleanup') response = self.app.post(url(controller='cleanup', action='post')) LOG.debug('Delete response body = ' + response.body) body = json.loads(response.body) tm = time.time() while (tm + 10 > time.time()): response = self.app.get(body['status'], expect_errors=True) LOG.debug('Status response body = ' + response.body) body = json.loads(response.body) print body if (body['progress'] == 100): break time.sleep(0.1) # make sure the responses are correct LOG.debug('status = ' + str(response.status_int)) assert response.status_int == 200, "HTTP response != 200" time.sleep(0.1) assert not os.path.exists( path1), 'service foo does exist or is not a directory' assert not os.path.exists( path2), 'service bar does exist or is not a directory' assert os.path.exists( path3), 'service agent does NOT exist or is not a directory' assert not testThFoo.isAlive(), 'thread Foo is still alive' assert not testThBar.isAlive(), 'thread Bar is still alive' assert not testThAgent.isAlive(), 'thread Agent is still alive' assert not os.path.exists(pkgPath), 'package foo exists' assert not os.path.exists(pkgPropPath), 'package prop foo exists' assert os.path.exists(pkgDir), 'package directory does not exist' # ensure agent cleanup is proper active_mf_path = ManifestController.manifestPath('agent', active_mf) active_link = os.path.join(ServiceController.manifestPath('agent'), 'active') all_mf.remove(active_mf) actual_active_mf_path = utils.readlink(active_link) self.assertTrue( os.path.exists(active_mf_path), 'active agent manifest got deleted but shouldn\t have') self.assertTrue(os.path.exists(active_link), 'agent active link missing') self.assertEqual( active_mf_path, actual_active_mf_path, 'agent active link pointing to some wrong manifest; link broken?') for mf in all_mf: agnt_mf_path = ManifestController.manifestPath('agent', mf) self.assertFalse( os.path.exists(agnt_mf_path), 'non active agent mf %s should have been deleted' % mf)
def __getSymlinkPath(self, service): """ return symlink path for a service """ return os.path.join(ServiceController.manifestPath(service), 'active')
def testDelete(self): def deleteTestDir(service): LOG.debug('************ service = %s' % service) response = self.app.delete(url(controller='service', service=service, action='delete'), expect_errors = True) # make sure the responses are correct LOG.debug('status = ' + str(response.status_int)) # assert response.status_int == 500, "HTTP response != 500" def makeTestDir(path): os.makedirs(path) os.makedirs(os.path.join(path, 'manifests')) os.makedirs(os.path.join(path, 'installed-packages')) def createManifests(mf_path): os.makedirs(os.path.join(mf_path, 'm1.0', 'dummy_dir1.0')) os.makedirs(os.path.join(mf_path, 'm2.0', 'dummy_dir2.0')) latest = os.path.join(mf_path, 'm3.0') os.makedirs(os.path.join(latest, 'dummy_dir3.0')) utils.symlink(latest, os.path.join(mf_path, 'active')) return (['m1.0', 'm2.0', 'm3.0'], 'm3.0') def makePackageContent(path, pkgPath, pkgPropPath): pkgFile = file(pkgPath, 'w') for index in range(10): pkgFile.write(('%s%s') % (index, index)) pkgFile.close() pkgFile = file(pkgPropPath, 'w') for index in range(10): pkgFile.write(('%s%s') % (index, index)) pkgFile.close() uname = pylons.config['agent_user_account'] TestCleanupController.rchown(path, uname) def createTestThread(serviceName): appGlobal = config['pylons.app_globals'] testTh = WaitThread(appGlobal.threadMgr, ServiceController.serviceCat(serviceName)) testTh.start() return testTh def startTestProcess(): cmd = utils.sudoCmd(["sleep", "5"], pylons.config['app_user_account']) return Popen(cmd) path1 = os.path.join(pylons.config['agent_root'], 'service_nodes', 'foo') path2 = os.path.join(pylons.config['agent_root'], 'service_nodes', 'bar') path3 = os.path.join(pylons.config['agent_root'], 'service_nodes', 'agent') deleteTestDir('foo') deleteTestDir('bar') deleteTestDir('agent') # make dirs makeTestDir(path1) makeTestDir(path2) makeTestDir(path3) all_mf, active_mf = createManifests(ServiceController.manifestPath('agent')) uname = pylons.config['agent_user_account'] TestCleanupController.rchown(ServiceController.serviceRootPath(), uname) pkgDir = PackageMgr.packagePath() pkgPath = os.path.join(pkgDir, "foo.cronus") pkgPropPath = os.path.join(pkgDir, "foo.cronus.prop") makePackageContent(pkgDir, pkgPath, pkgPropPath) # create threads testThFoo = createTestThread('foo') testThBar = createTestThread('bar') testThAgent = createTestThread('agent') # start process process = startTestProcess() # start testing LOG.debug('************ start cleanup') response = self.app.post(url(controller='cleanup', action='post')) LOG.debug ('Delete response body = ' + response.body) body = json.loads(response.body) tm = time.time() while (tm + 10 > time.time()): response = self.app.get(body['status'], expect_errors = True) LOG.debug ('Status response body = ' + response.body) body = json.loads(response.body) print body if (body['progress'] == 100): break time.sleep(0.1) # make sure the responses are correct LOG.debug('status = ' + str(response.status_int)) assert response.status_int == 200, "HTTP response != 200" time.sleep(0.1) assert not os.path.exists(path1), 'service foo does exist or is not a directory' assert not os.path.exists(path2), 'service bar does exist or is not a directory' assert os.path.exists(path3), 'service agent does NOT exist or is not a directory' assert not testThFoo.isAlive(), 'thread Foo is still alive' assert not testThBar.isAlive(), 'thread Bar is still alive' assert not testThAgent.isAlive(), 'thread Agent is still alive' assert not os.path.exists(pkgPath), 'package foo exists' assert not os.path.exists(pkgPropPath), 'package prop foo exists' assert os.path.exists(pkgDir), 'package directory does not exist' # ensure agent cleanup is proper active_mf_path = manifestutil.manifestPath('agent', active_mf) active_link = os.path.join(ServiceController.manifestPath('agent'), 'active') all_mf.remove(active_mf) actual_active_mf_path = utils.readlink(active_link) self.assertTrue(os.path.exists(active_mf_path), 'active agent manifest got deleted but shouldn\t have') self.assertTrue(os.path.exists(active_link), 'agent active link missing') self.assertEqual(active_mf_path, actual_active_mf_path, 'agent active link pointing to some wrong manifest; link broken?') for mf in all_mf: agnt_mf_path = manifestutil.manifestPath('agent', mf) self.assertFalse(os.path.exists(agnt_mf_path), 'non active agent mf %s should have been deleted' % mf)
def doRun(self): """ Main body of the thread """ errorMsg = "" errorCode = None symlinkSwitched = False failed = False try: activePath = os.path.join( ServiceController.manifestPath(self._service), 'active') oldManifest = None appGlobal = pylons.config['pylons.app_globals'] # make sure that if the active path exists, it's a link # if not log that and delete the link if (os.path.exists(activePath) and not os.name == 'nt' and not islink(activePath)): self.__LOG.error('%s is not a link. Attempted to delete' % activePath) shutil.rmtree(activePath) if (os.path.exists(activePath)): oldManifest = os.path.basename(readlink(activePath)) self.__installManifest(self._service, self._manifest) self.__deactivateManifest(self._service, oldManifest) symlinkSwitched = self.__switchSymlink(self._service, self._manifest) appGlobal = pylons.config['pylons.app_globals'] if self._service == 'agent': # START Jeff 09 19 2012: save the timestamp and old manifestPath to .recover: only for agent service. recoveryInfo = {} beforeKillTimeHuman = strftime("%Y-%m-%d %H:%M:%S", localtime()) beforeKillTimeStamp = int(time.time()) recoveryInfo['beforeKillTimeHuman'] = str(beforeKillTimeHuman) recoveryInfo['beforeKillTimeStamp'] = str(beforeKillTimeStamp) # make sure there is always quote: even if null. easy for json parsing in startup if self._manifest: recoveryInfo['newManifest'] = self._manifest else: recoveryInfo['newManifest'] = 'null' if oldManifest: recoveryInfo['oldManifest'] = oldManifest else: recoveryInfo['oldManifest'] = 'null' manifestutil.writeJson('agent', '.recovery', recoveryInfo) # END Jeff 09 19 2012: save the timestamp and .recover files with # persist threads result before shutting down if (hasattr(appGlobal, 'threadMgr') and appGlobal.threadMgr != None): killStatus = {} killStatus['httpStatus'] = 500 killStatus['error'] = Errors.THREAD_KILLED_AGENT_RESTART killStatus['errorMsg'] = 'thread killed, agent restart' appGlobal.threadMgr.snapshot(killStatus, True) self.__activateManifest(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] raise exc except AgentException as exc: failed = True errorMsg = 'Activate Manifest - Agent Exception - %s' % exc.getMsg( ) errorCode = exc.getCode() except Exception as exc: failed = True errorMsg = 'Activate Manifest - Unknown error - (%s/%s) - %s - %s' \ % (self._service, self._manifest, str(exc), traceback.format_exc(5)) errorCode = Errors.UNKNOWN_ERROR finally: if failed: if not self._skipCleanupOnFailure(): self.__cleanup(symlinkSwitched, errorMsg, errorCode) self.__LOG.warning(errorMsg) self._updateStatus(httpStatus=500, error=errorCode, errorMsg=errorMsg) else: self._updateProgress(100)