def start(self): from webapp.libs.openstack import flavor_verify_install from webapp.libs.openstack import image_verify_install from webapp.libs.openstack import instance_start # build the response response = {"response": "success", "result": {"message": ""}} # appliance appliance = Appliance().get() # load the callback url (expected to be None) callback_url = self.callback_url # check if instance needs to reset epoch_time = int(time.time()) if self.expires < epoch_time: # instance time expired, so don't start self.state = 1 self.update() response['response'] = "error" response['result']['message'] = "Instance payment is expired. Now waiting on payment." # we run a maximum of 7 callback checks for loop_count in range(7): # make a call to the callback url to get instance details next_state = 3 # hack the expected next state into the pool packet pool_response = pool_instance(url=callback_url, instance=self, next_state=next_state, appliance=appliance) # check for a failure to contact the callback server if pool_response['response'] == "error": self.message = pool_response['result']['message'] self.message_count = self.message_count + 1 self.update() return pool_response # look and see if we have a callback_url in the response try: callback_url = pool_response['result']['instance']['callback_url'] # run the loop again to call the callback url continue except: # break out break # for else returns a depth error else: response['response'] = "error" response['result']['message'] = "Callback depth exceeded." self.message = response['result']['message'] self.message_count = self.message_count + 1 self.update() return response # and lo, callback_url is saved self.callback_url = callback_url self.update() # get the image name if it exists in the response try: image_name = pool_response['result']['instance']['image'] image = db.session.query(Images).filter_by(name=image_name).first() self.image_id = image.id self.update() except: image_name = None # get the dynamic image url if it exists in the response try: dynamic_image_url = pool_response['result']['instance']['dynamic_image_url'] self.dynamic_image_url = dynamic_image_url self.update() except: # not good, but we can use a default image = db.session.query(Images).first() self.image_id = image.id self.update() # post creation file is blank to start post_creation_ssh_key_combo = "" # load the parser to unencode jinja2 template escaping from appliance h = HTMLParser() # ssh_key unrolling try: ssh_key = pool_response['result']['instance']['ssh_key'] # an array # loop through both strings and cat onto post_creation_ssh_key_combo # using prefered method of injecting keys with cloud-init post_creation_ssh_key_combo += "#cloud-config\n" post_creation_ssh_key_combo += "ssh_authorized_keys:\n" for line in ssh_key: post_creation_ssh_key_combo += " - %s\n" % h.unescape(line) post_creation_ssh_key_combo += "\n" except: # do nothing on various key failure pass # post creation configuration handling try: post_creation = pool_response['result']['instance']['post_creation'] # an array for line in post_creation: # import what the user put in the textbox for their wisp post_creation_ssh_key_combo += "%s\n" % h.unescape(line) except: # do nothing on post creation failure pass # update the instance with post creation self.post_creation = post_creation_ssh_key_combo self.update() # take the instance's flavor and verify install flavor = Flavors().get_by_id(self.flavor.id) osflavor = flavor_verify_install(flavor) if osflavor['response'] == "error": # we've failed to install flavor, so we disable it flavor.osid = "" flavor.active = 0 flavor.update() # now we disable the other instances using the flavor instances = Instances() instances.toggle(flavor.id, 0) # disable this instance self.state = 0 self.expires = self.created # zeros out the payment self.update() # log it app.logger.error("Disabling all instances using flavor=(%s) due to OpenStack failure." % flavor.name) # build the response and return response['response'] = "error" response['result']['message'] = "Error creating flavor inside OpenStack." return response # deal with creating dynamic image or use predefined one if self.dynamic_image_url: image = Images().get_or_create_by_instance(self) else: image = Images().get_by_id(self.image.id) if not image: response['response'] = "error" response['result']['message'] = "Error creating dynamic image." return response else: self.image = image self.update() # take the image and verify install osimage = image_verify_install(self.image) # handle failures of either flavor or image if osimage['response'] == "error": response['response'] = "error" response['result']['message'] = "Error creating image." return response # tell openstack to start the instance cluster_response = instance_start(self) # process response if cluster_response['response'] == "success": server = cluster_response['result']['server'] self.osid = server.id # assign openstack instance id self.state = 3 # mark as starting self.update() response['result'] = cluster_response['result'] else: response = cluster_response return response
def start(self): from webapp.libs.openstack import flavor_verify_install from webapp.libs.openstack import image_verify_install from webapp.libs.openstack import instance_start # build the response response = {"response": "success", "result": {"message": ""}} # appliance appliance = Appliance().get() # load the callback url (expected to be None) callback_url = self.callback_url # check if instance needs to reset epoch_time = int(time.time()) if self.expires < epoch_time: # instance time expired, so don't start self.state = 1 self.update() response['response'] = "error" response['result'][ 'message'] = "Instance payment is expired. Now waiting on payment." # we run a maximum of 7 callback checks for loop_count in range(7): # make a call to the callback url to get instance details next_state = 3 # hack the expected next state into the pool packet pool_response = pool_instance(url=callback_url, instance=self, next_state=next_state, appliance=appliance) # check for a failure to contact the callback server if pool_response['response'] == "error": self.message = pool_response['result']['message'] self.message_count = self.message_count + 1 self.update() return pool_response # look and see if we have a callback_url in the response try: callback_url = pool_response['result']['instance'][ 'callback_url'] # run the loop again to call the callback url continue except: # break out break # for else returns a depth error else: response['response'] = "error" response['result']['message'] = "Callback depth exceeded." self.message = response['result']['message'] self.message_count = self.message_count + 1 self.update() return response # and lo, callback_url is saved self.callback_url = callback_url self.update() # get the image name if it exists in the response try: image_name = pool_response['result']['instance']['image'] image = db.session.query(Images).filter_by(name=image_name).first() self.image_id = image.id self.update() except: image_name = None # get the dynamic image url if it exists in the response try: dynamic_image_url = pool_response['result']['instance'][ 'dynamic_image_url'] self.dynamic_image_url = dynamic_image_url self.update() except: # not good, but we can use a default image = db.session.query(Images).first() self.image_id = image.id self.update() # post creation file is blank to start post_creation_ssh_key_combo = "" # load the parser to unencode jinja2 template escaping from appliance h = HTMLParser() # ssh_key unrolling try: ssh_key = pool_response['result']['instance'][ 'ssh_key'] # an array # loop through both strings and cat onto post_creation_ssh_key_combo # using prefered method of injecting keys with cloud-init post_creation_ssh_key_combo += "#cloud-config\n" post_creation_ssh_key_combo += "ssh_authorized_keys:\n" for line in ssh_key: post_creation_ssh_key_combo += " - %s\n" % h.unescape(line) post_creation_ssh_key_combo += "\n" except: # do nothing on various key failure pass # post creation configuration handling try: post_creation = pool_response['result']['instance'][ 'post_creation'] # an array for line in post_creation: # import what the user put in the textbox for their wisp post_creation_ssh_key_combo += "%s\n" % h.unescape(line) except: # do nothing on post creation failure pass # update the instance with post creation self.post_creation = post_creation_ssh_key_combo self.update() # take the instance's flavor and verify install flavor = Flavors().get_by_id(self.flavor.id) osflavor = flavor_verify_install(flavor) if osflavor['response'] == "error": # we've failed to install flavor, so we disable it flavor.osid = "" flavor.active = 0 flavor.update() # now we disable the other instances using the flavor instances = Instances() instances.toggle(flavor.id, 0) # disable this instance self.state = 0 self.expires = self.created # zeros out the payment self.update() # log it app.logger.error( "Disabling all instances using flavor=(%s) due to OpenStack failure." % flavor.name) # build the response and return response['response'] = "error" response['result'][ 'message'] = "Error creating flavor inside OpenStack." return response # deal with creating dynamic image or use predefined one if self.dynamic_image_url: image = Images().get_or_create_by_instance(self) else: image = Images().get_by_id(self.image.id) if not image: response['response'] = "error" response['result']['message'] = "Error creating dynamic image." return response else: self.image = image self.update() # take the image and verify install osimage = image_verify_install(self.image) # handle failures of either flavor or image if osimage['response'] == "error": response['response'] = "error" response['result']['message'] = "Error creating image." return response # tell openstack to start the instance cluster_response = instance_start(self) # process response if cluster_response['response'] == "success": server = cluster_response['result']['server'] self.osid = server.id # assign openstack instance id self.state = 3 # mark as starting self.update() response['result'] = cluster_response['result'] else: response = cluster_response return response