def test_service_create_uid(self): # make sure we don't have any template loaded in the current process tcol._templates = {} with self.assertRaises(TemplateNotFoundError, msg='trying to create a service from non handled template should raise '): self.api.services.create("github.com/threefoldtech/0-robot/node/0.0.1", 'node1') # load template in current process with tempfile.TemporaryDirectory(prefix="robotlocal") as tmpdir: config.data_repo = config.DataRepo(tmpdir) tcol.add_repo('http://github.com/threefoldtech/0-robot', directory='tests/fixtures/templates') # now that we have some templates loaded, it should create a local service node2 = self.api.services.create("github.com/threefoldtech/0-robot/node/0.0.1", 'node2') self.assertTrue(isinstance(node2, TemplateBase)) # the api should get all services from the local robot only self.assertEqual(len(self.api.services.names), 1) self.assertEqual(len(self.api.services.guids), 1) # make sure remote robot doesn't have service created on them for instance in self.api.robots.list(): robot = self.api.robots.get(instance) self.assertEqual(len(robot.services.names), 0) robot = self.api.robots.get('robot1') node = robot.services.create("github.com/threefoldtech/0-robot/node/0.0.1", 'node3') self.assertEqual(type(node), ServiceProxy, "service create on remote robot should return ServiceProxy") self.assertEqual(len(robot.services.guids), 1) # ensure we can access the remote service from the robot object assert robot.services.names[node.name] assert robot.services.guids[node.guid]
def _create_node_service(): service_found = scol.find(template_host='github.com', template_account='zero-os', template_name='node') if not service_found: template_found = tcol.find(host='github.com', account='zero-os', name='node') if not template_found: tcol.add_repo("https://github.com/zero-os/0-templates") template_found = tcol.find(host='github.com', account='zero-os', name='node') if not template_found: raise RuntimeError( "cannot create node service and --mode node is set") logger.info("create node service because --mode node is net") node = tcol.instantiate_service(template_found[0], 'local', {}) else: node = service_found[0] try: node.state.check('actions', 'install', 'ok') except: node.schedule_action('install') node.schedule_action('_register')
def setUp(self): config.data_repo = config.DataRepo( tempfile.mkdtemp(prefix='0robottest')) tcol.add_repo("https://github.com/threefoldtech/0-robot", directory='tests/fixtures/templates') scol.drop_all() storage.init(config)
def test_service_exists(self): # load template in current process with self.subTest(name='local'): with tempfile.TemporaryDirectory(prefix="robotlocal") as tmpdir: config.data_repo = config.DataRepo(tmpdir) tcol.add_repo('http://github.com/zero-os/0-robot', directory='tests/fixtures/templates') self._test_exists(self.api) with self.subTest(name='remote'): self._test_exists(self.api.robots['robot1'])
def test_service_find_or_create(self): with self.subTest(name='local'): # load template in current process with tempfile.TemporaryDirectory(prefix="robotlocal") as tmpdir: config.data_repo = config.DataRepo(tmpdir) tcol.add_repo('http://github.com/threefoldtech/0-robot', directory='tests/fixtures/templates') self._test_find_or_create(self.api) with self.subTest(name='remote'): self._test_find_or_create(self.api.robots.get('robot1'))
def add_repo(self, url, branch='master'): """ Add a new template repository returns the templates that were added from this repository """ return tcol.add_repo(url=url, branch=branch)
def load_services(data_dir): if not os.path.exists(data_dir): os.makedirs(data_dir) for srv_dir in j.sal.fs.listDirsInDir(data_dir, recursive=True): info_path = os.path.join(srv_dir, 'service.yaml') if not os.path.exists(info_path): continue service_info = j.data.serializer.yaml.load(info_path) tmpl_uid = TemplateUID.parse(service_info['template']) try: tmplClass = tcol.get(str(tmpl_uid)) except tcol.TemplateNotFoundError: # template of the service not found, could be we have the template but not the same version # try to get the template without specifiying version tmplClasses = tcol.find(host=tmpl_uid.host, account=tmpl_uid.account, repo=tmpl_uid.repo, name=tmpl_uid.name) size = len(tmplClasses) if size > 1: raise RuntimeError("more then one template version found, this should never happens") elif size < 1: # if the template is not found, try to add the repo using the info of the service template uid url = "http://%s/%s/%s" % (tmpl_uid.host, tmpl_uid.account, tmpl_uid.repo) tcol.add_repo(url) tmplClass = tcol.get(service_info['template']) else: # template of another version found, use newer version to load the service tmplClass = tmplClasses[0] srv = scol.load(tmplClass, srv_dir) loading_failed = [] for service in scol.list_services(): try: service.validate() except Exception as err: logger.error("fail to load %s: %s" % (service.guid, str(err))) # the service is not going to process its task list until it can # execute validate() without problem service.gl_mgr.stop('executor') loading_failed.append(service) if len(loading_failed) > 0: gevent.spawn(_try_load_service, loading_failed)
def test_service_create_validate_fail(self): # make sure we don't have any template loaded in the current process tcol._templates = {} with self.assertRaises(TemplateNotFoundError, msg='trying to create a service from non handled template should raise '): self.api.services.create("validate", 'service1') # load template in current process with tempfile.TemporaryDirectory(prefix="robotlocal") as tmpdir: config.data_repo = config.DataRepo(tmpdir) tcol.add_repo('http://github.com/threefoldtech/0-robot', directory='tests/fixtures/templates') # try to create a service with wrong data, it should raise robot = self.api.robots.get('robot1') with pytest.raises(ServiceCreateError): service = robot.services.create("validate", 'service1') # create the same service with valid data, it should succeed assert len(robot.services.find()) == 0 service = robot.services.create("validate", 'service1', {'required': True}) assert len(robot.services.find()) == 1
def load_services(config): for service_details in storage.list(): tmpl_uid = TemplateUID.parse(service_details['service']['template']) try: tmplClass = tcol.get(str(tmpl_uid)) except tcol.TemplateNotFoundError: # template of the service not found, could be we have the template but not the same version # try to get the template without specifiying version tmplClasses = tcol.find(host=tmpl_uid.host, account=tmpl_uid.account, repo=tmpl_uid.repo, name=tmpl_uid.name) size = len(tmplClasses) if size > 1: raise RuntimeError("more then one template version found, this should never happens") elif size < 1: # if the template is not found, try to add the repo using the info of the service template uid url = "http://%s/%s/%s" % (tmpl_uid.host, tmpl_uid.account, tmpl_uid.repo) tcol.add_repo(url) tmplClass = tcol.get(service_details['service']['template']) else: # template of another version found, use newer version to load the service tmplClass = tmplClasses[0] scol.load(tmplClass, service_details) loading_failed = [] logger = j.logger.get('zerorobot') for service in scol.list_services(): try: service.validate() except Exception as err: logger.error("fail to load %s: %s" % (service.guid, str(err))) # the service is not going to process its task list until it can # execute validate() without problem service.gl_mgr.stop('executor') loading_failed.append(service) if len(loading_failed) > 0: gevent.spawn(_try_load_service, loading_failed)
def AddTemplateRepoHandler(): ''' Clone a template repository and make the templates available to the ZeroRobot It is handler for POST /templates ''' inputs = request.get_json() try: TemplateRepository_schema_validator.validate(inputs) except jsonschema.ValidationError as e: return json.dumps({ 'code': 400, 'message': "bad request body" }), 400, { "Content-type": 'application/json' } added = tcol.add_repo(inputs['url'], branch=inputs.get('branch', 'master')) templates = [template_view(t) for t in added] return json.dumps(templates), 201, {"Content-type": 'application/json'}
def add_template_repo(self, url, directory='templates'): url, branch = giturl.parse_template_repo_url(url) tcol.add_repo(url=url, branch=branch, directory=directory)
def setUp(self): tcol.add_repo("https://github.com/zero-os/0-robot", directory='tests/fixtures/templates') scol.drop_all()