diff options
Diffstat (limited to 'tools/laas-fog/source/pharos.py')
-rwxr-xr-x | tools/laas-fog/source/pharos.py | 217 |
1 files changed, 0 insertions, 217 deletions
diff --git a/tools/laas-fog/source/pharos.py b/tools/laas-fog/source/pharos.py deleted file mode 100755 index d5a6e8a8..00000000 --- a/tools/laas-fog/source/pharos.py +++ /dev/null @@ -1,217 +0,0 @@ -#!/usr/bin/python -""" -############################################################################# -#Copyright 2017 Parker Berberian and others # -# # -#Licensed under the Apache License, Version 2.0 (the "License"); # -#you may not use this file except in compliance with the License. # -#You may obtain a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -#Unless required by applicable law or agreed to in writing, software # -#distributed under the License is distributed on an "AS IS" BASIS, # -#WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -#See the License for the specific language governing permissions and # -#limitations under the License. # -############################################################################# -""" - -import requests -import time -import calendar -import subprocess -import sys -import yaml -import os -import logging -from utilities import Utilities -from database import BookingDataBase - - -class Pharos_api: - """ - This class listens to the dashboard and starts/stops bookings accordingly. - This class should run in the background indefinitely. - Do not execute this file directly - run ./listen.py instead - """ - def __init__(self, config): - """ - init function. - config is the already-parsed config file - """ - self.conf = config - self.servers = yaml.safe_load(open(config['inventory'])) - self.log = self.createLogger("pharos_api") - self.polling = 60 / int(config['polling']) - self.log.info( - "polling the dashboard once every %d seconds", self.polling) - self.dashboard = config['dashboard'] - self.log.info("connecting to dashboard at %s", self.dashboard) - if os.path.isfile(config['token']): - self.token = open(config['token']).read() - else: - self.token = config['token'] - self.updateHeader() - self.database = BookingDataBase(config['database']) - self.log.info("using database at %s", self.conf['database']) - self.deploy_path = os.path.join( - os.path.dirname(os.path.realpath(__file__)), "deploy.py") - if not os.path.isfile(self.deploy_path): - self.log.error( - "Cannot find the deployment script at %s", self.deploy_path) - - def setToken(self, token): - """ - Sets authentication token. Not yet needed. - """ - self.token = token - self.updateHeader() - - def setTokenFromFile(self, path): - """ - reads auth token from a file. Not yet needed. - """ - self.setToken(open(path).read()) - - def updateHeader(self): - """ - updates the http header used when talking to the dashboard - """ - self.header = {"Authorization": "Token " + self.token} - - def listen(self): - """ - this method will continuously poll the pharos dashboard. - If a booking is found on our server, - we will start a deployment in the background with the - proper config file for the requested - installer and scenario. - """ - self.log.info("%s", "Beginning polling of dashboard") - try: - while True: - time.sleep(self.polling) - url = self.dashboard+"/api/bookings/" - bookings = requests.get(url, headers=self.header).json() - for booking in bookings: - if booking['resource_id'] in self.servers.keys(): - self.convertTimes(booking) - self.database.checkAddBooking(booking) - self.checkBookings() - except Exception: - self.log.exception('%s', "failed to connect to dashboard") - - self.listen() - - def convertTimes(self, booking): - """ - this method will take the time reported by Pharos in the - format yyyy-mm-ddThh:mm:ssZ - and convert it into seconds since the epoch, - for easier management - """ - booking['start'] = self.pharosToEpoch(booking['start']) - booking['end'] = self.pharosToEpoch(booking['end']) - - def pharosToEpoch(self, timeStr): - """ - Converts the dates from the dashboard to epoch time. - """ - time_struct = time.strptime(timeStr, '%Y-%m-%dT%H:%M:%SZ') - epoch_time = calendar.timegm(time_struct) - return epoch_time - - def checkBookings(self): - """ - This method checks all the bookings in our database to see if any - action is required. - """ - # get all active bookings from database into a usable form - bookings = self.database.getBookings() - for booking in bookings: - # first, check if booking is over - if time.time() > booking[3]: - self.log.info("ending the booking with id %i", booking[0]) - self.endBooking(booking) - # Then check if booking has begun and the host is still idle - elif time.time() > booking[2] and booking[7] < 1: - self.log.info("starting the booking with id %i", booking[0]) - self.startBooking(booking) - - def startBooking(self, booking): - """ - Starts the scheduled booking on the requested host with - the correct config file. - The provisioning process gets spun up in a subproccess, - so the api listener is not interupted. - """ - try: - host = self.servers[booking[1]] - self.log.info("Detected a new booking started for host %s", host) - config_file = self.conf['default_configs']["None"] - try: - config_file = self.conf['default_configs'][booking[4]] - except KeyError: - self.log.warning( - "No installer detected in the booking request.") - self.log.info("New booking started for host %s", host) - self.database.setStatus(booking[0], 1) # mark booking started - if not os.path.isfile(self.deploy_path): - error = "Cannot find the deploment script at %s" - self.log.error(error, self.deploy_path) - subprocess.Popen([ - '/usr/bin/python', - self.deploy_path, - '--config', config_file, - '--host', host - ]) - except Exception: - self.log.exception("Failed to start booking for %s", host) - - def endBooking(self, booking): - """ - Resets a host once its booking has ended. - """ - try: - try: - config_file = self.conf['default_configs'][booking[4]] - except KeyError: - warn = "No installer detected in booking request" - self.log.warning("%s", warn) - config_file = self.conf['default_configs']["None"] - - host = self.servers[booking[1]] - log = logging.getLogger(host) - log.info('Lease expired. Resetting host %s', host) - self.database.setStatus(booking[0], 3) - if not os.path.isfile(self.deploy_path): - err = "Cannot find deployment script at %s" - self.log.error(err, self.deploy_path) - subprocess.Popen([ - '/usr/bin/python', - self.deploy_path, - '--config', config_file, - '--host', host, - '--reset' - ]) - self.database.removeBooking(booking[0]) - except Exception: - self.log.exception("Failed to end booking for %s", host) - - def createLogger(self, name): - return Utilities.createLogger(name, self.conf['logging_dir']) - - -if __name__ == "__main__": - if "--config" not in sys.argv: - print "Specify config file with --config option" - sys.exit(1) - config = None - try: - config_file = sys.argv[1+sys.argv.index('--config')] - config = yaml.safe_load(open(config_file)) - except Exception: - sys.exit(1) - api = Pharos_api(config) - api.listen() |