summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/tools/docker/frontend.py
diff options
context:
space:
mode:
Diffstat (limited to 'testing/web-platform/tests/tools/docker/frontend.py')
-rw-r--r--testing/web-platform/tests/tools/docker/frontend.py141
1 files changed, 141 insertions, 0 deletions
diff --git a/testing/web-platform/tests/tools/docker/frontend.py b/testing/web-platform/tests/tools/docker/frontend.py
new file mode 100644
index 0000000000..6ee2d20633
--- /dev/null
+++ b/testing/web-platform/tests/tools/docker/frontend.py
@@ -0,0 +1,141 @@
+# mypy: allow-untyped-defs
+
+import argparse
+import logging
+import os
+import re
+import subprocess
+import sys
+
+here = os.path.abspath(os.path.dirname(__file__))
+wpt_root = os.path.abspath(os.path.join(here, os.pardir, os.pardir))
+
+logger = logging.getLogger()
+
+
+def build(tag="wpt:local", *args, **kwargs):
+ subprocess.check_call(["docker",
+ "build",
+ "--pull",
+ "--tag", tag,
+ here])
+
+
+def parser_push():
+ parser = argparse.ArgumentParser()
+ parser.add_argument("--tag", action="store",
+ help="Tag to use (default is taken from .taskcluster.yml)")
+ parser.add_argument("--force", action="store_true",
+ help="Ignore warnings and push anyway")
+ return parser
+
+
+def walk_yaml(root, target):
+ rv = []
+ if isinstance(root, list):
+ for value in root:
+ if isinstance(value, (dict, list)):
+ rv.extend(walk_yaml(value, target))
+ elif isinstance(root, dict):
+ for key, value in root.items():
+ if isinstance(value, (dict, list)):
+ rv.extend(walk_yaml(value, target))
+ elif key == target:
+ rv.append(value)
+ return rv
+
+
+def read_image_name():
+ import yaml
+ with open(os.path.join(wpt_root, ".taskcluster.yml")) as f:
+ taskcluster_data = yaml.safe_load(f)
+ taskcluster_values = set(walk_yaml(taskcluster_data, "image"))
+ with open(os.path.join(wpt_root, "tools", "ci", "tc", "tasks", "test.yml")) as f:
+ test_data = yaml.safe_load(f)
+ tests_value = test_data["components"]["wpt-base"]["image"]
+ return taskcluster_values, tests_value
+
+
+def lookup_tag(tag):
+ import requests
+ org, repo_version = tag.split("/", 1)
+ repo, version = repo_version.rsplit(":", 1)
+ resp = requests.get("https://hub.docker.com/v2/repositories/%s/%s/tags/%s" %
+ (org, repo, version))
+ if resp.status_code == 200:
+ return True
+ if resp.status_code == 404:
+ return False
+ resp.raise_for_status()
+
+
+def push(venv, tag=None, force=False, *args, **kwargs):
+ taskcluster_tags, tests_tag = read_image_name()
+
+ taskcluster_tag = taskcluster_tags.pop()
+
+ error_log = logger.warning if force else logger.error
+ if len(taskcluster_tags) != 0 or tests_tag != taskcluster_tag:
+ error_log("Image names in .taskcluster.yml and tools/ci/tc/tasks/test.yml "
+ "don't match.")
+ if not force:
+ sys.exit(1)
+ if tag is not None and tag != taskcluster_tag:
+ error_log("Supplied tag doesn't match .taskcluster.yml or "
+ "tools/ci/tc/tasks/test.yml; remember to update before pushing")
+ if not force:
+ sys.exit(1)
+ if tag is None:
+ logger.info("Using tag %s from .taskcluster.yml" % taskcluster_tag)
+ tag = taskcluster_tag
+
+ tag_re = re.compile(r"webplatformtests/wpt:\d\.\d+")
+ if not tag_re.match(tag):
+ error_log("Tag doesn't match expected format webplatformtests/wpt:0.x")
+ if not force:
+ sys.exit(1)
+
+ if lookup_tag(tag):
+ # No override for this case
+ logger.critical("Tag %s already exists" % tag)
+ sys.exit(1)
+
+ build(tag)
+ subprocess.check_call(["docker",
+ "push",
+ tag])
+
+
+def parser_run():
+ parser = argparse.ArgumentParser()
+ parser.add_argument("--rebuild", action="store_true", help="Force rebuild of image")
+ parser.add_argument("--checkout", action="store",
+ help="Revision to checkout in the image. "
+ "If this is not supplied we mount the wpt checkout on the host as "
+ "/home/test/web-platform-tests/")
+ parser.add_argument("--privileged", action="store_true",
+ help="Run the image in priviledged mode (required for emulators)")
+ parser.add_argument("--tag", action="store", default="wpt:local",
+ help="Docker image tag to use (default wpt:local)")
+ return parser
+
+
+def run(*args, **kwargs):
+ if kwargs["rebuild"]:
+ build()
+
+ args = ["docker", "run"]
+ args.extend(["--security-opt", "seccomp:%s" %
+ os.path.join(wpt_root, "tools", "docker", "seccomp.json")])
+ if kwargs["privileged"]:
+ args.append("--privileged")
+ if kwargs["checkout"]:
+ args.extend(["--env", "REF==%s" % kwargs["checkout"]])
+ else:
+ args.extend(["--mount",
+ "type=bind,source=%s,target=/home/test/web-platform-tests" % wpt_root])
+ args.extend(["-it", kwargs["tag"]])
+
+ proc = subprocess.Popen(args)
+ proc.wait()
+ return proc.returncode