def action(): """ Performs a sync from the pool's list of flavors to the appliance. Cron: Every 15 minutes. """ # get the appliance for api token (not required, but sent if we have it) appliance = db.session.query(Appliance).first() # sync the flavors flavors = Flavors() response = flavors.sync(appliance)
def action(ip=('i', default_ip)): """ Installs a new database configuration for the appliance. """ # create all tables db.create_all() if not Appliance.get(): # initialize the appliance object appliance = Appliance() appliance.initialize(ip) # sync flavors from pool (openstack sync comes later when we have a user) flavors = Flavors().sync() # configure output configure_blurb()
def action(ip=('i', default_ip)): """ Restores the appliance to factory default settings. """ try: if ip == default_ip: print "Please enter the appliance's IP address." print "Usage: ./manage.py reset -i x.x.x.x" return action # double check they want to do this if query_yes_no("Are you sure you want to reset the appliance?"): # initialize database path = os.path.dirname(os.path.abspath(__file__)) os.system('sqlite3 "%s/utterio.db" < "%s/schema.sql"' % (path, path)) # initialize the appliance object appliance = Appliance() appliance.initialize(ip) # sync with pool database images = Images() iresponse = images.sync(appliance) flavors = Flavors() fresponse = flavors.sync(appliance) if iresponse['response'] != "success": print iresponse['result'] elif fresponse['response'] != "success": print iresponse['result'] else: print "The database has been cleared and a new API token has been generated." configure_blurb() except ValueError as ex: print ex
def action(ip=('i', default_ip)): """ Installs a new database configuration for the appliance. """ # run database reset script - use current path to run file path = os.path.dirname(os.path.abspath(__file__)) # initialize database os.system('sqlite3 "%s/utterio.db" < "%s/schema.sql"' % (path, path)) # initialize the appliance object appliance = Appliance() appliance.initialize(ip) # sync to remote database images = Images() response = images.sync(appliance) flavors = Flavors() response = flavors.sync(appliance) # configure output configure_blurb()
def action(ip=('i', default_ip)): """ Restores the appliance to factory default settings. """ try: if ip == default_ip: print "Please enter the appliance's IP address." print "Usage: ./manage.py reset -i x.x.x.x" return action # double check they want to do this if query_yes_no("Are you sure you want to reset the appliance?"): # initialize database path = os.path.dirname(os.path.abspath(__file__)) os.system('cp "%s/utterio.db" "%s/utterio_backup.db"' % (path, path)) # delete, then create all tables db.drop_all() db.create_all() # initialize the appliance object appliance = Appliance() appliance.initialize(ip) # sync with pool database flavors = Flavors().sync() if flavors['response'] != "success": print flavors['result'] else: print "The database has been cleared and a new API token has been generated." configure_blurb() except ValueError as ex: print ex
def check_settings(self): status = db.session.query(Status).first() # calculate cache timeout (120 seconds) epoch_time = int(time.time()) try: if (status.updated + 900) < epoch_time: # it's been 15 minutes so we are hot check = True else: check = False except: # need to create a new entry check = True status = Status() # objects appliance = Appliance().get() openstack = OpenStack() flavors = Flavors() # if the cache time has been a while, or we are on # the configuration page, check settings and cache if check: app.logger.info("Running full status check.") # openstack connected? openstack_check = openstack.check() status.openstack_check = openstack_check['result'] # coinbase tokens working? coinbase_check = coinbase_checker(appliance) status.coinbase_check = coinbase_check # token valid? response = pool_connect(method='authorization', appliance=appliance) if response['response'] == "success": token_check = True else: token_check = False status.token_check = token_check # update database status.updated = epoch_time # ngrok connection ngrok_check = ngrok_checker(appliance) status.ngrok_check = ngrok_check # one flavor installed? flavors_check = flavors.check() status.flavors_check = flavors_check status.update() else: # app.logger.info("Running partial status check.") # stuff we check all the time # openstack connected? openstack_check = openstack.check() status.openstack_check = openstack_check['result'] # ngrok connection ngrok_check = ngrok_checker(appliance) status.ngrok_check = ngrok_check # one flavor installed? flavors_check = flavors.check() status.flavors_check = flavors_check # update status.update() # build the response object settings = { "flavors": status.flavors_check, "openstack": status.openstack_check, "coinbase": status.coinbase_check, "ngrok": status.ngrok_check, "token": status.token_check, } return settings
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