Skip to content

Commit 9ef18ea

Browse files
Jeny Sadadiagctucker
authored andcommitted
kernelci.cli: rework kci job commands
Rework `kci` commands to manage KernelCI jobs with `Click` framework. Signed-off-by: Jeny Sadadia <jeny.sadadia@collabora.com>
1 parent 8162cad commit 9ef18ea

File tree

4 files changed

+117
-0
lines changed

4 files changed

+117
-0
lines changed

kci

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ from kernelci.cli import ( # pylint: disable=unused-import
2020
config as kci_config,
2121
docker as kci_docker,
2222
event as kci_event,
23+
job as kci_job,
2324
node as kci_node,
2425
storage as kci_storage,
2526
user as kci_user,

kernelci/api/helper.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
"""KernelCI API helpers"""
88

99
from typing import Dict
10+
import json
1011

1112
from . import API
1213

@@ -180,3 +181,9 @@ def submit_results(self, results, root):
180181
node_id = data['node']['id']
181182
# pylint: disable=protected-access
182183
return self.api._put(f'nodes/{node_id}', data).json()
184+
185+
@classmethod
186+
def load_json(cls, json_path, encoding='utf-8'):
187+
"""Read content from JSON file"""
188+
with open(json_path, encoding=encoding) as json_file:
189+
return json.load(json_file)

kernelci/cli/__init__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,10 @@ class Args: # pylint: disable=too-few-public-methods
5858
'-v', '--verbose/--no-verbose', default=None,
5959
help="Print more details output"
6060
)
61+
runtime = click.option(
62+
'--runtime',
63+
help="Name of the Runtime environment config entry"
64+
)
6165

6266

6367
def catch_http_error(func):

kernelci/cli/job.py

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
# SPDX-License-Identifier: LGPL-2.1-or-later
2+
#
3+
# Copyright (C) 2023 Collabora Limited
4+
# Author: Guillaume Tucker <guillaume.tucker@collabora.com>
5+
# Author: Jeny Sadadia <jeny.sadadia@collabora.com>
6+
7+
"""Tool to generate and run KernelCI jobs"""
8+
9+
import json
10+
11+
import click
12+
13+
import kernelci.api
14+
import kernelci.config
15+
import kernelci.api.helper
16+
import kernelci.runtime
17+
from . import Args, kci, catch_http_error
18+
19+
20+
@kci.group(name='job')
21+
def kci_job():
22+
"""Manage KernelCI jobs"""
23+
24+
25+
@kci_job.command(secrets=True)
26+
@click.argument('name')
27+
@click.option('--node-id')
28+
@click.option('--node-json')
29+
@Args.config
30+
@Args.api
31+
@Args.indent
32+
@catch_http_error
33+
def new(name, node_id, node_json, config, # pylint: disable=too-many-arguments
34+
api, indent, secrets):
35+
"""Create a new job node"""
36+
configs = kernelci.config.load(config)
37+
api_config = configs['api'][api]
38+
api = kernelci.api.get_api(api_config, secrets.api.token)
39+
helper = kernelci.api.helper.APIHelper(api)
40+
if node_id:
41+
input_node = api.get_node(node_id)
42+
elif node_json:
43+
input_node = helper.load_json(node_json)
44+
else:
45+
raise click.ClickException("Either --node-id or --node-json \
46+
is required.")
47+
job_config = configs['jobs'][name]
48+
job_node = helper.create_job_node(job_config, input_node)
49+
click.echo(json.dumps(job_node, indent=indent))
50+
51+
52+
@kci_job.command(secrets=True)
53+
@click.argument('node-id')
54+
@click.option('--platform', help="Name of the platform to run the job",
55+
required=True)
56+
@click.option('--output', help="Path of the directory where to generate \
57+
the job data")
58+
@Args.runtime
59+
@Args.storage
60+
@Args.config
61+
@Args.api
62+
@catch_http_error
63+
def generate(node_id, # pylint: disable=too-many-arguments, too-many-locals
64+
runtime, storage, platform, output, config, api, secrets):
65+
"""Generate a job definition in a file"""
66+
configs = kernelci.config.load(config)
67+
api_config = configs['api'][api]
68+
api = kernelci.api.get_api(api_config, secrets.api.token)
69+
job_node = api.get_node(node_id)
70+
job = kernelci.runtime.Job(job_node, configs['jobs'][job_node['name']])
71+
job.platform_config = configs['device_types'][platform]
72+
job.storage_config = (
73+
configs['storage'][storage]
74+
if storage else None
75+
)
76+
runtime_config = configs['runtimes'][runtime]
77+
runtime = kernelci.runtime.get_runtime(
78+
runtime_config, token=secrets.api.runtime_token)
79+
params = runtime.get_params(job, api.config)
80+
job_data = runtime.generate(job, params)
81+
if output:
82+
output_file = runtime.save_file(job_data, output, params)
83+
click.echo(f"Job saved in {output_file}")
84+
else:
85+
click.echo(job_data)
86+
87+
88+
@kci_job.command(secrets=True)
89+
@click.argument('job-path')
90+
@click.option('--wait', is_flag=True)
91+
@Args.runtime
92+
@Args.config
93+
@catch_http_error
94+
def submit(runtime, job_path, wait, config, secrets):
95+
"""Submit a job definition to its designated runtime"""
96+
configs = kernelci.config.load(config)
97+
runtime_config = configs['runtimes'][runtime]
98+
runtime = kernelci.runtime.get_runtime(
99+
runtime_config, token=secrets.api.runtime_token
100+
)
101+
job = runtime.submit(job_path)
102+
click.echo(runtime.get_job_id(job))
103+
if wait:
104+
ret = runtime.wait(job)
105+
click.echo(f"Job completed with status: {ret}")

0 commit comments

Comments
 (0)