Skip to content

Commit 24dba2d

Browse files
committed
runtime/lava: Implement storage upload function
If url is none, this is "pull-only" lava, and we need to upload definition to storage. Implement relevant bits, including additional functionality for context library. Signed-off-by: Denys Fedoryshchenko <[email protected]>
1 parent c080bb5 commit 24dba2d

File tree

2 files changed

+56
-2
lines changed

2 files changed

+56
-2
lines changed

kernelci/context/__init__.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -468,6 +468,22 @@ def init_api(self, name: str) -> Optional[Dict[str, Any]]:
468468
"""
469469
return self.get_api_config(name)
470470

471+
def get_default_storage_config(self) -> Optional[str]:
472+
"""Get default storage configuration name from TOML [DEFAULT] section
473+
474+
Returns:
475+
Default storage configuration name or None if not found
476+
"""
477+
return self.get_secret("DEFAULT.storage_config")
478+
479+
def get_default_api_config(self) -> Optional[str]:
480+
"""Get default API configuration name from TOML [DEFAULT] section
481+
482+
Returns:
483+
Default API configuration name or None if not found
484+
"""
485+
return self.get_secret("DEFAULT.api_config")
486+
471487
def get_storage_names(self) -> List[str]:
472488
"""Get list of all available storage configuration names
473489

kernelci/runtime/lava.py

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,16 @@
33
# Copyright (C) 2019 Linaro Limited
44
# Author: Dan Rue <[email protected]>
55
#
6-
# Copyright (C) 2019, 2021-2023 Collabora Limited
6+
# Copyright (C) 2019, 2021-2025 Collabora Limited
77
# Author: Guillaume Tucker <[email protected]>
88
# Author: Michal Galka <[email protected]>
9+
# Author: Denys Fedoryshchenko <[email protected]>
910

1011
"""LAVA runtime implementation"""
1112

1213
from collections import namedtuple
1314
import time
15+
import uuid
1416
from urllib.parse import urljoin
1517

1618
import requests
@@ -300,8 +302,9 @@ class LAVA(Runtime):
300302
API_VERSION = 'v0.2'
301303
RestAPIServer = namedtuple('RestAPIServer', ['url', 'session'])
302304

303-
def __init__(self, configs, **kwargs):
305+
def __init__(self, configs, context=None, **kwargs):
304306
super().__init__(configs, **kwargs)
307+
self._context = context
305308
self._server = self._connect()
306309

307310
def _get_priority(self, job):
@@ -368,6 +371,8 @@ def wait(self, job_object):
368371
time.sleep(3)
369372

370373
def _connect(self):
374+
if not hasattr(self.config, 'url') or not self.config.url:
375+
return self.RestAPIServer(None, None)
371376
rest_url = f'{self.config.url}/api/{self.API_VERSION}/'
372377
rest_api = self.RestAPIServer(rest_url, requests.Session())
373378
rest_api.session.params = {'format': 'json', 'limit': '256'}
@@ -378,6 +383,9 @@ def _connect(self):
378383
return rest_api
379384

380385
def _submit(self, job):
386+
if self._server.url is None:
387+
return self._store_job_in_external_storage(job)
388+
381389
jobs_url = urljoin(self._server.url, 'jobs/')
382390
job_data = {
383391
'definition': job,
@@ -391,6 +399,36 @@ def _submit(self, job):
391399
resp.raise_for_status()
392400
return resp.json()['job_ids'][0]
393401

402+
def _store_job_in_external_storage(self, job):
403+
"""Store job in external storage when LAVA server URL is not defined"""
404+
if not self._context:
405+
raise ValueError("Context is required for external storage but was not provided")
406+
407+
# Get default storage configuration name from TOML [DEFAULT] section
408+
storage_name = self._context.get_default_storage_config()
409+
if not storage_name:
410+
# Fallback to first available storage if no default is specified
411+
storage_names = self._context.get_storage_names()
412+
if not storage_names:
413+
raise ValueError("No storage configurations found in context")
414+
storage_name = storage_names[0]
415+
416+
storage = self._context.init_storage(storage_name)
417+
if not storage:
418+
raise ValueError(f"Failed to initialize storage '{storage_name}'")
419+
420+
# Generate a unique filename for the job
421+
filename = f"lava_job_definition"
422+
423+
# Store the job definition in external storage
424+
try:
425+
job_bytes = job.encode('utf-8')
426+
storage.upload_single((filename, job_bytes))
427+
print(f"Job stored in external storage '{storage_name}': {filename}")
428+
return None
429+
except Exception as e:
430+
raise ValueError(f"Failed to store job in external storage: {e}")
431+
394432

395433
def get_runtime(runtime_config, **kwargs):
396434
"""Get a LAVA runtime object"""

0 commit comments

Comments
 (0)