Beispiel #1
0
def get_transformed_webhook_payload(gh_payload,
                                    default_branch=None,
                                    lookup_user=None):
    """ Returns the GitHub webhook JSON payload transformed into our own payload
      format. If the gh_payload is not valid, returns None.
  """
    try:
        validate(gh_payload, GITHUB_WEBHOOK_PAYLOAD_SCHEMA)
    except Exception as exc:
        raise InvalidPayloadException(exc.message)

    payload = JSONPathDict(gh_payload)

    if payload["head_commit"] is None:
        raise SkipRequestException

    config = SafeDictSetter()
    config["commit"] = payload["head_commit.id"]
    config["ref"] = payload["ref"]
    config["default_branch"] = payload[
        "repository.default_branch"] or default_branch
    config["git_url"] = payload["repository.ssh_url"]

    config["commit_info.url"] = payload["head_commit.url"]
    config["commit_info.message"] = payload["head_commit.message"]
    config["commit_info.date"] = payload["head_commit.timestamp"]

    config["commit_info.author.username"] = payload[
        "head_commit.author.username"]
    config["commit_info.author.url"] = payload.get(
        "head_commit.author.html_url")
    config["commit_info.author.avatar_url"] = payload.get(
        "head_commit.author.avatar_url")

    config["commit_info.committer.username"] = payload.get(
        "head_commit.committer.username")
    config["commit_info.committer.url"] = payload.get(
        "head_commit.committer.html_url")
    config["commit_info.committer.avatar_url"] = payload.get(
        "head_commit.committer.avatar_url")

    # Note: GitHub doesn't always return the extra information for users, so we do the lookup
    # manually if possible.
    if (lookup_user and not payload.get("head_commit.author.html_url")
            and payload.get("head_commit.author.username")):
        author_info = lookup_user(payload["head_commit.author.username"])
        if author_info:
            config["commit_info.author.url"] = author_info["html_url"]
            config["commit_info.author.avatar_url"] = author_info["avatar_url"]

    if (lookup_user and payload.get("head_commit.committer.username")
            and not payload.get("head_commit.committer.html_url")):
        committer_info = lookup_user(payload["head_commit.committer.username"])
        if committer_info:
            config["commit_info.committer.url"] = committer_info["html_url"]
            config["commit_info.committer.avatar_url"] = committer_info[
                "avatar_url"]

    return config.dict_value()
Beispiel #2
0
    def build_manifest(tag, manifest, synthetic_image_id):
        """
        Builds an ACI manifest of an existing repository image.
        """
        docker_layer_data = JSONPathDict(
            json.loads(manifest.leaf_layer.raw_v1_metadata))
        config = docker_layer_data["config"] or JSONPathDict({})

        namespace = tag.repository.namespace_name
        repo_name = tag.repository.name
        source_url = "%s://%s/%s/%s:%s" % (
            app.config["PREFERRED_URL_SCHEME"],
            app.config["SERVER_HOSTNAME"],
            namespace,
            repo_name,
            tag.name,
        )

        # ACI requires that the execution command be absolutely referenced. Therefore, if we find
        # a relative command, we give it as an argument to /bin/sh to resolve and execute for us.
        entrypoint = config["Entrypoint"] or []
        exec_path = entrypoint + (config["Cmd"] or [])
        if exec_path and not exec_path[0].startswith("/"):
            exec_path = ["/bin/sh", "-c", '""%s""' % " ".join(exec_path)]

        # TODO: ACI doesn't support : in the name, so remove any ports.
        hostname = app.config["SERVER_HOSTNAME"]
        hostname = hostname.split(":", 1)[0]

        # Calculate the environment variables.
        docker_env_vars = config.get("Env") or []
        env_vars = []
        for var in docker_env_vars:
            pieces = var.split("=")
            if len(pieces) != 2:
                continue

            env_vars.append(pieces)

        manifest = {
            "acKind":
            "ImageManifest",
            "acVersion":
            "0.6.1",
            "name":
            "%s/%s/%s" %
            (hostname.lower(), namespace.lower(), repo_name.lower()),
            "labels": [
                {
                    "name": "version",
                    "value": tag.name,
                },
                {
                    "name": "arch",
                    "value": docker_layer_data.get("architecture") or "amd64"
                },
                {
                    "name": "os",
                    "value": docker_layer_data.get("os") or "linux"
                },
            ],
            "app": {
                "exec":
                exec_path,
                # Below, `or 'root'` is required to replace empty string from Dockerfiles.
                "user":
                config.get("User") or "root",
                "group":
                config.get("Group") or "root",
                "eventHandlers": [],
                "workingDirectory":
                config.get("WorkingDir") or "/",
                "environment": [{
                    "name": key,
                    "value": value
                } for (key, value) in env_vars],
                "isolators":
                DockerV1ToACIManifestTranslator._build_isolators(config),
                "mountPoints":
                DockerV1ToACIManifestTranslator._build_volumes(config),
                "ports":
                DockerV1ToACIManifestTranslator._build_ports(config),
                "annotations": [
                    {
                        "name": "created",
                        "value": docker_layer_data.get("created") or ""
                    },
                    {
                        "name": "homepage",
                        "value": source_url
                    },
                    {
                        "name": "quay.io/derived-image",
                        "value": synthetic_image_id
                    },
                ],
            },
        }

        return manifest