Esempio n. 1
0
    def __check_expr_status(self, user, hackathon, template):
        """
        check experiment status, if there are pre-allocate experiments, the experiment will be assigned directly
        :param user:
        :param hackathon:
        :param template:
        :return:
        """
        criterion = Q(status__in=[ExprStatus.RUNNING, ExprStatus.STARTING], hackathon=hackathon, user=user)
        is_admin = self.admin_manager.is_hackathon_admin(hackathon.id, user.id)
        if is_admin:
            criterion &= Q(template=template)

        expr = Experiment.objects(criterion).first()
        if expr:
            # user has a running/starting experiment
            return expr

        # try to assign pre-configured expr to user
        expr = Experiment.objects(status=ExprStatus.RUNNING, hackathon=hackathon, template=template, user=None).first()
        if expr:
            expr.user = user
            expr.save()
            return expr
Esempio n. 2
0
 def stop_expr(self, expr_id):
     """
     :param expr_id: experiment id
     :return:
     """
     self.log.debug("begin to stop %s" % str(expr_id))
     expr = Experiment.objects(id=expr_id).first()
     if expr is not None:
         starter = self.get_starter(expr.hackathon, expr.template)
         if starter:
             starter.stop_expr(Context(experiment_id=expr.id, experiment=expr))
         self.log.debug("experiment %s ended success" % expr_id)
         return ok('OK')
     else:
         return ok()
Esempio n. 3
0
    def _internal_stop_expr(self, context):
        expr = Experiment.objects(id=context.experiment_id).first()
        if not expr:
            return

        if len(expr.virtual_environments) == 0:
            expr.status = ExprStatus.ROLL_BACKED
            expr.save()
            return

        # delete containers and change expr status
        for ve in expr.virtual_environments:
            context = context.copy()  # create new context for every virtual_environment
            context.virtual_environment_name = ve.name
            self._stop_virtual_environment(ve, expr, context)
Esempio n. 4
0
    def roll_back(self, expr_id):
        """
        roll back when exception occurred
        :param expr_id: experiment id
        """
        self.log.debug("Starting rollback experiment %s..." % expr_id)
        expr = Experiment.objects(id=expr_id)
        if not expr:
            self.log.warn("rollback failed due to experiment not found")
            return

        starter = self.get_starter(expr.hackathon, expr.template)
        if not starter:
            self.log.warn("rollback failed due to no starter found")
            return

        return starter.rollback(Context(experiment=expr))
Esempio n. 5
0
    def delete_template(self, template_id):
        self.log.debug("delete template [%s]" % template_id)
        try:
            template = self.get_template_info_by_id(template_id)
            if template is None:
                return ok("already removed")
            # user can only delete the template which created by himself except super admin
            if g.user.id != template.creator.id and not g.user.is_super:
                return forbidden()
            if Experiment.objects(template=template).count() > 0:
                return forbidden("template already in use")

            # remove record in DB
            # the Hackathon used this template will imply the mongoengine's PULL reverse_delete_rule
            self.log.debug("delete template {}".format(template.name))
            template.delete()

            return ok("delete template success")
        except Exception as ex:
            self.log.error(ex)
            return internal_server_error("delete template failed")
Esempio n. 6
0
    def scheduler_recycle_expr(self):
        """recycle experiment according to hackathon basic info on recycle configuration

        According to the hackathon's basic info on 'recycle_enabled', find out time out experiments
        Then call function to recycle them

        :return:
        """
        self.log.debug("start checking recyclable experiment ... ")
        for hackathon in self.hackathon_manager.get_recyclable_hackathon_list():
            try:
                # check recycle enabled
                mins = self.hackathon_manager.get_recycle_minutes(hackathon)
                # filter out the experiments that need to be recycled
                exprs = Experiment.objects(create_time__lt=self.util.get_now() - timedelta(minutes=mins),
                                           status=ExprStatus.RUNNING,
                                           hackathon=hackathon)
                for expr in exprs:
                    self.__recycle_expr(expr)
            except Exception as e:
                self.log.error(e)
Esempio n. 7
0
    def _enable_guacd_file_transfer(self, context):
        """
        This function should be invoked after container is started in hosted_docker.py
        :param ve: virtual environment
        """
        expr = Experiment.objects(id=context.experiment_id).no_dereference().first()
        virtual_env = expr.virtual_environments.get(name=context.virtual_environment_name)
        remote = virtual_env.remote_paras

        p = pexpect.spawn("scp -P %s %s %s@%s:/usr/local/sbin/guacctl" %
                          (remote["port"],
                           abspath("%s/../expr/guacctl" % dirname(realpath(__file__))),
                           remote["username"],
                           remote["hostname"]))
        i = p.expect([pexpect.TIMEOUT, 'yes/no', 'password: '******'password:'])

        if i != 0:
            p.sendline(remote["password"])
            p.expect(pexpect.EOF)
        p.close()
Esempio n. 8
0
    def __start_virtual_environment(self, context, docker_template_unit):
        origin_name = docker_template_unit.get_name()
        prefix = str(context.experiment_id)[0:9]
        suffix = "".join(random.sample(string.ascii_letters + string.digits, 8))
        new_name = '%s-%s-%s' % (prefix, origin_name, suffix.lower())
        docker_template_unit.set_name(new_name)
        self.log.debug("starting to start container: %s" % new_name)

        # db document for VirtualEnvironment
        ve = VirtualEnvironment(provider=VirtualEnvProvider.DOCKER,
                                name=new_name,
                                image=docker_template_unit.get_image_with_tag(),
                                status=ExprEnvStatus.INIT,
                                remote_provider=VERemoteProvider.Guacamole)
        # create a new context for current ve only
        context = context.copy()
        experiment = Experiment.objects(id=context.experiment_id).no_dereference().only("virtual_environments").first()
        experiment.virtual_environments.append(ve)
        experiment.save()

        # start container remotely , use hosted docker
        context.virtual_environment_name = ve.name
        context.unit = docker_template_unit
        self._internal_start_virtual_environment(context)
Esempio n. 9
0
 def get_expr_status_and_confirm_starting(self, expr_id):
     expr = Experiment.objects(id=expr_id).first()
     if expr:
         return self.__report_expr_status(expr, isToConfirmExprStarting=True)
     else:
         return not_found('Experiment Not found')