← Back to team overview

canonical-ubuntu-qa team mailing list archive

Re: [Merge] ~andersson123/autopkgtest-cloud:stop-tests-from-webpage into autopkgtest-cloud:master

 


Diff comments:

> diff --git a/charms/focal/autopkgtest-web/reactive/autopkgtest_web.py b/charms/focal/autopkgtest-web/reactive/autopkgtest_web.py
> index 994a91a..8d3897e 100644
> --- a/charms/focal/autopkgtest-web/reactive/autopkgtest_web.py
> +++ b/charms/focal/autopkgtest-web/reactive/autopkgtest_web.py
> @@ -256,6 +257,7 @@ def set_up_web_config(apache):
>  
>                  # webcontrol CGI scripts
>                  ScriptAlias /request.cgi {webcontrol_dir}/request.cgi/
> +                ScriptAlias /test-manager.cgi {webcontrol_dir}/test-manager.cgi/

remove dis

>                  ScriptAlias /login {webcontrol_dir}/request.cgi/login
>                  ScriptAlias /logout {webcontrol_dir}/request.cgi/logout
>                  ScriptAlias /private-results {webcontrol_dir}/private-results.cgi/
> diff --git a/charms/focal/autopkgtest-web/webcontrol/browse.cgi b/charms/focal/autopkgtest-web/webcontrol/browse.cgi
> index 309fb82..eab81ea 100755
> --- a/charms/focal/autopkgtest-web/webcontrol/browse.cgi
> +++ b/charms/focal/autopkgtest-web/webcontrol/browse.cgi
> @@ -85,6 +84,7 @@ def get_running_jobs():
>  
>  def render(template, code=200, **kwargs):
>      # sort the values passed in, so that releases are in the right order
> +    flask.config["KILL-TEST-RESPONSE"] = ""

remove

>      try:
>          release_arches = OrderedDict()
>          for k in sorted(
> @@ -326,6 +369,7 @@ def package_overview(package, _=None):
>                  }
>              }
>          }
> +    show_stop = flask.session.get("nickname", "") in get_admin_nicks()

move show stop to flask.config option so it doesn't need to be passed explicitly

>  
>      return render(
>          "browse-package.html",
> diff --git a/charms/focal/autopkgtest-web/webcontrol/templates/browse-results.html b/charms/focal/autopkgtest-web/webcontrol/templates/browse-results.html
> index fadff6d..57af00f 100644
> --- a/charms/focal/autopkgtest-web/webcontrol/templates/browse-results.html
> +++ b/charms/focal/autopkgtest-web/webcontrol/templates/browse-results.html
> @@ -58,6 +58,11 @@
>            {% endif %}
>          {% endif %}
>        </td>
> +      <td class="nowrap">
> +        {% if show_stop and row[6] == "running" and row[10] not in ["-", ""] %}
> +          <a href="{{ base_url }}test-manager.cgi?uuid={{ row[10] }}">&#x2620;</a> <!-- Displays skull and crossbones-->

replace this with a url_for call

> +        {% endif %}
> +      </td>
>      </tr>
>    {% endfor %}
>    </table>
> diff --git a/charms/focal/autopkgtest-web/webcontrol/templates/macros.html b/charms/focal/autopkgtest-web/webcontrol/templates/macros.html
> index 941dc77..f75ebcb 100644
> --- a/charms/focal/autopkgtest-web/webcontrol/templates/macros.html
> +++ b/charms/focal/autopkgtest-web/webcontrol/templates/macros.html
> @@ -15,6 +15,11 @@
>                {% endif %}
>            {% endfor %}
>            <tr><th>Running for:</th><td>{{ duration//3600 }}h {{ duration % 3600//60 }}m {{ duration % 60 }}s ({{ duration }}s)</td></tr>
> +          {% if show_stop %}
> +            {% if "uuid" in params.keys() %}
> +              <tr><td><a href="{{ base_url }}test-manager.cgi?uuid={{ params.get("uuid") }}">Stop this test</a></td></tr>

replace with url_for call, add skull and crossbones also

> +            {% endif %}
> +          {% endif %}
>         </table>
>        <pre>
>  {{ logtail }}
> diff --git a/charms/focal/autopkgtest-web/webcontrol/test-manager.cgi b/charms/focal/autopkgtest-web/webcontrol/test-manager.cgi
> new file mode 100755
> index 0000000..9df3db3
> --- /dev/null
> +++ b/charms/focal/autopkgtest-web/webcontrol/test-manager.cgi

remove this file

> @@ -0,0 +1,11 @@
> +#!/usr/bin/env python3
> +
> +"""Run test-manager app as CGI script """
> +
> +from wsgiref.handlers import CGIHandler
> +
> +from test_manager.app import app
> +
> +if __name__ == "__main__":
> +    app.config["DEBUG"] = True
> +    CGIHandler().run(app)
> diff --git a/charms/focal/autopkgtest-web/webcontrol/test_manager/app.py b/charms/focal/autopkgtest-web/webcontrol/test_manager/app.py
> new file mode 100644
> index 0000000..8a62aae
> --- /dev/null
> +++ b/charms/focal/autopkgtest-web/webcontrol/test_manager/app.py

remove this file also

> @@ -0,0 +1,135 @@
> +"""
> +test-manager is an app for autopkgtest-web which sends kill requests to
> +the worker units, detailing the test uuid.
> +
> +The worker units then kill the test with the matching uuid.
> +
> +On the running page, admins will have a hyperlink under running jobs which, when clicked,
> +will send the kill request.
> +
> +Before sending the kill request, test_manager checks that the uuid is indeed in running.json
> +
> +After sending the kill request, the request is picked up by a systemd unit named "test-killer"
> +on the cloud worker units.
> +
> +This unit, through all the cloud worker units, will find which unit the test is running on,
> +and kill the test, removing the test request from the queue and making the worker unit move
> +on to the next test in the queue.
> +"""
> +
> +
> +import configparser
> +import json
> +import logging
> +import os
> +import pathlib
> +import urllib
> +
> +import amqplib.client_0_8 as amqp
> +from flask import request, session
> +from helpers.exceptions import RunningJSONNotFound
> +from helpers.utils import (
> +    HTML,
> +    get_admin_nicks,
> +    get_all_releases,
> +    initialise_app,
> +    maybe_escape,
> +)
> +
> +ALL_UBUNTU_RELEASES = get_all_releases()
> +
> +RUNNING_FP = "/run/amqp-status-collector/running.json"
> +RUNNING_FILE = pathlib.Path("/run/amqp-status-collector/running.json")
> +WRITER_EXCHANGE_NAME = "stop-running.fanout"
> +
> +
> +def submit_to_queue(message: dict):
> +    """
> +    Submits a dictionary as an amqp message to the WRITER_EXCHANGE_NAME exchange
> +
> +    :param message: Dictionary to be converted to an amqp.Message and placed into the queue
> +    """
> +    amqp_con = amqp_connect()
> +    complete_amqp = amqp_con.channel()
> +    complete_amqp.access_request(
> +        "/complete", active=True, read=False, write=True
> +    )
> +    complete_amqp.exchange_declare(
> +        WRITER_EXCHANGE_NAME, "fanout", durable=True, auto_delete=False
> +    )
> +    complete_amqp.basic_publish(
> +        amqp.Message(json.dumps(message), delivery_mode=2),
> +        WRITER_EXCHANGE_NAME,
> +        "",
> +    )
> +
> +
> +# THIS CAN BE REFACTORED AFTER THE AUTO-QUEUE-CLEANUP MP IS MERGED!!!
> +# AMQP_CONNECT IS NOW SHARED FUNCTION IN HELPERS/UTILS.PY
> +def amqp_connect() -> amqp.Connection:
> +    """Connect to AMQP server"""
> +    cp = configparser.ConfigParser()
> +    cp.read(os.path.expanduser("~ubuntu/autopkgtest-cloud.conf"))
> +    amqp_uri = cp["amqp"]["uri"]
> +    parts = urllib.parse.urlsplit(amqp_uri, allow_fragments=False)
> +    amqp_con = amqp.Connection(
> +        parts.hostname, userid=parts.username, password=parts.password
> +    )
> +    logging.info(
> +        "Connected to AMQP server at %s@%s" % (parts.username, parts.hostname)
> +    )
> +    return amqp_con
> +
> +
> +PATH, app, secret_path, oid = initialise_app("test_manager")
> +
> +
> +@app.route("/", methods=["GET", "POST"])
> +def index_root():
> +    """Handle stop test requests"""
> +    session.permanent = True
> +    nick = maybe_escape(session.get("nickname"))
> +    if nick not in get_admin_nicks():
> +        return (
> +            HTML.format(
> +                (
> +                    "<p>You are not an admin. You are not "
> +                    "allowed to use this endpoint.</p>"
> +                )
> +            ),
> +            200,
> +        )
> +    params = {
> +        maybe_escape(k): maybe_escape(v) for k, v in request.args.items()
> +    }
> +    if list(params.keys()) != ["uuid"]:
> +        return (
> +            HTML.format(
> +                "<p>You have passed %s, please only pass the uuid</p>"
> +                % ",".join(params.keys())
> +            ),
> +            200,
> +        )
> +    if not RUNNING_FILE.is_file():
> +        raise RunningJSONNotFound
> +    running_data = json.loads(RUNNING_FILE.read_text())
> +    if params["uuid"] not in json.dumps(running_data):
> +        return (
> +            HTML.format(
> +                "<p>uuid %s not found in running jobs</p>" % params["uuid"]
> +            ),
> +            200,
> +        )
> +    queue_message = {
> +        "uuid": params["uuid"],
> +        "not-running-on": [],
> +    }
> +    submit_to_queue(queue_message)
> +    while params["uuid"] in RUNNING_FILE.read_text():
> +        pass
> +    return (
> +        HTML.format(
> +            "<p>Test with uuid %s has been killed.</p>" % params["uuid"]
> +        ),
> +        200,
> +    )


-- 
https://code.launchpad.net/~andersson123/autopkgtest-cloud/+git/autopkgtest-cloud/+merge/461654
Your team Canonical's Ubuntu QA is requested to review the proposed merge of ~andersson123/autopkgtest-cloud:stop-tests-from-webpage into autopkgtest-cloud:master.



References