tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

frontend.py (4557B)


      1 # mypy: allow-untyped-defs
      2 
      3 import argparse
      4 import logging
      5 import os
      6 import re
      7 import subprocess
      8 import sys
      9 
     10 here = os.path.abspath(os.path.dirname(__file__))
     11 wpt_root = os.path.abspath(os.path.join(here, os.pardir, os.pardir))
     12 
     13 logger = logging.getLogger()
     14 
     15 
     16 def build(tag="wpt:local", *args, **kwargs):
     17    subprocess.check_call(["docker",
     18                           "build",
     19                           "--pull",
     20                           "--tag", tag,
     21                           here])
     22 
     23 
     24 def parser_push():
     25    parser = argparse.ArgumentParser()
     26    parser.add_argument("--tag",
     27                        help="Tag to use (default is taken from .taskcluster.yml)")
     28    parser.add_argument("--force", action="store_true",
     29                        help="Ignore warnings and push anyway")
     30    return parser
     31 
     32 
     33 def walk_yaml(root, target):
     34    rv = []
     35    if isinstance(root, list):
     36        for value in root:
     37            if isinstance(value, (dict, list)):
     38                rv.extend(walk_yaml(value, target))
     39    elif isinstance(root, dict):
     40        for key, value in root.items():
     41            if isinstance(value, (dict, list)):
     42                rv.extend(walk_yaml(value, target))
     43            elif key == target:
     44                rv.append(value)
     45    return rv
     46 
     47 
     48 def read_image_name():
     49    import yaml
     50    with open(os.path.join(wpt_root, ".taskcluster.yml")) as f:
     51        taskcluster_data = yaml.safe_load(f)
     52    taskcluster_values = set(walk_yaml(taskcluster_data, "image"))
     53    with open(os.path.join(wpt_root, "tools", "ci", "tc", "tasks", "test.yml")) as f:
     54        test_data = yaml.safe_load(f)
     55    tests_value = test_data["components"]["wpt-base"]["image"]
     56    return taskcluster_values, tests_value
     57 
     58 
     59 def tag_exists(tag):
     60    retcode = subprocess.call(["docker", "manifest", "inspect", tag])
     61    # The command succeeds if the tag exists.
     62    return retcode != 0
     63 
     64 
     65 def push(venv, tag=None, force=False, *args, **kwargs):
     66    taskcluster_tags, tests_tag = read_image_name()
     67 
     68    taskcluster_tag = taskcluster_tags.pop()
     69 
     70    error_log = logger.warning if force else logger.error
     71    if len(taskcluster_tags) != 0 or tests_tag != taskcluster_tag:
     72        error_log("Image names in .taskcluster.yml and tools/ci/tc/tasks/test.yml "
     73                  "don't match.")
     74        if not force:
     75            sys.exit(1)
     76    if tag is not None and tag != taskcluster_tag:
     77        error_log("Supplied tag doesn't match .taskcluster.yml or "
     78                  "tools/ci/tc/tasks/test.yml; remember to update before pushing")
     79        if not force:
     80            sys.exit(1)
     81    if tag is None:
     82        logger.info("Using tag %s from .taskcluster.yml" % taskcluster_tag)
     83        tag = taskcluster_tag
     84 
     85    tag_re = re.compile(r"ghcr.io/web-platform-tests/wpt:\d+")
     86    if not tag_re.match(tag):
     87        error_log("Tag doesn't match expected format ghcr.io/web-platform-tests/wpt:x")
     88        if not force:
     89            sys.exit(1)
     90 
     91    if tag_exists(tag):
     92        # No override for this case
     93        logger.critical("Tag %s already exists" % tag)
     94        sys.exit(1)
     95 
     96    build(tag)
     97    subprocess.check_call(["docker",
     98                           "push",
     99                           tag])
    100 
    101 
    102 def parser_run():
    103    parser = argparse.ArgumentParser()
    104    parser.add_argument("--rebuild", action="store_true", help="Force rebuild of image")
    105    parser.add_argument("--checkout",
    106                        help="Revision to checkout in the image. "
    107                        "If this is not supplied we mount the wpt checkout on the host as "
    108                        "/home/test/web-platform-tests/")
    109    parser.add_argument("--privileged", action="store_true",
    110                        help="Run the image in priviledged mode (required for emulators)")
    111    parser.add_argument("--tag", default="wpt:local",
    112                        help="Docker image tag to use (default wpt:local)")
    113    return parser
    114 
    115 
    116 def run(*args, **kwargs):
    117    if kwargs["rebuild"]:
    118        build()
    119 
    120    args = ["docker", "run"]
    121    args.extend(["--security-opt", "seccomp:%s" %
    122                 os.path.join(wpt_root, "tools", "docker", "seccomp.json")])
    123    if kwargs["privileged"]:
    124        args.append("--privileged")
    125        args.extend(["--device", "/dev/kvm"])
    126    if kwargs["checkout"]:
    127        args.extend(["--env", "REF==%s" % kwargs["checkout"]])
    128    else:
    129        args.extend(["--mount",
    130                     "type=bind,source=%s,target=/home/test/web-platform-tests" % wpt_root])
    131    args.extend(["-it", kwargs["tag"]])
    132 
    133    proc = subprocess.Popen(args)
    134    proc.wait()
    135    return proc.returncode