12
12
import requests
13
13
import yaml
14
14
15
- from jinja2 import Environment , FileSystemLoader
15
+ from jinja2 import Environment , FileSystemLoader , ChoiceLoader
16
16
17
17
from kernelci .config .base import get_system_arch
18
18
@@ -75,13 +75,22 @@ class Runtime(abc.ABC):
75
75
TEMPLATES = ['config/runtime' , '/etc/kernelci/runtime' ]
76
76
77
77
# 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 ):
79
79
"""A Runtime object can be used to run jobs in a runtime environment
80
80
81
81
*config* is a kernelci.config.runtime.Runtime object
82
+ *custom_template_dir* is an optional custom directory for Jinja2 templates
82
83
"""
83
84
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 )
85
94
self ._user = user
86
95
self ._token = token
87
96
@@ -96,8 +105,9 @@ def templates(self):
96
105
return self ._templates
97
106
98
107
def _get_template (self , job_config ):
108
+ loaders = [FileSystemLoader (path ) for path in self .templates ]
99
109
jinja2_env = Environment (
100
- loader = FileSystemLoader ( self . templates ),
110
+ loader = ChoiceLoader ( loaders ),
101
111
extensions = ["jinja2.ext.do" ]
102
112
)
103
113
jinja2_env .globals .update (self ._get_jinja2_functions ())
@@ -211,19 +221,20 @@ def wait(self, job_object):
211
221
"""Wait for a job to complete and get the exit status code"""
212
222
213
223
214
- def get_runtime (config , user = None , token = None ):
224
+ def get_runtime (config , user = None , token = None , custom_template_dir = None ):
215
225
"""Get the Runtime object for a given runtime config.
216
226
217
227
*config* is a kernelci.config.runtime.Runtime object
218
228
*user* is the name of the user to connect to the runtime
219
229
*token* is the associated token to connect to the runtime
230
+ *custom_template_dir* is an optional custom directory for Jinja2 templates
220
231
"""
221
232
module_name = '.' .join (['kernelci' , 'runtime' , config .lab_type ])
222
233
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 )
224
235
225
236
226
- def get_all_runtimes (runtime_configs , opts ):
237
+ def get_all_runtimes (runtime_configs , opts , custom_template_dir = None ):
227
238
"""Get all the Runtime objects based on the runtime configs and options
228
239
229
240
This will iterate over all the runtimes configs and yield a (name, runtime)
@@ -232,14 +243,16 @@ def get_all_runtimes(runtime_configs, opts):
232
243
233
244
*runtime_configs* is the 'runtimes' config loaded from YAML
234
245
*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
235
247
"""
236
248
for config_name , config in runtime_configs .items ():
237
249
section = ('runtime' , config_name )
238
250
user , token = (
239
251
opts .get_from_section (section , opt )
240
252
for opt in ('user' , 'runtime_token' )
241
253
)
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
243
256
244
257
245
258
def evaluate_test_suite_result (child_nodes ):
0 commit comments