Example #1
0
    def update_application(self):
        if self.run_plan:

            current_backends = [bc.backend for bc in self.run_plan.backends]
            scheduler = Scheduler()
            new_backends = scheduler.find_backends(self.run_plan)
            if not new_backends:
                log.error(_("Can't update '{name}', no backend "
                            "available").format(name=self.name))
                return

            updated_backends = []
            for backend_conf in new_backends:
                if backend_conf.backend in current_backends:
                    # replace backend settings with updated version
                    self.run_plan.update(
                        pull__backends__backend=backend_conf.backend)
                    self.run_plan.update(push__backends=backend_conf)
                    updated_backends.append(backend_conf.backend)
                else:
                    # add backend to run plan if not already there
                    ApplicationRunPlan.objects(
                        id=self.run_plan.id,
                        backends__backend__nin=[
                            backend_conf.backend]).update_one(
                        push__backends=backend_conf)
                    log.info(_("Starting {name} on backend {backend}").format(
                        name=self.name, backend=backend_conf.backend.name))
                    ApplicationFlag.objects(
                        pending_backends__ne=backend_conf.backend,
                        application=self,
                        name=IsStartingFlag.name).update_one(
                            add_to_set__pending_backends=backend_conf.backend,
                            upsert=True)

            if updated_backends:
                ApplicationFlag.objects(
                    application=self, name=NeedsRestartFlag.name).update_one(
                        set__pending_backends=updated_backends, upsert=True)

            for backend in current_backends:
                if backend not in [bc.backend for bc in new_backends]:
                    log.info(_("Stopping {name} on old backend "
                               "{backend}").format(name=self.name,
                                                   backend=backend.name))
                    ApplicationFlag.objects(
                        pending_backends__ne=backend,
                        application=self,
                        name=NeedsStoppingFlag.name).update_one(
                            add_to_set__pending_backends=backend, upsert=True)
Example #2
0
 def handle_task(self):
     task_handled = super(Command, self).handle_task()
     if task_handled:
         return task_handled
     if self.last_app_check and self.last_app_check >= (
             datetime.now() - timedelta(seconds=60)):
         return False
     self.last_app_check = datetime.now()
     for app in ApplicationRunPlan.objects(
             backends__backend=self.backend).distinct('application'):
         if app.flags:
             continue
         if not self.is_application_running(app):
             log.info(_("Application {name} is not running, "
                        "starting").format(name=app.name))
             ApplicationFlag.objects(
                 application=app, name=IsStartingFlag.name).update_one(
                     add_to_set__pending_backends=self.backend, upsert=True)
         elif not self.is_vassal_config_valid(app):
             log.info(_("Application {name} vassal config is invalid, "
                        "restarting").format(name=app.name))
             ApplicationFlag.objects(
                 application=app, name=NeedsRestartFlag.name).update_one(
                     add_to_set__pending_backends=self.backend, upsert=True)
         else:
             run_plan = app.run_plan
             if run_plan and not run_plan.is_valid():
                 log.info(_("Application {name} run plan is invalid, "
                            "rescheduling").format(name=app.name))
                 ApplicationFlag.objects(
                     application=app,
                     name=NeedsReschedulingFlag.name).update_one(
                         unset__pending=True, upsert=True)
Example #3
0
 def limits_usage(self):
     ret = {'running_apps': 0, 'workers': 0}
     for arp in ApplicationRunPlan.objects(
             application__in=Application.objects(owner=self)):
         ret['running_apps'] += 1
         ret['workers'] += arp.workers_max
     return ret
    def test_run_plan_migration(self):

        backend_settings = BackendRunPlanSettings(backend=self.backend,
                                                  package=self.pkg,
                                                  socket=8080, stats=9090,
                                                  workers_min=1, workers_max=4)

        run_plan = ApplicationRunPlan(application=self.app,
                                      backends=[backend_settings],
                                      workers_min=1, workers_max=4,
                                      memory_per_worker=128, max_log_size=1)
        run_plan.save()

        self.app.reload()
        self.assertEqual(self.app.run_plan, None)
        self.assertEqual(call_command('migrate_db'), None)
        self.app.reload()
        self.assertEqual(self.app.run_plan, run_plan)

        run_plan.delete()
Example #5
0
def create_run_plan_pkg_list(request):
    create_app(request)
    create_pkg_list(request)
    create_backend(request)
    create_router(request)

    backend_settings = BackendRunPlanSettings(
        backend=request.instance.backend, package=request.instance.pkg_list[0],
        socket=8080, stats=9090, workers_min=1, workers_max=4)

    run_plan = ApplicationRunPlan(application=request.instance.app,
                                  backends=[backend_settings],
                                  workers_min=1, workers_max=4,
                                  memory_per_worker=128, max_log_size=1)
    run_plan.save()
    request.instance.app.update(set__run_plan=run_plan)
    request.instance.app.reload()

    def cleanup():
        run_plan.delete()
    request.addfinalizer(cleanup)

    request.instance.run_plan = run_plan
Example #6
0
    def clean(self):
        workers_min = self.cleaned_data.get('workers_min')
        workers_max = self.cleaned_data.get('workers_max')

        if not self.instance.id:
            apps_running = self.user.limits_usage['running_apps']
            apps_limit = self.user.limits['running_apps']
            if apps_limit and apps_running >= apps_limit:
                raise forms.ValidationError(
                    _("Already running maximum allowed applications "
                      "({count}), can't start another one").format(
                        count=apps_running))

        if workers_min is None or workers_max is None:
            return self.cleaned_data

        if workers_min > workers_max:
            raise forms.ValidationError(_("Minimum workers number cannot be"
                                          "lower than maximum"))

        workers_used = self.user.limits_usage['workers']
        if self.instance.id:
            run_plan = ApplicationRunPlan.objects(id=self.instance.id).first()
            workers_used -= run_plan.workers_max
        workers_limit = self.user.limits['workers']
        if workers_limit:
            workers_available = max(workers_limit - workers_used, 0)
            if workers_min > workers_available:
                raise forms.ValidationError(_(
                    "Only {available} workers available, cannot set "
                    "{workers} as minimum ").format(
                    available=workers_available, workers=workers_min))
            if workers_max > workers_available:
                raise forms.ValidationError(_(
                    "Only {available} workers available, cannot set "
                    "{workers} as maximum ").format(
                    available=workers_available, workers=workers_max))

        return self.cleaned_data
Example #7
0
 def run_plans(self):
     """
     Returns the list of application run plans scheduled to be running on
     this backend.
     """
     return ApplicationRunPlan.objects(backends__backend=self)
Example #8
0
 def running_applications(self):
     return [arp.application for arp in ApplicationRunPlan.objects(
         application__in=Application.objects(owner=self))]
Example #9
0
 def migrate_run_plans(self):
     for run_plan in ApplicationRunPlan.objects():
         if not run_plan.application.run_plan:
             log.info("Migrating run plan for %s" % run_plan.application.name)
             run_plan.application.update(set__run_plan=run_plan)