def run(self): self.app.register_backend(self.srv_type, self.service_backend) if self.reg_srv: self.register_service() # setup shutdown handler for de-registration of service for sig in [signal.SIGTERM, signal.SIGINT, signal.SIGHUP, signal.SIGQUIT]: signal.signal(sig, self.shutdown_handler) up = urlparse(self.stg["service_endpoint"]) dep_port = CONFIG.get("general", "port") if dep_port != "": LOG.warn( "DEPRECATED: parameter general: port in service manager config. " "Service port number (" + str(up.port) + ") is taken from the service manifest" ) if self.DEBUG: from wsgiref.simple_server import make_server httpd = make_server("", int(up.port), self.app) httpd.serve_forever() else: container = wsgi.WSGIContainer(self.app) http_server = httpserver.HTTPServer(container) http_server.listen(int(up.port)) ioloop.IOLoop.instance().start() LOG.info("Service Manager running on interfaces, running on port: " + int(up.port))
def service_parameters(self, state='', content_type='text/occi'): # takes the internal parameters defined for the lifecycle phase... # and combines them with the client supplied parameters if content_type == 'text/occi': params = [] # get the state specific internal parameters try: params = self.service_params[state] except KeyError as err: LOG.warn( 'The requested states parameters are not available: "' + state + '"') # get the client supplied parameters if any try: for p in self.service_params['client_params']: params.append(p) except KeyError as err: LOG.info('No client params') header = '' for param in params: if param['type'] == 'string': value = '"' + param['value'] + '"' else: value = str(param['value']) header = header + param['name'] + '=' + value + ', ' return header[0:-2] else: LOG.error('Content type not supported: ' + content_type)
def run(self): self.app.register_backend(self.srv_type, self.service_backend) if self.reg_srv: self.register_service() # setup shutdown handler for de-registration of service for sig in [signal.SIGTERM, signal.SIGINT, signal.SIGHUP, signal.SIGQUIT]: signal.signal(sig, self.shutdown_handler) up = urlparse(self.stg['service_endpoint']) dep_port = CONFIG.get('general', 'port') if dep_port != '': LOG.warn('DEPRECATED: parameter general: port in service manager config. ' 'Service port number (' + str(up.port) + ') is taken from the service manifest') if self.DEBUG: LOG.debug('Using WSGI reference implementation') httpd = make_server('', int(up.port), self.app) httpd.serve_forever() else: LOG.debug('Using tornado implementation') container = wsgi.WSGIContainer(self.app) http_server = httpserver.HTTPServer(container) http_server.listen(int(up.port)) ioloop.IOLoop.instance().start() LOG.info('Service Manager running on interfaces, running on port: ' + str(up.port))
def service_parameters(self, state='', content_type='text/occi'): # takes the internal parameters defined for the lifecycle phase... # and combines them with the client supplied parameters if content_type == 'text/occi': params = [] # get the state specific internal parameters try: params = self.service_params[state] except KeyError: # as err: LOG.warn('The requested states parameters are not available: "' + state + '"') # get the client supplied parameters if any try: for param in self.service_params['client_params']: params.append(param) except KeyError: # as err: LOG.info('No client params') header = '' for param in params: if param['type'] == 'string': value = '"' + param['value'] + '"' else: value = str(param['value']) header = header + param['name'] + '=' + value + ', ' return header[0:-2] else: LOG.error('Content type not supported: ' + content_type)
def run(self): # example request to the SO # curl -v -X GET http://localhost:8051/orchestrator/default \ # -H 'X-Auth-Token: '$KID \ # -H 'X-Tenant-Name: '$TENANT if self.entity.attributes['mcn.service.state'] in ['activate', 'deploy', 'provision', 'update']: heads = { 'Content-Type': 'text/occi', 'Accept': 'text/occi', 'X-Auth-Token': self.extras['token'], 'X-Tenant-Name': self.extras['tenant_name']} LOG.info('Getting state of service orchestrator with: ' + self.host + '/orchestrator/default') LOG.info('Sending headers: ' + heads.__repr__()) r = http_retriable_request('GET', HTTP + self.host + '/orchestrator/default', headers=heads) attrs = r.headers['x-occi-attribute'].split(', ') for attr in attrs: kv = attr.split('=') if kv[0] != 'occi.core.id': if kv[1].startswith('"') and kv[1].endswith('"'): kv[1] = kv[1][1:-1] # scrub off quotes self.entity.attributes[kv[0]] = kv[1] LOG.debug('OCCI Attribute: ' + kv[0] + ' --> ' + kv[1]) # Assemble the SIG svcinsts = '' try: svcinsts = self.entity.attributes['mcn.so.svcinsts'] del self.entity.attributes['mcn.so.svcinsts'] # remove this, not be be used anywhere else except KeyError: LOG.warn('There was no service instance endpoints - ignore if not a composition.') pass if self.registry is None: LOG.error('No registry!') if len(svcinsts) > 0: svcinsts = svcinsts.split() # all instance EPs for svc_loc in svcinsts: # TODO get the service instance resource representation # source resource is self.entity compos = svc_loc.split('/') key = '/' + compos[3] + '/' + compos[4] target = Resource(key, Resource.kind, []) # target resource target.attributes['mcn.sm.endpoint'] = svc_loc self.registry.add_resource(key, target, None) key = '/link/'+str(uuid.uuid4()) link = Link(key, Link.kind, [], self.entity, target) self.registry.add_resource(key, link, None) self.entity.links.append(link) else: LOG.debug('Cannot GET entity as it is not in the activated, deployed or provisioned, updated state') return self.entity, self.extras
def get_category(self, svc_kind): keystone = client.Client(token=self.token, tenant_name=self.tenant_name, auth_url=self.design_uri) try: svc = keystone.services.find(type=svc_kind.keys()[0]) svc_ep = keystone.endpoints.find(service_id=svc.id) except Exception as e: LOG.error('Cannot find the service endpoint of: ' + svc_kind.__repr__()) raise e u = urlparse(svc_ep.publicurl) # sort out the OCCI QI path if u.path == '/': svc_ep.publicurl += '-/' elif u.path == '': svc_ep.publicurl += '/-/' else: LOG.warn('Service endpoint URL does not look like it will work: ' + svc_ep.publicurl.__repr__()) svc_ep.publicurl = u.scheme + '://' + u.netloc + '/-/' LOG.warn('Trying with the scheme and net location: ' + svc_ep.publicurl.__repr__()) heads = { 'X-Auth-Token': self.token, 'X-Tenant-Name': self.tenant_name, 'Accept': 'application/occi+json' } try: r = requests.get(svc_ep.publicurl, headers=heads) r.raise_for_status() except requests.HTTPError as err: LOG.error('HTTP Error: should do something more here!' + err.message) raise err registry = json.loads(r.content) category = None for cat in registry: if 'related' in cat: category = cat return Kind(scheme=category['scheme'], term=category['term'], related=category['related'], title=category['title'], attributes=category['attributes'], location=category['location'])
def __init__(self, entity, extras): Task.__init__(self, entity, extras, state='initialise') self.nburl = CONFIG.get('cloud_controller', 'nb_api', '') if self.nburl[-1] == '/': self.nburl = self.nburl[0:-1] LOG.info('CloudController Northbound API: ' + self.nburl) if len(entity.attributes) > 0: LOG.info('Client supplied parameters: ' + entity.attributes.__repr__()) # XXX check that these parameters are valid according to the kind specification self.extras['srv_prms'].add_client_params(entity.attributes) else: LOG.warn('No client supplied parameters.')
def __init__(self, app, srv_type=None): # openstack objects tracking the keystone service and endpoint self.srv_ep = None self.ep = None self.DEBUG = True self.app = app self.service_backend = ServiceBackend(app) LOG.info('Using configuration file: ' + CONFIG_PATH) self.token, self.tenant_name = self.get_service_credentials() self.design_uri = CONFIG.get('service_manager', 'design_uri', '') if self.design_uri == '': LOG.fatal('No design_uri parameter supplied in sm.cfg') raise Exception('No design_uri parameter supplied in sm.cfg') self.stg = None stg_path = CONFIG.get('service_manager', 'manifest', '') if stg_path == '': raise RuntimeError('No STG specified in the configuration file.') with open(stg_path) as stg_content: self.stg = json.load(stg_content) stg_content.close() if not srv_type: srv_type = self.create_service_type() self.srv_type = srv_type self.reg_srv = CONFIG.getboolean('service_manager_admin', 'register_service') if self.reg_srv: self.region = CONFIG.get('service_manager_admin', 'region', '') if self.region == '': LOG.info( 'No region parameter specified in sm.cfg, defaulting to an OpenStack default: RegionOne' ) self.region = 'RegionOne' self.service_endpoint = CONFIG.get('service_manager_admin', 'service_endpoint') if self.service_endpoint != '': LOG.warn( 'DEPRECATED: service_endpoint parameter supplied in sm.cfg! Endpoint is now specified in ' 'service manifest as service_endpoint') LOG.info('Using ' + self.stg['service_endpoint'] + ' as the service_endpoint value ' 'from service manifest') up = urlparse(self.stg['service_endpoint']) self.service_endpoint = up.scheme + '://' + up.hostname + ':' + str( up.port) + '/' + str('mobaas') LOG.info(self.service_endpoint)
def __init__(self): self.service_params = {} service_params_file_path = CONFIG.get('service_manager', 'service_params', '') if len(service_params_file_path) > 0: try: with open(service_params_file_path) as svc_params_content: self.service_params = json.load(svc_params_content) svc_params_content.close() except ValueError: # as e: LOG.error("Invalid JSON sent as service config file") except IOError: # as e: LOG.error('Cannot find the specified parameters file: ' + service_params_file_path) else: LOG.warn("No service parameters file found in config file, setting internal params to empty.")
def get_category(self, svc_kind): keystone = client.Client(token=self.token, tenant_name=self.tenant_name, auth_url=self.design_uri) try: svc = keystone.services.find(type=svc_kind.keys()[0]) svc_ep = keystone.endpoints.find(service_id=svc.id) except Exception as e: LOG.error("Cannot find the service endpoint of: " + svc_kind.__repr__()) raise e u = urlparse(svc_ep.publicurl) # sort out the OCCI QI path if u.path == "/": svc_ep.publicurl += "-/" elif u.path == "": svc_ep.publicurl += "/-/" else: LOG.warn("Service endpoint URL does not look like it will work: " + svc_ep.publicurl.__repr__()) svc_ep.publicurl = u.scheme + "://" + u.netloc + "/-/" LOG.warn("Trying with the scheme and net location: " + svc_ep.publicurl.__repr__()) heads = {"X-Auth-Token": self.token, "X-Tenant-Name": self.tenant_name, "Accept": "application/occi+json"} try: r = requests.get(svc_ep.publicurl, headers=heads) r.raise_for_status() except requests.HTTPError as err: LOG.error("HTTP Error: should do something more here!" + err.message) raise err registry = json.loads(r.content) category = None for cat in registry: if "related" in cat: category = cat return Kind( scheme=category["scheme"], term=category["term"], related=category["related"], title=category["title"], attributes=category["attributes"], location=category["location"], )
def __init__(self, app, srv_type=None): # openstack objects tracking the keystone service and endpoint self.srv_ep = None self.ep = None self.DEBUG = True self.app = app self.service_backend = ServiceBackend(app) LOG.info("Using configuration file: " + CONFIG_PATH) self.token, self.tenant_name = self.get_service_credentials() self.design_uri = CONFIG.get("service_manager", "design_uri", "") if self.design_uri == "": LOG.fatal("No design_uri parameter supplied in sm.cfg") raise Exception("No design_uri parameter supplied in sm.cfg") self.stg = None stg_path = CONFIG.get("service_manager", "manifest", "") if stg_path == "": raise RuntimeError("No STG specified in the configuration file.") with open(stg_path) as stg_content: self.stg = json.load(stg_content) stg_content.close() if not srv_type: srv_type = self.create_service_type() self.srv_type = srv_type self.reg_srv = CONFIG.getboolean("service_manager_admin", "register_service") if self.reg_srv: self.region = CONFIG.get("service_manager_admin", "region", "") if self.region == "": LOG.info("No region parameter specified in sm.cfg, defaulting to an OpenStack default: RegionOne") self.region = "RegionOne" self.service_endpoint = CONFIG.get("service_manager_admin", "service_endpoint") if self.service_endpoint != "": LOG.warn( "DEPRECATED: service_endpoint parameter supplied in sm.cfg! Endpoint is now specified in " "service manifest as service_endpoint" ) LOG.info( "Using " + self.stg["service_endpoint"] + " as the service_endpoint value " "from service manifest" ) up = urlparse(self.stg["service_endpoint"]) self.service_endpoint = up.scheme + "://" + up.hostname + ":" + str(up.port)
def __init__(self, app, srv_type=None): # openstack objects tracking the keystone service and endpoint self.srv_ep = None self.ep = None self.DEBUG = True self.app = app self.service_backend = ServiceBackend(app) LOG.info('Using configuration file: ' + CONFIG_PATH) self.token, self.tenant_name = self.get_service_credentials() self.design_uri = CONFIG.get('service_manager', 'design_uri', '') if self.design_uri == '': LOG.fatal('No design_uri parameter supplied in sm.cfg') raise Exception('No design_uri parameter supplied in sm.cfg') self.stg = None stg_path = CONFIG.get('service_manager', 'manifest', '') if stg_path == '': raise RuntimeError('No STG specified in the configuration file.') with open(stg_path) as stg_content: self.stg = json.load(stg_content) stg_content.close() if not srv_type: srv_type = self.create_service_type() self.srv_type = srv_type self.reg_srv = CONFIG.getboolean('service_manager_admin', 'register_service') if self.reg_srv: self.region = CONFIG.get('service_manager_admin', 'region', '') if self.region == '': LOG.info('No region parameter specified in sm.cfg, defaulting to an OpenStack default: RegionOne') self.region = 'RegionOne' self.service_endpoint = CONFIG.get('service_manager_admin', 'service_endpoint') if self.service_endpoint != '': LOG.warn('DEPRECATED: service_endpoint parameter supplied in sm.cfg! Endpoint is now specified in ' 'service manifest as service_endpoint') LOG.info('Using ' + self.stg['service_endpoint'] + ' as the service_endpoint value ' 'from service manifest') up = urlparse(self.stg['service_endpoint']) self.service_endpoint = up.scheme + '://' + up.hostname + ':' + str(up.port) + '/' + str('mobaas') LOG.info(self.service_endpoint)
def get_category(self, svc_kind): keystone = client.Client(token=self.token, tenant_name=self.tenant_name, auth_url=self.design_uri) try: svc = keystone.services.find(type=svc_kind.keys()[0]) svc_ep = keystone.endpoints.find(service_id=svc.id) except Exception as e: LOG.error('Cannot find the service endpoint of: ' + svc_kind.__repr__()) raise e u = urlparse(svc_ep.publicurl) # sort out the OCCI QI path if u.path == '/': svc_ep.publicurl += '-/' elif u.path == '': svc_ep.publicurl += '/-/' else: LOG.warn('Service endpoint URL does not look like it will work: ' + svc_ep.publicurl.__repr__()) svc_ep.publicurl = u.scheme + '://' + u.netloc + '/-/' LOG.warn('Trying with the scheme and net location: ' + svc_ep.publicurl.__repr__()) heads = {'X-Auth-Token': self.token, 'X-Tenant-Name': self.tenant_name, 'Accept': 'application/occi+json'} try: r = requests.get(svc_ep.publicurl, headers=heads) r.raise_for_status() except requests.HTTPError as err: LOG.error('HTTP Error: should do something more here!' + err.message) raise err registry = json.loads(r.content) category = None for cat in registry: if 'related' in cat: category = cat return Kind(scheme=category['scheme'], term=category['term'], related=category['related'], title=category['title'], attributes=category['attributes'], location=category['location'])
def __create_app(self): # will generate an appname 24 chars long - compatible with v2 and v3 # e.g. soandycd009b39c28790f3 app_name = 'so' + self.entity.kind.term[0:4] + \ ''.join(random.choice('0123456789abcdef') for _ in range(16)) heads = {'Content-Type': 'text/occi'} url = self.nburl + '/app/' if self.entity.extras['ops_version'] == 'v2': heads['category'] = 'app; scheme="http://schemas.ogf.org/occi/platform#", ' \ 'python-2.7; scheme="http://schemas.openshift.com/template/app#", ' \ 'small; scheme="http://schemas.openshift.com/template/app#"' heads['X-OCCI-Attribute'] = str('occi.app.name=' + app_name) LOG.debug('Ensuring SM SSH Key...') self.__ensure_ssh_key() elif self.entity.extras['ops_version'] == 'v3': # for OpSv3 bundle location is the repo id of the container image bundle_loc = CONFIG.get('service_manager', 'bundle_location', '') if bundle_loc == '': LOG.error('No bundle_location parameter supplied in sm.cfg') raise Exception('No bundle_location parameter supplied in sm.cfg') if bundle_loc.startswith('/'): LOG.warn('Bundle location does not look like an image reference!') LOG.debug('Bundle to execute: ' + bundle_loc) design_uri = CONFIG.get('service_manager', 'design_uri', '') if design_uri == '': raise Exception('No design_uri parameter supplied in sm.cfg') LOG.debug('Design URI: ' + design_uri) heads['category'] = 'app; scheme="http://schemas.ogf.org/occi/platform#"' # TODO provide a means to provide additional docker env params attrs = 'occi.app.name="' + app_name + '", ' + \ 'occi.app.image="' + bundle_loc + '", ' + \ 'occi.app.env="DESIGN_URI=' + design_uri + '"' heads['X-OCCI-Attribute'] = str(attrs) else: LOG.error('Unknown OpenShift version. ops_version: ' + self.entity.extras['ops_version']) raise Exception('Unknown OpenShift version. ops_version: ' + self.entity.extras['ops_version']) LOG.debug('Requesting container to execute SO Bundle: ' + url) LOG.info('Sending headers: ' + heads.__repr__()) r = http_retriable_request('POST', url, headers=heads, authenticate=True) loc = r.headers.get('Location', '') if loc == '': LOG.error("No OCCI Location attribute found in request") raise AttributeError("No OCCI Location attribute found in request") self.entity.attributes['occi.so.url'] = loc app_uri_path = urlparse(loc).path LOG.debug('SO container created: ' + app_uri_path) LOG.debug('Updating OCCI entity.identifier from: ' + self.entity.identifier + ' to: ' + app_uri_path.replace('/app/', self.entity.kind.location)) self.entity.identifier = app_uri_path.replace('/app/', self.entity.kind.location) LOG.debug('Setting occi.core.id to: ' + app_uri_path.replace('/app/', '')) self.entity.attributes['occi.core.id'] = app_uri_path.replace('/app/', '') # its a bit wrong to put this here, but we do not have the required information before. # this keeps things consistent as the timing is done right infoDict = { 'so_id': self.entity.attributes['occi.core.id'].split('/'), 'sm_name': self.entity.kind.term, 'so_phase': 'init', 'phase_event': 'start', 'response_time': 0, 'tenant': self.extras['tenant_name'] } tmpJSON = json.dumps(infoDict) LOG.debug(tmpJSON) # OpSv2 only: get git uri. this is where our bundle is pushed to # XXX this is fugly # TODO use the same name for the app URI if self.entity.extras['ops_version'] == 'v2': self.entity.extras['repo_uri'] = self.__git_uri(app_uri_path) elif self.entity.extras['ops_version'] == 'v3': self.entity.extras['loc'] = self.__git_uri(app_uri_path)
def __create_app(self): # will generate an appname 24 chars long - compatible with v2 and v3 # e.g. soandycd009b39c28790f3 app_name = 'so' + self.entity.kind.term[0:4] + \ ''.join(random.choice('0123456789abcdef') for _ in range(16)) heads = {'Content-Type': 'text/occi'} url = self.nburl + '/app/' if self.entity.extras['ops_version'] == 'v2': heads['category'] = 'app; scheme="http://schemas.ogf.org/occi/platform#", ' \ 'python-2.7; scheme="http://schemas.openshift.com/template/app#", ' \ 'small; scheme="http://schemas.openshift.com/template/app#"' heads['X-OCCI-Attribute'] = str('occi.app.name=' + app_name) LOG.debug('Ensuring SM SSH Key...') self.__ensure_ssh_key() elif self.entity.extras['ops_version'] == 'v3': # for OpSv3 bundle location is the repo id of the container image bundle_loc = os.environ.get('BUNDLE_LOC', False) if not bundle_loc: bundle_loc = CONFIG.get('service_manager', 'bundle_location', '') if bundle_loc == '': LOG.error('No bundle_location parameter supplied in sm.cfg') raise Exception( 'No bundle_location parameter supplied in sm.cfg') if bundle_loc.startswith('/'): LOG.warn( 'Bundle location does not look like an image reference!') LOG.debug('Bundle to execute: ' + bundle_loc) design_uri = CONFIG.get('service_manager', 'design_uri', '') if design_uri == '': raise Exception('No design_uri parameter supplied in sm.cfg') LOG.debug('Design URI: ' + design_uri) heads[ 'category'] = 'app; scheme="http://schemas.ogf.org/occi/platform#"' # TODO provide a means to provide additional docker env params attrs = 'occi.app.name="' + app_name + '", ' + \ 'occi.app.image="' + bundle_loc + '", ' + \ 'occi.app.env="DESIGN_URI=' + design_uri + '"' heads['X-OCCI-Attribute'] = str(attrs) else: LOG.error('Unknown OpenShift version. ops_version: ' + self.entity.extras['ops_version']) raise Exception('Unknown OpenShift version. ops_version: ' + self.entity.extras['ops_version']) LOG.debug('Requesting container to execute SO Bundle: ' + url) LOG.info('Sending headers: ' + heads.__repr__()) r = http_retriable_request('POST', url, headers=heads, authenticate=True) loc = r.headers.get('Location', '') if loc == '': LOG.error("No OCCI Location attribute found in request") raise AttributeError("No OCCI Location attribute found in request") self.entity.attributes['occi.so.url'] = loc app_uri_path = urlparse(loc).path LOG.debug('SO container created: ' + app_uri_path) LOG.debug('Updating OCCI entity.identifier from: ' + self.entity.identifier + ' to: ' + app_uri_path.replace('/app/', self.entity.kind.location)) self.entity.identifier = app_uri_path.replace( '/app/', self.entity.kind.location) LOG.debug('Setting occi.core.id to: ' + app_uri_path.replace('/app/', '')) self.entity.attributes['occi.core.id'] = app_uri_path.replace( '/app/', '') # its a bit wrong to put this here, but we do not have the required information before. # this keeps things consistent as the timing is done right infoDict = { 'so_id': self.entity.attributes['occi.core.id'].split('/'), 'sm_name': self.entity.kind.term, 'so_phase': 'init', 'phase_event': 'start', 'response_time': 0, 'tenant': self.extras['tenant_name'] } tmpJSON = json.dumps(infoDict) LOG.debug(tmpJSON) # OpSv2 only: get git uri. this is where our bundle is pushed to # XXX this is fugly # TODO use the same name for the app URI if self.entity.extras['ops_version'] == 'v2': self.entity.extras['repo_uri'] = self.__git_uri(app_uri_path) elif self.entity.extras['ops_version'] == 'v3': self.entity.extras['loc'] = self.__git_uri(app_uri_path)
def __create_app(self): # will generate an appname 24 chars long - compatible with v2 and v3 # e.g. soandycd009b39c28790f3 app_name = 'so' + self.entity.kind.term[0:4] + \ ''.join(random.choice('0123456789abcdef') for _ in range(16)) heads = {'Content-Type': 'text/occi'} url = self.nburl + '/app/' if self.entity.extras['ops_version'] == 'v2': heads['category'] = 'app; scheme="http://schemas.ogf.org/occi/platform#", ' \ 'python-2.7; scheme="http://schemas.openshift.com/template/app#", ' \ 'small; scheme="http://schemas.openshift.com/template/app#"' heads['X-OCCI-Attribute'] = str('occi.app.name=' + app_name) LOG.debug('Ensuring SM SSH Key...') self.__ensure_ssh_key() elif self.entity.extras['ops_version'] == 'v3': # for OpSv3 bundle location is the repo id of the container image bundle_loc = CONFIG.get('service_manager', 'bundle_location', '') if bundle_loc == '': LOG.error('No bundle_location parameter supplied in sm.cfg') raise Exception('No bundle_location parameter supplied in sm.cfg') if bundle_loc.startswith('/'): LOG.warn('Bundle location does not look like an image reference!') LOG.debug('Bundle to execute: ' + bundle_loc) design_uri = CONFIG.get('service_manager', 'design_uri', '') if design_uri == '': raise Exception('No design_uri parameter supplied in sm.cfg') LOG.debug('Design URI: ' + design_uri) heads['category'] = 'app; scheme="http://schemas.ogf.org/occi/platform#"' # TODO provide a means to provide additional docker env params attrs = 'occi.app.name="' + app_name + '", ' + \ 'occi.app.image="' + bundle_loc + '", ' + \ 'occi.app.env="DESIGN_URI=' + design_uri + '"' heads['X-OCCI-Attribute'] = str(attrs) else: LOG.error('Unknown OpenShift version. ops_version: ' + self.entity.extras['ops_version']) raise Exception('Unknown OpenShift version. ops_version: ' + self.entity.extras['ops_version']) LOG.debug('Requesting container to execute SO Bundle: ' + url) LOG.info('Sending headers: ' + heads.__repr__()) r = http_retriable_request('POST', url, headers=heads, authenticate=True) loc = r.headers.get('Location', '') if loc == '': LOG.error("No OCCI Location attribute found in request") raise AttributeError("No OCCI Location attribute found in request") app_uri_path = urlparse(loc).path LOG.debug('SO container created: ' + app_uri_path) LOG.debug('Updating OCCI entity.identifier from: ' + self.entity.identifier + ' to: ' + app_uri_path.replace('/app/', self.entity.kind.location)) self.entity.identifier = app_uri_path.replace('/app/', self.entity.kind.location) LOG.debug('Setting occi.core.id to: ' + app_uri_path.replace('/app/', '')) self.entity.attributes['occi.core.id'] = app_uri_path.replace('/app/', '') # OpSv2 only: get git uri. this is where our bundle is pushed to # XXX this is fugly # TODO use the same name for the app URI if self.entity.extras['ops_version'] == 'v2': self.entity.extras['repo_uri'] = self.__git_uri(app_uri_path) elif self.entity.extras['ops_version'] == 'v3': self.entity.extras['loc'] = self.__git_uri(app_uri_path) # wait until occi.app.state="active" - loop a GET # this may not be applicable to OpSv2 LOG.info('checking: ' + loc) while not self.__is_complete(loc): time.sleep(3)