-
Notifications
You must be signed in to change notification settings - Fork 37
Expand file tree
/
Copy pathjob-runner
More file actions
executable file
·105 lines (85 loc) · 4.35 KB
/
job-runner
File metadata and controls
executable file
·105 lines (85 loc) · 4.35 KB
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
#!/usr/bin/env python3
# Copyright (C) 2024 Red Hat, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import argparse
import asyncio
import logging
import sys
from pathlib import Path
from typing import assert_never
from lib.aio.job import Job, run_job
from lib.aio.jobcontext import JobContext
from lib.aio.jsonutil import JsonError, JsonObject
from lib.aio.testingfarm import TestingFarmClient
from lib.aio.util import JsonObjectAction, KeyValueAction
logger = logging.getLogger(__name__)
BOTS_DIR = Path(__file__).parent
async def main() -> None:
parser = argparse.ArgumentParser()
parser.add_argument('--debug', action='store_true', help="Enable debugging output")
parser.add_argument('--config-file', '-F', metavar='FILENAME',
help="Config file [default JOB_RUNNER_CONFIG or ~/.config/cockpit-dev/job-runner.toml]")
parser.add_argument('--to', choices=['local', 'testing-farm'], default='local',
help="Where to run the job (default: local)")
subprograms = parser.add_subparsers(dest='cmd', required=True, title="Subcommands")
run_parser = subprograms.add_parser("run", help="Run a single job provided on the command line")
run_parser.add_argument('repo', help="The repository (like `cockpit-project/cockpit`)")
run_parser.add_argument('--forge', help="The forge to interact with (default: first)")
run_parser.add_argument('--pull', type=int, help="The pull request number to run tests on")
run_parser.add_argument('--sha', help="The revision sha, exactly 40 hex digits")
run_parser.add_argument('--context', help="The status we're reporting against the sha")
run_parser.add_argument('--target', help="The target branch")
run_parser.add_argument('--report', action=JsonObjectAction, help="Open an issue on failures")
run_parser.add_argument('--slug', help="The URL slug (used for logging)")
run_parser.add_argument('--title', help="The title for the log page")
run_parser.add_argument('--container', help="The container image (like `ghcr.io/cockpit-project/tasks:latest`)")
run_parser.add_argument('--env', help="Environment variables for the test run", action=KeyValueAction)
run_parser.add_argument('--timeout', type=int, help="Timeout of the job, in minutes", default=120)
run_parser.add_argument('--secret', dest='secrets', default=[], action='append', help="Provide the named secret")
run_parser.add_argument('command', nargs='*', help="Command to run [default: .cockpit-ci/run]")
json_parser = subprograms.add_parser("json", help="Run a single given as a JSON blob")
json_parser.add_argument('json', action=JsonObjectAction, help="The job, in JSON format")
args = parser.parse_args()
if args.debug:
logging.basicConfig(level=logging.DEBUG)
else:
logging.basicConfig(level=logging.INFO)
job_json: JsonObject
match args.cmd:
case 'run':
job_json = vars(args)
case 'json':
job_json = args.json
case other:
assert_never(other)
ctx = JobContext(args.config_file, debug=args.debug)
match args.to:
case 'testing-farm':
async with TestingFarmClient() as tf:
request_id = await tf.submit_job(ctx, job_json)
artifacts_url = await tf.wait_for_artifacts(request_id)
if artifacts_url:
print(artifacts_url)
else:
sys.exit(f'Job failed to start: {tf.get_request_url(request_id)}')
case 'local':
try:
job = Job(job_json)
except JsonError as exc:
sys.exit(f'Poorly formed job: {exc}')
async with ctx:
await run_job(job, ctx)
if __name__ == '__main__':
asyncio.run(main())