예제 #1
0
async def module_info(request):
    module = request.match_info["module"].lower()

    if not await request.app.cache.modules.exists(module):
        flash.flash(request, ("danger", f"Module does not exist: {module}."))
        return web.HTTPFound("/modules")

    module_meta = await request.app.cache.modules.get(module)

    request.context["modulename"] = module
    request.context["module_meta"] = copy.deepcopy(module_meta)
    description = module_meta.get("description")
    if description:
        description = "\n".join(description)
    else:
        description = "No description provided."

    description = markdown.markdown(description)
    request.context["module_meta"]["description"] = description

    request.context["breadcrumbs"] = [
        ("Home", False, "/"),
        ("Modules", False, "/modules"),  # FIXME(aloga): use url
        (module, True, f"/modules/{module}"),  # FIXME(aloga): use url
    ]

    return request.context
예제 #2
0
async def get_deployment_template(request):
    request.context["deployments"] = []

    uuid = request.match_info['uuid']

    request.context["breadcrumbs"] = [
        ("Home", False, "/"),
        ("Deployments", False, "/deployments"),  # FIXME(aloga): use url
        (uuid, False, f"/deployments/{uuid}"),  # FIXME(aloga): use url
        ("template", True, f"/deployments/{uuid}/template"),  # FIXME(aloga)
    ]

    cli = await orchestrator.get_client(CONF.orchestrator.url, request)

    try:
        template = cli.deployments.get_template(uuid).template
        request.context["template"] = template
    except orpy.exceptions.ClientException as e:
        flash.flash(
            request,
            ("danger", f"Error retrieving deployment {uuid} template: "
             f"{e.message}"),
        )
        return web.HTTPFound("/deployments")
    else:
        return request.context
예제 #3
0
async def create_module_training(request):
    form_data = await request.post()
    LOG.debug(f"Received form data: {form_data}")

    tosca_template = form_data.get('template')
    LOG.debug(f"Selected template file: {tosca_template}")

    if not await request.app.cache.tosca_templates.exists(tosca_template):
        flash.flash(
            request,
            ("danger", f"TOSCA template does not exist: {tosca_template}."))
        return web.HTTPFound("/modules")

    aux = await request.app.cache.tosca_templates.get(tosca_template)
    template = aux["original tosca"]

    params = {}
    if 'extra_opts.keepLastAttempt' in form_data:
        params["keepLastAttempt"] = "true"
    else:
        params["keepLastAttempt"] = "false"

    if form_data['extra_opts.schedtype'] == "manual":
        if sla := form_data.get('extra_opts.selectedSLA', None):
            LOG.debug(f"Adding SLA to deployment request {sla}")
            template['topology_template']['policies'] = [{
                "deploy_on_specific_site": {
                    "type": "tosca.policies.indigo.SlaPlacement",
                    "properties": {
                        "sla_id": sla
                    }
                }
            }]
        else:
            flash.flash(request, ("danger", "SLA does not exist."))
예제 #4
0
async def delete_deployment(request):
    uuid = request.match_info['uuid']

    cli = await orchestrator.get_client(CONF.orchestrator.url, request)

    try:
        cli.deployments.delete(uuid)
    except orpy.exceptions.ClientException as e:
        flash.flash(
            request,
            ("danger", f"Error deleting deployment {uuid}: {e.message}"))
    finally:
        return web.HTTPFound("/deployments")
예제 #5
0
async def error_middleware(request, handler):
    try:
        response = await handler(request)
        if response.status != 404:
            return response
        message = response.message
    except web.HTTPServerError as e:
        LOG.exception(e)
        message = "Internal server error. "
    except web.HTTPException as e:
        message = f"Error {e.status_code}: {e.reason}"
    aiohttp_session_flash.flash(request, ("danger", message))
    response = web.HTTPFound("/")
    return response
예제 #6
0
 async def middleware_handler(request):
     try:
         response = await handler(request)
         if response.status in [400, 403, 404, 405]:
             if response.status == 400:
                 message = "Bad request"
             elif response.status == 403:
                 message = "Forbidden"
             elif response.status == 404:
                 message = "Not found"
             else:
                 message = "Method not allowed"
             flash(request, ("danger", message))
             return render_template("error.html", request, {})
         return response
     except web.HTTPException as e:
         flash(request, ("danger", str(e)))
         return render_template("error.html", request, {})
예제 #7
0
async def get_deployments(request):
    request.context["deployments"] = []

    cli = await orchestrator.get_client(CONF.orchestrator.url, request)

    request.context["breadcrumbs"] = [
        ("Home", False, "/"),
        ("Deployments", True, "/deployments"),  # FIXME(aloga): use url
    ]

    try:
        request.context["deployments"] = cli.deployments.list()
    except orpy.exceptions.ClientException as e:
        flash.flash(
            request,
            ("danger", f"Error retrieving deployment list: {e.message}"),
        )
    finally:
        return request.context
예제 #8
0
async def show_deployment_history(request):
    uuid = request.match_info['uuid']

    request.context["breadcrumbs"] = [
        ("Home", False, "/"),
        ("Deployments", False, "/deployments"),  # FIXME(aloga): use url
        (uuid, False, f"/deployments/{uuid}"),  # FIXME(aloga): use url
        ("history", True, f"/deployments/{uuid}/history"),  # FIXME(aloga)
    ]

    cli = await orchestrator.get_client(CONF.orchestrator.url, request)

    try:
        deployment = cli.deployments.show(uuid)
    except orpy.exceptions.ClientException as e:
        flash.flash(
            request,
            ("danger", f'Error getting deployment {uuid}: {e.message}'))
        return web.HTTPFound("/deployments")

    # Check if deployment is still in 'create_in_progress'
    if 'deepaas_endpoint' not in deployment.outputs:
        flash.flash(request,
                    ("warning",
                     'Wait until creation is completed before you access the '
                     'training history.'))
        return web.HTTPFound("/deployments")

    session = aiohttp.ClientSession()

    # Check if deployment has DEEPaaS V2
    deepaas_url = deployment.outputs['deepaas_endpoint']
    try:
        async with session.get(deepaas_url, raise_for_status=True) as r:
            data = await r.json()
        versions = data['versions']
        if 'v2' not in [v['id'] for v in versions]:
            raise Exception
    except Exception:
        flash.flash(request,
                    ("warning",
                     "You need to be running DEEPaaS V2 inside the deployment "
                     "to be able to access the training history."))
        return web.HTTPFound("/deployments")

    # Get info
    async with session.get(deepaas_url + '/v2/models',
                           raise_for_status=False) as r:
        r = await r.json()

    training_info = {}
    for model in r['models']:
        async with session.get(f'{deepaas_url}/v2/models/{model["id"]}/train/',
                               raise_for_status=False) as r:
            training_info[model['id']] = await r.json()

    request.context["deployment"] = deployment
    request.context["training_info"] = training_info
    return request.context
예제 #9
0
async def delete_training(request):
    dep_uuid = request.match_info["uuid"]
    model = request.match_info["model"]
    training_uuid = request.match_info["training_uuid"]

    cli = await orchestrator.get_client(CONF.orchestrator.url, request)

    try:
        deployment = cli.deployments.show(dep_uuid)
    except orpy.exceptions.ClientException as e:
        flash.flash(
            request,
            ("danger", f'Error getting deployment {dep_uuid}: {e.message}'))
        return web.HTTPFound("/deployments")

    # Check if deployment is still in 'create_in_progress'
    if 'deepaas_endpoint' not in deployment.outputs:
        flash.flash(request,
                    ("warning",
                     'Wait until creation is completed before you access the '
                     'training history.'))
        return web.HTTPFound(f"/deployments/{dep_uuid}/history")

    # Check if deployment has DEEPaaS V2
    deepaas_url = deployment.outputs['deepaas_endpoint']
    training_url = f"{deepaas_url}/v2/models/{model}/train/{training_uuid}"

    session = aiohttp.ClientSession()

    try:
        async with session.delete(training_url, raise_for_status=True) as r:
            if r.status not in [200, 201]:
                raise Exception
    except Exception as e:
        flash.flash(
            request,
            ("warning", f"Could not delete training!! (reason: {e.message})"))
    finally:
        return web.HTTPFound(f"/deployments/{dep_uuid}/history")
예제 #10
0
async def configure_module_training(request):
    module = request.match_info["module"].lower()

    if not await request.app.cache.modules.exists(module):
        flash.flash(request, ("danger", f"Module does not exist: {module}."))
        return web.HTTPFound("/modules")

    request.context["selected_module"] = module
    module_meta = await request.app.cache.modules.get(module)

    selected_tosca = request.query.get(
        "selected_tosca",
        list(module_meta["tosca_templates"].keys())[0])
    template_name = module_meta["tosca_templates"][selected_tosca]
    hardware_configuration = request.query.get("hardware_configuration",
                                               "CPU").lower()
    docker_tag = request.query.get("docker_tag",
                                   module_meta["docker_tags"][0]).lower()
    run_command = request.query.get("run_command", "DEEPaaS")

    general_configuration = {
        "tosca_templates": {
            "available": module_meta["tosca_templates"].keys(),
            "selected": selected_tosca,
        },
        "docker_tags": {
            "available": module_meta["docker_tags"],
            "selected": docker_tag,
        },
        "hardware_configuration": {
            "available": ["CPU", "GPU"],
            "selected": hardware_configuration,
        },
        "run_command": {
            "available": ["DEEPaaS", "JupyterLab", "Custom command"],
            "selected": run_command,
        },
    }

    tosca_template = module_meta["tosca_templates"].get(selected_tosca)
    if tosca_template is None:
        flash.flash(
            request,
            ("danger", f"TOSCA template does not exist: {tosca_template}."))
        return web.HTTPFound("/modules")

    aux = await request.app.cache.tosca_templates.get(tosca_template)
    inputs = copy.deepcopy(aux["inputs"])
    inputs['docker_image'].setdefault(
        'default', module_meta['sources']['docker_registry_repo'])

    docker_tags = module_meta['docker_tags']
    if docker_tag not in docker_tags:
        docker_tag = docker_tags[0]

    if run_command == 'deepaas':
        inputs['run_command']['default'] = 'deepaas-run --listen-ip=0.0.0.0'
        if hardware_configuration == 'gpu':
            inputs['run_command']['default'] += ' --listen-port=$PORT0'
    elif run_command == 'jupyterlab':
        flash.flash(request,
                    ("warning", 'Remember to set a Jupyter password.'))
        inputs['run_command']['default'] = (
            '/srv/.jupyter/run_jupyter.sh --allow-root')
        if hardware_configuration == 'gpu':
            inputs['run_command']['default'] = (
                "jupyterPORT=$PORT2 " + inputs['run_command']['default'])

    if hardware_configuration == 'cpu':
        inputs['num_cpus']['default'] = 1
        inputs['num_gpus']['default'] = 0
        inputs['run_command']['default'] = ("monitorPORT=6006 " +
                                            inputs['run_command']['default'])
    elif hardware_configuration == 'gpu':
        inputs['num_cpus']['default'] = 1
        inputs['num_gpus']['default'] = 1
        inputs['run_command']['default'] = ("monitorPORT=$PORT1 " +
                                            inputs['run_command']['default'])

    # FIXME(aloga): improve conditions here
    if run_command == "custom command":
        inputs['run_command']['default'] = ''

    inputs['docker_image']['default'] += ':{}'.format(docker_tag)

    grouped = {
        "docker": {},
        "jupyter": {},
        "storage": {},
        "hardware": {},
        "other": {},
    }

    for k, v in inputs.items():
        if k.startswith("docker_"):
            grouped["docker"][k] = v
        elif k.startswith("jupyter_"):
            grouped["jupyter"][k] = v
        elif any([
                k.startswith("rclone_"),
                k.startswith("onedata_"),
                k.startswith("oneclient_"), k == "app_in_out_base_dir"
        ]):
            grouped["storage"][k] = v
        elif k in ["mem_size", "num_cpus", "num_gpus"]:
            grouped["hardware"][k] = v
        else:
            grouped["other"][k] = v

    template_meta = {
        "inputs": inputs,
        "grouped": grouped,
    }

    request.context["general_configuration"] = general_configuration
    request.context["template_meta"] = template_meta
    request.context["template_name"] = template_name
    request.context["slas"] = request.app.slas
    request.context["module_meta"] = module_meta
    request.context["breadcrumbs"] = [
        ("Home", False, "/"),
        ("Modules", False, "/modules"),  # FIXME(aloga): use url
        (module, False, f"/modules/{module}"),  # FIXME(aloga): use url
        ("train", True, f"/modules/{module}/train"),  # FIXME(aloga): use url
    ]

    return request.context
		async def save_array(request):
			flash(request, ["This", "works", "too"])
			return web.Response(body=b'OK')
		async def save_redirect(request):
			flash(request, "Redirect")
			raise web.HTTPFound('/')
		async def save(request):
			flash(request, "Hello")
			return web.Response(body=b'OK')
예제 #14
0
    async def post(self):
        form = self.RecordingForm(await self.request.post())
        form.adapter.choices = self.adapters_choices
        form.channel.choices = self.channels_choices
        if form.data["submit"]:
            if form.validate():
                data = remove_special_data(form.data)

                error = False
                begin_date = data["begin_date"]
                if begin_date is None:
                    immediate = True
                    begin_date = datetime.now()
                else:
                    immediate = False
                    if begin_date <= datetime.now():
                        error = True
                        message = _(
                            "La date de début doit être dans le futur.")
                end_date = data["end_date"]
                if begin_date >= end_date:
                    error = True
                    message = _(
                        "La date de début doit être antérieure à la date de fin."
                    )
                duration = (end_date - begin_date).total_seconds()
                if duration > int(self.recorder.max_duration):
                    error = True
                    message = _(
                        "La durée de l'enregistrement est trop longue.")
                if error:
                    flash(self.request, ("danger", message))
                else:
                    adapter = data["adapter"]
                    shutdown = data["shutdown"]
                    channel = self.channels_choices[data["channel"]][1]
                    program_name = data["program_name"]
                    self.recorder.record(adapter, channel, program_name,
                                         immediate, begin_date, end_date,
                                         duration, shutdown)
                    message = _("L'enregistrement de \"{}\" est programmé "
                                "pour le {} à {} pendant {} minutes de \"{}\" "
                                "sur l'enregistreur {}").format(
                                    program_name,
                                    begin_date.strftime("%d/%m/%Y"),
                                    begin_date.strftime("%H:%M"),
                                    round(duration / 60), channel, adapter)
                    flash(self.request, ("info", message))
                    return web.HTTPFound(
                        self.request.app.router["index"].url_for())
            else:
                flash(self.request,
                      ("danger", _("Le formulaire contient des erreurs.")))

        form2 = self.AwakeningForm(await self.request.post())
        if form2.data["submit2"]:
            if form2.validate():
                data = remove_special_data(form2.data)
                awakening_date = data["awakening_date"]
                self.wakeup.add_awakening(awakening_date)
                return web.HTTPFound(
                    self.request.app.router["index"].url_for())
            else:
                flash(self.request,
                      ("danger", _("Le formulaire contient des erreurs.")))

        form3 = self.ToolsForm(await self.request.post())
        if form3.data["submit3"]:
            if form3.validate():
                data = remove_special_data(form3.data)
                if data["shutdown"]:
                    halt()
            else:
                flash(self.request,
                      ("danger", _("Le formulaire contient des erreurs.")))

        return {
            "form": form,
            "recordings": self.recorder.get_recordings(),
            "form2": form2,
            "awakenings": self.wakeup.get_awakenings(),
            "form3": form3
        }