Skip to content

Commit a652096

Browse files
committed
Improve jinja2 search, include custom config path into search
Signed-off-by: Denys Fedoryshchenko <[email protected]>
1 parent 085c515 commit a652096

File tree

2 files changed

+24
-11
lines changed

2 files changed

+24
-11
lines changed

kernelci/cli/job.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ def new(name, input_node_id, platform, # pylint: disable=too-many-arguments
5555
if runtime not in configs['runtimes']:
5656
raise click.ClickException(f"Invalid runtime {runtime}")
5757
runtime = kernelci.runtime.get_runtime(
58-
configs['runtimes'][runtime], token=secrets.api.runtime_token)
58+
configs['runtimes'][runtime], token=secrets.api.runtime_token, custom_template_dir=config[0] if config else None)
5959
job_node = helper.create_job_node(job_config, input_node,
6060
platform=platform_config, runtime=runtime)
6161
if job_node:
@@ -116,7 +116,7 @@ def generate(node_id, # pylint: disable=too-many-arguments, too-many-locals
116116
if runtime_config is None:
117117
raise click.ClickException(f"Runtime {runtime} not found in the config")
118118
runtime = kernelci.runtime.get_runtime(
119-
runtime_config, token=secrets.api.runtime_token)
119+
runtime_config, token=secrets.api.runtime_token, custom_template_dir=config[0] if config else None)
120120
params = runtime.get_params(job, api.config)
121121
if not params:
122122
raise click.ClickException("Invalid job parameters, aborting...")
@@ -149,7 +149,7 @@ def submit(runtime, job_path, wait, # pylint: disable=too-many-arguments
149149
configs = kernelci.config.load(config)
150150
runtime_config = configs['runtimes'][runtime]
151151
runtime = kernelci.runtime.get_runtime(
152-
runtime_config, token=secrets.api.runtime_token
152+
runtime_config, token=secrets.api.runtime_token, custom_template_dir=config[0] if config else None
153153
)
154154
job = runtime.submit(job_path)
155155
click.echo(runtime.get_job_id(job))

kernelci/runtime/__init__.py

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
import requests
1313
import yaml
1414

15-
from jinja2 import Environment, FileSystemLoader
15+
from jinja2 import Environment, FileSystemLoader, ChoiceLoader
1616

1717
from kernelci.config.base import get_system_arch
1818

@@ -75,13 +75,22 @@ class Runtime(abc.ABC):
7575
TEMPLATES = ['config/runtime', '/etc/kernelci/runtime']
7676

7777
# pylint: disable=unused-argument
78-
def __init__(self, config, user=None, token=None):
78+
def __init__(self, config, user=None, token=None, custom_template_dir=None):
7979
"""A Runtime object can be used to run jobs in a runtime environment
8080
8181
*config* is a kernelci.config.runtime.Runtime object
82+
*custom_template_dir* is an optional custom directory for Jinja2 templates
8283
"""
8384
self._config = config
84-
self._templates = self.TEMPLATES
85+
self._templates = self.TEMPLATES.copy()
86+
if custom_template_dir:
87+
# Add the main custom dir
88+
self._templates.append(custom_template_dir)
89+
# Add relevant subdirectories
90+
for subdir in ["runtime", "runtime/base", "runtime/boot", "runtime/tests"]:
91+
sub_path = os.path.join(custom_template_dir, subdir) if not custom_template_dir.endswith(subdir) else custom_template_dir
92+
if os.path.isdir(sub_path):
93+
self._templates.append(sub_path)
8594
self._user = user
8695
self._token = token
8796

@@ -96,8 +105,9 @@ def templates(self):
96105
return self._templates
97106

98107
def _get_template(self, job_config):
108+
loaders = [FileSystemLoader(path) for path in self.templates]
99109
jinja2_env = Environment(
100-
loader=FileSystemLoader(self.templates),
110+
loader=ChoiceLoader(loaders),
101111
extensions=["jinja2.ext.do"]
102112
)
103113
jinja2_env.globals.update(self._get_jinja2_functions())
@@ -211,19 +221,20 @@ def wait(self, job_object):
211221
"""Wait for a job to complete and get the exit status code"""
212222

213223

214-
def get_runtime(config, user=None, token=None):
224+
def get_runtime(config, user=None, token=None, custom_template_dir=None):
215225
"""Get the Runtime object for a given runtime config.
216226
217227
*config* is a kernelci.config.runtime.Runtime object
218228
*user* is the name of the user to connect to the runtime
219229
*token* is the associated token to connect to the runtime
230+
*custom_template_dir* is an optional custom directory for Jinja2 templates
220231
"""
221232
module_name = '.'.join(['kernelci', 'runtime', config.lab_type])
222233
runtime_module = importlib.import_module(module_name)
223-
return runtime_module.get_runtime(config, user=user, token=token)
234+
return runtime_module.get_runtime(config, user=user, token=token, custom_template_dir=custom_template_dir)
224235

225236

226-
def get_all_runtimes(runtime_configs, opts):
237+
def get_all_runtimes(runtime_configs, opts, custom_template_dir=None):
227238
"""Get all the Runtime objects based on the runtime configs and options
228239
229240
This will iterate over all the runtimes configs and yield a (name, runtime)
@@ -232,14 +243,16 @@ def get_all_runtimes(runtime_configs, opts):
232243
233244
*runtime_configs* is the 'runtimes' config loaded from YAML
234245
*opts* is an Options object loaded from the CLI args and settings file
246+
*custom_template_dir* is an optional custom directory for Jinja2 templates
235247
"""
236248
for config_name, config in runtime_configs.items():
237249
section = ('runtime', config_name)
238250
user, token = (
239251
opts.get_from_section(section, opt)
240252
for opt in ('user', 'runtime_token')
241253
)
242-
yield config_name, get_runtime(config, user, token)
254+
runtime = get_runtime(config, user=user, token=token, custom_template_dir=custom_template_dir)
255+
yield config_name, runtime
243256

244257

245258
def evaluate_test_suite_result(child_nodes):

0 commit comments

Comments
 (0)