summaryrefslogtreecommitdiff
path: root/.gitlab-ci/lava/utils/lava_job_definition.py
blob: df6fc99a90828737003e30435f7853b427cc360b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
# How many attempts should be made when a timeout happen during LAVA device boot.
from os import getenv
from typing import Any

NUMBER_OF_ATTEMPTS_LAVA_BOOT = int(getenv("LAVA_NUMBER_OF_ATTEMPTS_LAVA_BOOT", 3))

# Supports any integers in [0, 100].
# The scheduler considers the job priority when ordering the queue
# to consider which job should run next.
JOB_PRIORITY = int(getenv("LAVA_JOB_PRIORITY", 75))


def generate_lava_yaml_payload(args) -> dict[str, Any]:
    # General metadata and permissions, plus also inexplicably kernel arguments
    values = {
        "job_name": "mesa: {}".format(args.pipeline_info),
        "device_type": args.device_type,
        "visibility": {"group": [args.visibility_group]},
        "priority": JOB_PRIORITY,
        "context": {
            "extra_nfsroot_args": " init=/init rootwait usbcore.quirks=0bda:8153:k"
        },
        "timeouts": {
            "job": {"minutes": args.job_timeout_min},
            "actions": {
                "depthcharge-retry": {
                    # Could take between 1 and 1.5 min in slower boots
                    "minutes": 2
                },
                "depthcharge-start": {
                    # Should take less than 1 min.
                    "minutes": 1,
                },
                "depthcharge-action": {
                    # This timeout englobes the entire depthcharge timing,
                    # including retries
                    "minutes": 2
                    * NUMBER_OF_ATTEMPTS_LAVA_BOOT,
                },
            },
        },
    }

    if args.lava_tags:
        values["tags"] = args.lava_tags.split(",")

    # URLs to our kernel rootfs to boot from, both generated by the base
    # container build
    deploy = {
        "timeout": {"minutes": 10},
        "to": "tftp",
        "os": "oe",
        "kernel": {
            "url": "{}/{}".format(args.kernel_url_prefix, args.kernel_image_name),
        },
        "nfsrootfs": {
            "url": "{}/lava-rootfs.tar.zst".format(args.rootfs_url_prefix),
            "compression": "zstd",
        },
    }
    if args.kernel_image_type:
        deploy["kernel"]["type"] = args.kernel_image_type
    if args.dtb_filename:
        deploy["dtb"] = {
            "url": "{}/{}.dtb".format(args.kernel_url_prefix, args.dtb_filename)
        }

    # always boot over NFS
    boot = {
        "failure_retry": NUMBER_OF_ATTEMPTS_LAVA_BOOT,
        "method": args.boot_method,
        "commands": "nfs",
        "prompts": ["lava-shell:"],
    }

    # skeleton test definition: only declaring each job as a single 'test'
    # since LAVA's test parsing is not useful to us
    run_steps = []
    test = {
        "timeout": {"minutes": args.job_timeout_min},
        "failure_retry": 1,
        "definitions": [
            {
                "name": "mesa",
                "from": "inline",
                "lava-signal": "kmsg",
                "path": "inline/mesa.yaml",
                "repository": {
                    "metadata": {
                        "name": "mesa",
                        "description": "Mesa test plan",
                        "os": ["oe"],
                        "scope": ["functional"],
                        "format": "Lava-Test Test Definition 1.0",
                    },
                    "run": {"steps": run_steps},
                },
            }
        ],
    }

    # job execution script:
    #   - inline .gitlab-ci/common/init-stage1.sh
    #   - fetch and unpack per-pipeline build artifacts from build job
    #   - fetch and unpack per-job environment from lava-submit.sh
    #   - exec .gitlab-ci/common/init-stage2.sh

    with open(args.first_stage_init, "r") as init_sh:
        run_steps += [
            x.rstrip() for x in init_sh if not x.startswith("#") and x.rstrip()
        ]
        run_steps.append(
            f"curl -L --retry 4 -f --retry-all-errors --retry-delay 60 {args.job_rootfs_overlay_url} | tar -xz -C /",
        )

    if args.jwt_file:
        with open(args.jwt_file) as jwt_file:
            run_steps += [
                "set +x",
                f'echo -n "{jwt_file.read()}" > "{args.jwt_file}"  # HIDEME',
                "set -x",
                f'echo "export CI_JOB_JWT_FILE={args.jwt_file}" >> /set-job-env-vars.sh',
            ]
    else:
        run_steps += [
            "echo Could not find jwt file, disabling MINIO requests...",
            "sed -i '/MINIO_RESULTS_UPLOAD/d' /set-job-env-vars.sh",
        ]

    run_steps += [
        "mkdir -p {}".format(args.ci_project_dir),
        "curl {} | tar --zstd -x -C {}".format(args.build_url, args.ci_project_dir),
        # Sleep a bit to give time for bash to dump shell xtrace messages into
        # console which may cause interleaving with LAVA_SIGNAL_STARTTC in some
        # devices like a618.
        "sleep 1",
        # Putting CI_JOB name as the testcase name, it may help LAVA farm
        # maintainers with monitoring
        f"lava-test-case 'mesa-ci_{args.mesa_job_name}' --shell /init-stage2.sh",
    ]

    values["actions"] = [
        {"deploy": deploy},
        {"boot": boot},
        {"test": test},
    ]

    return values