예제 #1
0
 def assign_services_to_workers(self, composition):
     """
         Assign the composition of services to the swarm workers
     :param composition: Service composition
     :return: bool
     """
     llogger = local_logger.LocalLogger()
     llogger.log_method_call(self.__class__.__name__,
                             sys._getframe().f_code.co_name)
     open_allocations = composition.get_open_allocations()
     llogger.debug("Open service allocations: %s", len(open_allocations))
     service_allocation_dict = self.allocate_services_to_workers(
         composition, open_allocations)
     if service_allocation_dict is not None:
         for worker, service_list in list(service_allocation_dict.items()):
             composition.assign_worker_to_services(service_list, worker)
             for service in service_list:
                 evaluation_logger.EvaluationLogger().write(
                     [service, worker.hostname],
                     evaluation_logger.LogType.ALLOCATIONS)
         llogger.debug(composition._allocation)
         return True
     else:
         llogger.debug(composition._allocation)
         return False
예제 #2
0
 def start_swarm_by_composition(self, composition, swarm_uuid):
     """
         Start swarm by parsed service composition
     :param composition: Object of service composition
     :param swarm_uuid: UUID of the swarm
     :raises SwarmException
     """
     llogger = local_logger.LocalLogger()
     llogger.log_method_call(self.__class__.__name__,
                             sys._getframe().f_code.co_name)
     start_timer = datetime.datetime.now()
     if self.swarm is None:
         raise SwarmException("Swarm not initialized")
     llogger.debug("Try to match swarm: %s with the following composition",
                   swarm_uuid)
     llogger.debug("\n" + composition.format_service_composition_as_table())
     result = self.assign_services_to_workers(composition)
     if result is True:
         llogger.debug("Worker matched. Try to start network")
         network = self.create_docker_network()
         llogger.debug(composition._allocation)
         self.start_services_on_workers(composition, network)
     total_time_of_run = datetime.datetime.now() - start_timer
     evaluation_logger.EvaluationLogger().write([
         "Total Time of Run", "*", "*",
         total_time_of_run.total_seconds(),
         self.swarm.get_worker_count(),
         len(composition.get_open_allocations())
     ], evaluation_logger.LogType.ALLOC_METRICS)
     llogger.debug("Time elapsed for Total Run: %f",
                   total_time_of_run.total_seconds())
 def calculate_costs(self, worker, service):
     """
         Implemented cost calculation method
     :param service: Related service object
     :param worker: Related worker object
     :return:
     """
     llogger = local_logger.LocalLogger()
     llogger.log_method_call(self.__class__.__name__,
                             sys._getframe().f_code.co_name)
     cpu_usage_of_worker, vram_usage_of_worker, swap_usage_of_worker, size_of_docker_image, bandwidth_in_percent = \
         self.get_usage_of_worker(worker, service)
     cpu_costs, vram_costs, swap_costs, image_download_costs = self.calculate_partial_costs(
         cpu_usage_of_worker, vram_usage_of_worker, swap_usage_of_worker,
         size_of_docker_image, bandwidth_in_percent)
     overall_costs = self.calculate_overall_costs(cpu_costs, vram_costs,
                                                  swap_costs,
                                                  image_download_costs)
     evaluation_logger.EvaluationLogger().write([
         service.id, worker.hostname, cpu_usage_of_worker,
         vram_usage_of_worker, swap_usage_of_worker, bandwidth_in_percent,
         cpu_costs * self.cpu_cost_weight, vram_costs *
         self.vram_cost_weight, swap_costs * self.swap_cost_weight,
         image_download_costs * self.image_download_cost_weight,
         overall_costs
     ], evaluation_logger.LogType.COSTS)
     return int(overall_costs)
예제 #4
0
 def reset_evaluation_logger(self):
     """
         Resets the time of the evaluation logger to let it use a new file
     :return:
     """
     llogger = local_logger.LocalLogger()
     llogger.log_method_call(self.__class__.__name__,
                             sys._getframe().f_code.co_name)
     evaluation_logger.EvaluationLogger().reset_time()
예제 #5
0
 def start_services_on_workers(self, composition, network):
     """
         Start the services on the allocated workers
     :param composition: Object of service composition
     :param network: docker network
     :raises SwarmException
     """
     llogger = local_logger.LocalLogger()
     llogger.log_method_call(self.__class__.__name__,
                             sys._getframe().f_code.co_name)
     start_timer = datetime.datetime.now()
     service_key_queue = deque(list(composition._allocation.keys()))
     started_services = []
     while len(service_key_queue) > 0:
         service_key = service_key_queue.popleft()
         worker_key = composition.get_worker_key(service_key)
         service = composition.get_service(service_key)
         if service.are_dependencies_started(started_services):
             worker = self.swarm.get_worker(worker_key)
             if worker is None:
                 llogger.debug("Error worker not found for worker key %s",
                               worker_key)
                 raise SwarmException("Worker not found for worker key " +
                                      worker_key)
             elif worker.start_service(jsonpickle.encode(service),
                                       network) is False:
                 llogger.debug("Error starting service %s on worker %s",
                               service.tag, worker.uuid)
                 raise SwarmException("Failed to start service " +
                                      service.tag + " on worker " +
                                      worker.uuid)
             started_services.append(service_key)
             llogger.debug("Started service " + service_key +
                           " on worker " + worker_key)
         else:
             service_key_queue.append(service_key)
     elapsed_time_until_service_start = datetime.datetime.now(
     ) - start_timer
     evaluation_logger.EvaluationLogger().write([
         "Time for starting containers", "*", "*",
         elapsed_time_until_service_start.total_seconds(),
         self.swarm.get_worker_count(),
         composition.get_service_count()
     ], evaluation_logger.LogType.ALLOC_METRICS)
     llogger.debug("Time elapsed for starting containers: %f",
                   elapsed_time_until_service_start.total_seconds())
예제 #6
0
 def allocate_services_to_workers(self, composition, allocations):
     llogger = local_logger.LocalLogger()
     llogger.log_method_call(self.__class__.__name__,
                             sys._getframe().f_code.co_name)
     from gortools import ortools_interface
     hardware_matrix, cost_matrix = self.get_cost_and_hardware_matrix(
         composition, allocations)
     start_timer = datetime.datetime.now()
     service_allocation_dict = ortools_interface.allocate_services_to_workers(
         services=allocations,
         workers=self.swarm._worker_list,
         hardware_matrix=hardware_matrix,
         cost_matrix=cost_matrix)
     time_of_allocation = datetime.datetime.now() - start_timer
     evaluation_logger.EvaluationLogger().write([
         "Time of allocation", "*", "*",
         time_of_allocation.total_seconds(),
         self.swarm.get_worker_count(),
         len(allocations)
     ], evaluation_logger.LogType.ALLOC_METRICS)
     return service_allocation_dict
예제 #7
0
 def configure_evaluation_logger(self,
                                 log_folder=None,
                                 log_ident=None,
                                 enable=True):
     """
         Configures the evaluation logger by setting its log_folder, log_ident, enabling or disabling it and
         resetting its time
     :param log_folder: None or log folder path
     :param log_ident: identification string
     :param enable: True when the evaluation logger should be enabled
     :return:
     """
     llogger = local_logger.LocalLogger()
     llogger.log_method_call(self.__class__.__name__,
                             sys._getframe().f_code.co_name)
     eval_logger = evaluation_logger.EvaluationLogger()
     if log_folder is not None:
         eval_logger.set_log_folder(log_folder)
     if log_ident is not None:
         eval_logger.set_log_ident(log_ident)
     self.reset_evaluation_logger()
     eval_logger.enable(enable)
예제 #8
0
 def get_cost_and_hardware_matrix(self, composition, allocations):
     llogger = local_logger.LocalLogger()
     llogger.log_method_call(self.__class__.__name__,
                             sys._getframe().f_code.co_name)
     hardware_matrix = []
     cost_matrix = []
     start_timer = datetime.datetime.now()
     for service_key in allocations:
         service = composition.get_service(service_key)
         hardware_row_for_service, cost_row_for_service = self.get_cost_and_hardware_row_for_service(
             service)
         hardware_matrix.append(hardware_row_for_service)
         cost_matrix.append(cost_row_for_service)
     time_of_calculation = datetime.datetime.now() - start_timer
     evaluation_logger.EvaluationLogger().write([
         "Time of cost calculation", "*", "*",
         time_of_calculation.total_seconds(),
         self.swarm.get_worker_count(),
         len(allocations)
     ], evaluation_logger.LogType.ALLOC_METRICS)
     llogger.debug("Time elapsed for cost calculation: %f",
                   time_of_calculation.total_seconds())
     return hardware_matrix, cost_matrix