def test_once(timeout=6.0): with self.database.transaction(): self.assertIsNone(Initialized.lookupAny()) self.assertIsNone(Stopped.lookupAny()) ServiceManager.createOrUpdateService(WaitForService, svcName) ServiceManager.startService(svcName) ServiceManager.waitRunning(self.database, svcName, timeout=timeout) with self.database.view(): self.assertIsNotNone(Initialized.lookupAny()) with self.database.transaction(): ServiceManager.stopService(svcName) ServiceManager.waitStopped(self.database, svcName, timeout=timeout) with self.database.view(): self.assertIsNotNone(Stopped.lookupAny()) with self.database.transaction(): for obj in Initialized.lookupAll(): obj.delete() for obj in Stopped.lookupAll(): obj.delete()
def test_racheting_service_count_up_and_down(self): with self.database.transaction(): ServiceManager.createOrUpdateService(TestService, "TestService", target_count=1) numpy.random.seed(42) for count in numpy.random.choice(6, size=20): logging.getLogger(__name__).info( "Setting count for TestService to %s and waiting for it to be alive.", count) with self.database.transaction(): ServiceManager.startService("TestService", int(count)) self.waitForCount(count) with self.database.transaction(): ServiceManager.startService("TestService", 0) self.waitForCount(0) # make sure we don't have a bunch of zombie processes hanging underneath the service manager time.sleep(1.0) self.assertEqual(len(psutil.Process().children()[0].children()), 0)
def test_service_storage(self): with self.database.transaction(): ServiceManager.createOrUpdateService(StorageTest, "StorageTest", target_count=1) self.waitForCount(1)
def test_throughput_while_adjusting_servicecount(self): with self.database.transaction(): ServiceManager.createOrUpdateService(TestService, "TestService", target_count=0) emptyThroughputs = [self.measureThroughput(1.0)] fullThroughputs = [] for i in range(2): with self.database.transaction(): ServiceManager.startService("TestService", 20) self.waitForCount(20) fullThroughputs.append(self.measureThroughput(1.0)) with self.database.transaction(): ServiceManager.startService("TestService", 0) self.waitForCount(0) emptyThroughputs.append(self.measureThroughput(1.0)) print("Throughput with no workers: ", emptyThroughputs) print("Throughput with 20 workers: ", fullThroughputs) # we want to ensure that we don't have some problem where our transaction throughput # goes down because we have left-over connections or something similar in the server, # which would be a real problem! self.assertTrue(emptyThroughputs[-1] * 2 > emptyThroughputs[0], (emptyThroughputs))
def test_starting_services(self): with self.database.transaction(): ServiceManager.createOrUpdateService(TestService, "TestService", target_count=1) self.waitForCount(1)
def test_logfiles_exist_and_get_recycled(self): with self.database.transaction(): ServiceManager.createOrUpdateService(TestService, "TestService", target_count=1) self.waitForCount(1) self.assertTrue( self.database.waitForCondition( lambda: len(os.listdir(self.logDir)) == 1, timeout=5.0, maxSleepTime=0.001)) priorFilename = os.listdir(self.logDir)[0] self.setCountAndBlock(0) self.setCountAndBlock(1) self.assertTrue( self.database.waitForCondition( lambda: len(os.listdir(self.logDir)) == 2, timeout=5.0, maxSleepTime=0.001)) newFilename = [x for x in os.listdir(self.logDir) if x != 'old'][0] self.assertNotEqual(priorFilename, newFilename)
def installServices(self): with self.database.transaction(): ServiceManager.createOrUpdateService(Task.TaskService, "TaskService", target_count=1, gbRamUsed=0, coresUsed=0) ServiceManager.createOrUpdateService(Task.TaskDispatchService, "TaskDispatchService", target_count=1, gbRamUsed=0, coresUsed=0) self.waitRunning("TaskService") self.waitRunning("TaskDispatchService") with open(os.path.join(ownDir, "test_files", "TestModule1.py"), "r") as f: files = {"TestModule1.py": f.read()} with self.database.transaction(): self.testService1Object = ServiceManager.createOrUpdateServiceWithCodebase( service_schema.Codebase.createFromFiles(files), "TestModule1.TestService1", "TestService1", 0) self.testService1Codebase = self.testService1Object.codebase.instantiate( ) self.service1Conn = self.newDbConnection() self.service1Conn.setSerializationContext( self.testService1Codebase.serializationContext) self.service1Conn.subscribeToType(Task.Task) self.service1Conn.subscribeToType(Task.TaskStatus) self.service1Conn.subscribeToType( self.testService1Codebase.getClassByName("TestModule1.Record"))
def redeploy(database, config, watch=False): if watch: curHash = None while True: time.sleep(0.25) if curHash != hashCurrentCodebase(): print("Codebase changed to ", curHash, ". redeploying") try: redeploy(database, config) except Exception: print("ERROR: ") traceback.print_exc() curHash = hashCurrentCodebase() return with database.transaction(): ServiceManager.createOrUpdateService(ResearchFrontend, "ResearchFrontend", placement="Master") ServiceManager.createOrUpdateService(ResearchBackend, "ResearchBackend", placement="Master")
def dialWorkers(self, workerCount): with self.database.transaction(): ServiceManager.createOrUpdateService(Task.TaskService, "TaskService", target_count=workerCount, gbRamUsed=0, coresUsed=0)
def configureResearchFrontend(database, config): with database.transaction(): frontend_svc = ServiceManager.createOrUpdateService(ResearchFrontend, "ResearchFrontend", placement="Master") ServiceManager.createOrUpdateService(ResearchBackend, "ResearchBackend", placement="Master")
def test_service_restarts_after_killing(self): with self.database.transaction(): ServiceManager.createOrUpdateService(TestService, "TestService", target_count=1) self.waitForCount(1) with self.database.transaction(): s = TestServiceLastTimestamp.aliveServices()[0] s.triggerHardKill = True self.database.waitForCondition(lambda: not s.connection.exists(), timeout=5.0) self.waitForCount(1)
def test_own_ip_populated(self): with self.database.transaction(): ServiceManager.createOrUpdateService(TestService, "TestService", target_count=1) self.waitForCount(1) with self.database.view(): state = TestServiceLastTimestamp.lookupAny() # we should always know our ip as 127.0.0.1 because we infer it from # the server we connect to, and we connected to localhost. self.assertEqual(state.ownIp, "127.0.0.1")
def DISABLEDtest_throughput_with_many_workers(self): with self.database.transaction(): ServiceManager.createOrUpdateService(TestService, "TestService", target_count=0) throughputs = [] for ct in [16,18,20,22,24,26,28,30,32,34,0]: with self.database.transaction(): ServiceManager.startService("TestService", ct) self.waitForCount(ct) throughputs.append(self.measureThroughput(5.0)) print("Total throughput was", throughputs, " transactions per second")
def main(argv=None): if argv is not None: argv = sys.argv token = genToken() port = 8020 with tempfile.TemporaryDirectory() as tmpDirName: try: server = start_service_manager(tmpDirName, port, token) database = connect("localhost", port, token, retry=True) database.subscribeToSchema(core_schema, service_schema, active_webservice_schema) with database.transaction(): service = ServiceManager.createOrUpdateService( ActiveWebService, "ActiveWebService", target_count=0) ActiveWebService.configureFromCommandline(database, service, [ '--port', '8000', '--host', '0.0.0.0', '--auth', 'NONE', '--log-level', 'INFO' ]) with database.transaction(): ServiceManager.startService("ActiveWebService", 1) with database.transaction(): service = ServiceManager.createOrUpdateService( UninitializableService, "UninitializableService", target_count=1) with database.transaction(): service = ServiceManager.createOrUpdateService(HappyService, "HappyService", target_count=1) with database.transaction(): service = ServiceManager.createOrUpdateService( GraphDisplayService, "GraphDisplayService", target_count=1) while True: time.sleep(.1) finally: server.terminate() server.wait() return 0
def test_starting_uninitializable_services(self): with self.database.transaction(): svc = ServiceManager.createOrUpdateService(UninitializableService, "UninitializableService", target_count=1) self.assertTrue( self.database.waitForCondition( lambda: svc.timesBootedUnsuccessfully == ServiceInstance.MAX_BAD_BOOTS, 10 ) ) with self.database.view(): self.assertEqual(svc.effectiveTargetCount(), 0) with self.database.transaction(): svc.resetCounters() with self.database.view(): self.assertEqual(svc.effectiveTargetCount(), 1) self.assertTrue( self.database.waitForCondition( lambda: svc.timesBootedUnsuccessfully == ServiceInstance.MAX_BAD_BOOTS, 10 ) )
def configurableSetUp(self, auth_type="LDAP", auth_hostname=None, authorized_groups=(), ldap_base_dn=None, ldap_ntlm_domain=None, company_name=None): self.token = genToken() log_level = self._logger.getEffectiveLevel() loglevel_name = logging.getLevelName(log_level) self.server, self.cleanupFn = autoconfigure_and_start_service_manager( port=DATABASE_SERVER_PORT, auth_token=self.token, loglevel_name=loglevel_name) try: self.database = connect("localhost", DATABASE_SERVER_PORT, self.token, retry=True) self.database.subscribeToSchema(core_schema, service_schema, active_webservice_schema) with self.database.transaction(): service = ServiceManager.createOrUpdateService( ActiveWebService, "ActiveWebService", target_count=0) optional_args = [] if len(authorized_groups) > 0: optional_args.extend( ['--authorized-groups', *authorized_groups]) if auth_hostname: optional_args.extend(['--auth-hostname', auth_hostname]) if ldap_base_dn: optional_args.extend(['--ldap-base-dn', ldap_base_dn]) if ldap_ntlm_domain: optional_args.extend(['--ldap-ntlm-domain', ldap_ntlm_domain]) if company_name: optional_args.extend(['--company-name', company_name]) ActiveWebService.configureFromCommandline(self.database, service, [ '--port', str(WEB_SERVER_PORT), '--host', 'localhost', '--log-level', loglevel_name, '--auth', auth_type ] + optional_args) with self.database.transaction(): ServiceManager.startService("ActiveWebService", 1) self.waitUntilUp() except Exception: self.cleanupFn(error=True) raise
def test_shutdown_hanging_services(self): with self.database.transaction(): ServiceManager.createOrUpdateService(HangingService, "HangingService", target_count=10) self.waitForCount(10) t0 = time.time() with self.database.transaction(): ServiceManager.startService("HangingService", 0) self.waitForCount(0) self.assertTrue(time.time() - t0 < 2.0) # make sure we don't have a bunch of zombie processes hanging underneath the service manager time.sleep(1.0) self.assertEqual(len(psutil.Process().children()[0].children()), 0)
def test_redeploy_hanging_services(self): with self.database.transaction(): ServiceManager.createOrUpdateService(HangingService, "HangingService", target_count=10) self.waitForCount(10) with self.database.view(): instances = service_schema.ServiceInstance.lookupAll() orig_codebase = instances[0].codebase with self.database.transaction(): ServiceManager.createOrUpdateServiceWithCodebase( service_schema.Codebase.createFromFiles( getTestServiceModule(2)), "test_service.service.Service", "HangingService", 10) # this should force a redeploy. maxProcessesEver = 0 for i in range(40): maxProcessesEver = max( maxProcessesEver, len(psutil.Process().children()[0].children())) time.sleep(.1) self.database.flush() # after 2 seconds, we should be redeployed, but give Travis a bit more time if os.environ.get('TRAVIS_CI', None) is not None: time.sleep(10.0) with self.database.view(): instances_redeployed = service_schema.ServiceInstance.lookupAll() self.assertEqual(len(instances), 10) self.assertEqual(len(instances_redeployed), 10) self.assertEqual( len(set(instances).intersection(set(instances_redeployed))), 0) self.assertTrue(orig_codebase != instances_redeployed[0].codebase) # and we never became too big! self.assertLess(maxProcessesEver, 11)
def test_deploy_imported_module(self): with tempfile.TemporaryDirectory() as tf: for fname, contents in getTestServiceModule(1).items(): if not os.path.exists(os.path.join(tf, os.path.dirname(fname))): os.makedirs(os.path.join(tf, os.path.dirname(fname))) with open(os.path.join(tf, fname), "w") as f: f.write(contents) try: sys.path += [tf] test_service = __import__("test_service.service") with self.database.transaction(): ServiceManager.createOrUpdateService( test_service.service.Service, "TestService", target_count=1) self.waitForCount(1) finally: sys.path = [x for x in sys.path if x != tf]
def _main(argv): configureLogging() parser = argparse.ArgumentParser("Install and configure services.") parser.add_argument("--hostname", default=os.getenv("ODB_HOST", "localhost"), required=False) parser.add_argument("--port", type=int, default=int(os.getenv("ODB_PORT", 8000)), required=False) parser.add_argument("--auth", type=str, default=os.getenv("ODB_AUTH_TOKEN", ""), required=False, help="Auth token to use to connect.") subparsers = parser.add_subparsers() connections_parser = subparsers.add_parser('connections', help='list live connections') connections_parser.set_defaults(command='connections') install_parser = subparsers.add_parser('install', help='install a service') install_parser.set_defaults(command='install') install_parser.add_argument("--path", action='append', dest='paths') install_parser.add_argument("--class") install_parser.add_argument("--name", required=False) install_parser.add_argument("--placement", required=False, default='Any', choices=['Any','Master','Worker']) install_parser.add_argument("--singleton", required=False, action='store_true') reset_parser = subparsers.add_parser('reset', help='reset a service''s boot count') reset_parser.set_defaults(command='reset') reset_parser.add_argument("name") configure_parser = subparsers.add_parser('configure', help='configure a service') configure_parser.set_defaults(command='configure') configure_parser.add_argument("name") configure_parser.add_argument("args", nargs=argparse.REMAINDER) list_parser = subparsers.add_parser('list', help='list installed services') list_parser.set_defaults(command='list') instances_parser = subparsers.add_parser('instances', help='list running service instances') instances_parser.set_defaults(command='instances') hosts_parser = subparsers.add_parser('hosts', help='list running hosts') hosts_parser.set_defaults(command='hosts') start_parser = subparsers.add_parser('start', help='Start (or change target replicas for) a service') start_parser.set_defaults(command='start') start_parser.add_argument("name") start_parser.add_argument("--count", type=int, default=1, required=False) stop_parser = subparsers.add_parser('stop', help='Stop a service') stop_parser.set_defaults(command='stop') stop_parser.add_argument("name") parsedArgs = parser.parse_args(argv[1:]) db = connect(parsedArgs.hostname, parsedArgs.port, parsedArgs.auth) db.subscribeToSchema(core_schema, service_schema, lazySubscription=True) if parsedArgs.command == 'connections': table = [['Connection ID']] with db.view(): for c in sorted(core_schema.Connection.lookupAll(), key=lambda c: c._identity): table.append([c._identity]) print(formatTable(table)) if parsedArgs.command == 'configure': try: with db.transaction(): s = service_schema.Service.lookupAny(name=parsedArgs.name) svcClass = s.instantiateServiceType() svcClass.configureFromCommandline(db, s, parsedArgs.args) except Exception as e: traceback.print_exc() return 1 if parsedArgs.command == 'reset': with db.transaction(): service = service_schema.Service.lookupAny(name=parsedArgs.name) service.timesBootedUnsuccessfully = 0 if parsedArgs.command == 'install': if parsedArgs.paths: paths = parsedArgs.paths else: paths = [findGitParent(os.getcwd())] gbRamUsed = 1 coresUsed = 1 with db.transaction(): fullClassname = getattr(parsedArgs, 'class') modulename, classname = fullClassname.rsplit(".",1) if modulename.startswith("object_database"): def _getobject(modname, attribute): mod = __import__(modname, fromlist=[attribute]) return mod.__dict__[attribute] actualClass = _getobject(modulename, classname) if not isinstance(actualClass, type): print("Named class %s is not a type." % fullClassname) return 1 if not issubclass(actualClass, ServiceBase): print("Named class %s is not a ServiceBase subclass." % fullClassname) return 1 coresUsed = actualClass.coresUsed gbRamUsed = actualClass.gbRamUsed ServiceManager.createOrUpdateService(actualClass, classname, placement=parsedArgs.placement, isSingleton=parsedArgs.singleton, coresUsed=coresUsed, gbRamUsed=gbRamUsed ) else: codebase = service_schema.Codebase.create(paths) #make sure the codebase is importable, etc module = codebase.instantiate(modulename) if module is None: print("Can't find", module, "in the codebase") actualClass = module.__dict__.get(classname, None) if actualClass is None: print("Can't find", module, "in module", modulename) if actualClass is None: print("Can't find", classname, "in the codebase") return 1 if not isinstance(actualClass, type): print("Named class %s is not a type." % fullClassname) return 1 if not issubclass(actualClass, ServiceBase): print("Named class %s is not a ServiceBase subclass." % fullClassname) return 1 coresUsed = actualClass.coresUsed gbRamUsed = actualClass.gbRamUsed if not parsedArgs.name: name = fullClassname.split(".")[-1] else: name = parsedArgs.name ServiceManager.createOrUpdateServiceWithCodebase(codebase, fullClassname, name, targetCount=None, placement=parsedArgs.placement, coresUsed=coresUsed, gbRamUsed=gbRamUsed) if parsedArgs.command == 'list': table = [['Service', 'Codebase', 'Module', 'Class', 'Placement', 'TargetCount', 'Cores', 'RAM']] with db.view(): for s in sorted(service_schema.Service.lookupAll(), key=lambda s:s.name): table.append([ s.name, str(s.codebase), s.service_module_name, s.service_class_name, s.placement, str(s.target_count), s.coresUsed, s.gbRamUsed ]) print(formatTable(table)) if parsedArgs.command == 'instances': table = [['Service', 'Host', 'Connection', 'State']] with db.view(): for s in sorted(service_schema.ServiceInstance.lookupAll(), key=lambda s:(s.service.name, s.host.hostname, s.state)): table.append([ s.service.name, s.host.hostname, s.connection if s.connection.exists() else "<DEAD>", s.state ]) print(formatTable(table)) if parsedArgs.command == 'hosts': table = [['Connection', 'IsMaster', 'Hostname', 'RAM USAGE', 'CORE USAGE', 'SERVICE COUNT']] with db.view(): for s in sorted(service_schema.ServiceHost.lookupAll(), key=lambda s:s.hostname): table.append([ s.connection._identity, str(s.isMaster), s.hostname, "%.1f / %.1f" % (s.gbRamUsed, s.maxGbRam), "%s / %s" % (s.coresUsed, s.maxCores), str(len(service_schema.ServiceInstance.lookupAll(host=s))) ]) print(formatTable(table)) if parsedArgs.command == 'start': with db.transaction(): s = service_schema.Service.lookupAny(name=parsedArgs.name) if not s: print("Can't find a service named", s) return 1 s.target_count = max(parsedArgs.count, 0) if parsedArgs.command == 'stop': with db.transaction(): s = service_schema.Service.lookupAny(name=parsedArgs.name) if not s: print("Can't find a service named", s) return 1 s.target_count = 0 return 0
def configurableSetUp( self, hostname='localhost', login_plugin_factory=None, # default: LoginIpPlugin, login_config=None, auth_plugins=(None), module=None, db_init_fun=None): self.base_url = "http://{host}:{port}".format(host=hostname, port=WEB_SERVER_PORT) login_plugin_factory = login_plugin_factory or LoginIpPlugin self.token = genToken() log_level = self._logger.getEffectiveLevel() loglevel_name = logging.getLevelName(log_level) self.server, self.cleanupFn = autoconfigure_and_start_service_manager( port=DATABASE_SERVER_PORT, auth_token=self.token, loglevel_name=loglevel_name, own_hostname=hostname, db_hostname=hostname) try: self.database = connect(hostname, DATABASE_SERVER_PORT, self.token, retry=True) self.database.subscribeToSchema(core_schema, service_schema, active_webservice_schema) if db_init_fun is not None: db_init_fun(self.database) codebase = None if module is not None and not module.__name__.startswith( "object_database."): self.database.serializeFromModule(module) root_path = TypedPythonCodebase.rootlevelPathFromModule(module) tpcodebase = TypedPythonCodebase.FromRootlevelPath(root_path) with self.database.transaction(): codebase = service_schema.Codebase.createFromCodebase( tpcodebase) with self.database.transaction(): service = ServiceManager.createOrUpdateService( ActiveWebService, "ActiveWebService", target_count=0) ActiveWebService.configureFromCommandline(self.database, service, [ '--port', str(WEB_SERVER_PORT), '--host', hostname, '--log-level', loglevel_name, ]) if login_config is None: login_config = self.login_config ActiveWebService.setLoginPlugin(self.database, service, login_plugin_factory, auth_plugins, codebase=codebase, config=login_config) with self.database.transaction(): ServiceManager.startService("ActiveWebService", 1) self.waitUntilUp() except Exception: self.cleanupFn(error=True) raise
def main(argv=None): if argv is not None: argv = sys.argv token = genToken() port = 8020 loglevel_name = 'INFO' with tempfile.TemporaryDirectory() as tmpDirName: try: server = start_service_manager(tmpDirName, port, token, loglevel_name=loglevel_name) database = connect("localhost", port, token, retry=True) database.subscribeToSchema(core_schema, service_schema, active_webservice_schema) with database.transaction(): service = ServiceManager.createOrUpdateService( ActiveWebService, "ActiveWebService", target_count=0) ActiveWebService.configureFromCommandline( database, service, ['--port', '8000', '--host', '0.0.0.0', '--log-level', loglevel_name] ) ActiveWebService.setLoginPlugin( database, service, LoginIpPlugin, [None], config={'company_name': 'A Testing Company'} ) with database.transaction(): ServiceManager.startService("ActiveWebService", 1) with database.transaction(): service = ServiceManager.createOrUpdateService( UninitializableService, "UninitializableService", target_count=1 ) with database.transaction(): service = ServiceManager.createOrUpdateService( HappyService, "HappyService", target_count=1 ) with database.transaction(): service = ServiceManager.createOrUpdateService( GraphDisplayService, "GraphDisplayService", target_count=1 ) with database.transaction(): service = ServiceManager.createOrUpdateService( TextEditorService, "TextEditorService", target_count=1 ) with database.transaction(): service = ServiceManager.createOrUpdateService( DropdownTestService, "DropdownTestService", target_count=1 ) with database.transaction(): service = ServiceManager.createOrUpdateService( BigGridTestService, "BigGridTestService", target_count=1 ) with database.transaction(): ServiceManager.createOrUpdateServiceWithCodebase( service_schema.Codebase.createFromFiles({ 'test_service/__init__.py': '', 'test_service/service.py': textwrap.dedent(""" from object_database.service_manager.ServiceBase import ServiceBase class TestService(ServiceBase): gbRamUsed = 0 coresUsed = 0 def initialize(self): with self.db.transaction(): self.runtimeConfig.serviceInstance.statusMessage = "Loaded" def doWork(self, shouldStop): shouldStop.wait() def display(self, queryParams=None): return "test service display message" """) }), "test_service.service.TestService", "TestService", 10 ) print("SERVER IS BOOTED") while True: time.sleep(.1) finally: server.terminate() server.wait() return 0
def main(argv): parser = argparse.ArgumentParser("Control the AWS service") parser.add_argument("--hostname", default=os.getenv("ODB_HOST", "localhost"), required=False) parser.add_argument("--port", type=int, default=int(os.getenv("ODB_PORT", 8000)), required=False) parser.add_argument("--auth", type=str, default=os.getenv("ODB_AUTH_TOKEN"), required=False, help="Auth token to use to connect.") subparsers = parser.add_subparsers() config_parser = subparsers.add_parser('config', help='configure the service') config_parser.set_defaults(command='config') config_parser.add_argument('--region', required=False) config_parser.add_argument('--vpc_id', required=False) config_parser.add_argument('--subnet', required=False) config_parser.add_argument('--security_group', required=False) config_parser.add_argument('--keypair', required=False) config_parser.add_argument('--worker_name', required=False) config_parser.add_argument('--worker_iam_role_name', required=False) config_parser.add_argument('--docker_image', required=False) config_parser.add_argument('--defaultStorageSize', required=False, type=int) config_parser.add_argument('--max_to_boot', required=False, type=int) install_parser = subparsers.add_parser('install', help='install the service') install_parser.set_defaults(command='install') list_parser = subparsers.add_parser('list', help='list machines') list_parser.set_defaults(command='list') boot_parser = subparsers.add_parser('boot', help='set the number of desired boxes') boot_parser.set_defaults(command='boot') boot_parser.add_argument("instance_type") boot_parser.add_argument("count", type=int) killall_parser = subparsers.add_parser('killall', help='kill everything') killall_parser.set_defaults(command='killall') reset_parser = subparsers.add_parser('reset', help='kill everything') reset_parser.set_defaults(command='reset') configureLogging() parsedArgs = parser.parse_args(argv[1:]) db = connect(parsedArgs.hostname, parsedArgs.port, parsedArgs.auth) db.subscribeToSchema(service_schema, lazySubscription=True) db.subscribeToSchema(aws_worker_boot_schema) if parsedArgs.command == 'reset': with db.transaction(): for s in aws_worker_boot_schema.State.lookupAll(): s.delete() if parsedArgs.command == 'config': with db.transaction(): AwsWorkerBootService.configure( db_hostname=parsedArgs.hostname, db_port=parsedArgs.port, region=parsedArgs.region, vpc_id=parsedArgs.vpc_id, subnet=parsedArgs.subnet, security_group=parsedArgs.security_group, keypair=parsedArgs.keypair, worker_name=parsedArgs.worker_name, worker_iam_role_name=parsedArgs.worker_iam_role_name, docker_image=parsedArgs.docker_image, defaultStorageSize=parsedArgs.defaultStorageSize, max_to_boot=parsedArgs.max_to_boot) if parsedArgs.command == 'install': with db.transaction(): ServiceManager.createOrUpdateService(AwsWorkerBootService, "AwsWorkerBootService", placement="Master") if parsedArgs.command == 'list': print() print() with db.view(): api = AwsApi() booted = AwsWorkerBootService.currentBooted() targets = AwsWorkerBootService.currentTargets() table = [["Instance Type", "Booted", "Desired"]] for instance_type in sorted(set(list(booted) + list(targets))): table.append([ instance_type, booted.get(instance_type, 0), targets.get(instance_type, 0) ]) print(formatTable(table)) print() print() with db.view(): api = AwsApi() table = [["InstanceID", "InstanceType", "IP", "Uptime"]] for instanceId, instance in api.allRunningInstances( spot=None).items(): table.append([ instance['InstanceId'], instance['InstanceType'], instance['PrivateIpAddress'], secondsToHumanReadable(time.time() - instance['LaunchTime'].timestamp()) ]) print(formatTable(table)) print() print() if parsedArgs.command == 'boot': with db.transaction(): AwsWorkerBootService.setBootState(parsedArgs.instance_type, parsedArgs.count) if parsedArgs.command == 'killall': with db.transaction(): AwsWorkerBootService.shutdownAll() with db.view(): api = AwsApi() for i in api.allRunningInstances(): try: api.terminateInstanceById(i) except Exception: pass return 0