Skip to content

Commit 28a7960

Browse files
committed
refactor to work with gardenlinux 0.9.1
1 parent 3e13563 commit 28a7960

File tree

6 files changed

+265
-383
lines changed

6 files changed

+265
-383
lines changed

.gitignore

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
*.egg-info
22
**/__pycache__
3-
.artifacts_cache.json
4-
.artifacts_index.json
53
.envrc
64
.venv
75
_build
86
dist/
7+
glrd/artifacts-cache.json
98
shell.nix
109
releases.json
1110
releases.yaml

glrd/manage.py

Lines changed: 9 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,10 @@
2929
timestamp_to_isodate,
3030
get_version,
3131
NoAliasDumper,
32+
get_flavors_from_git,
33+
get_s3_artifacts_data,
34+
get_flavors_from_s3_artifacts,
3235
)
33-
from python_gardenlinux_lib.flavors.parse_flavors import (
34-
parse_flavors_commit,
35-
)
36-
from python_gardenlinux_lib.s3.s3 import get_s3_artifacts, get_s3_client
3736

3837
# silence boto3 logging
3938
boto3.set_stream_logger(name="botocore.credentials", level=logging.ERROR)
@@ -643,29 +642,21 @@ def create_single_release(release_type, args, existing_releases):
643642
# Create version object
644643
version = {"major": major, "minor": minor, "patch": patch}
645644

646-
# First try to get flavors from flavors.yaml
647-
flavors = parse_flavors_commit(
648-
commit, version=version, query_s3=False, logger=logging.getLogger()
649-
)
645+
flavors = get_flavors_from_git(commit)
650646

651647
# Only if no flavors found in flavors.yaml, try S3
652648
if not flavors:
653649
logging.info("No flavors found in flavors.yaml, checking S3 artifacts...")
654650
# Get artifacts data from S3 with caching
655-
artifacts_data = get_s3_artifacts(
651+
# Get S3 artifacts using gardenlinux library
652+
artifacts_data = get_s3_artifacts_data(
656653
DEFAULTS["ARTIFACTS_S3_BUCKET_NAME"],
657654
DEFAULTS["ARTIFACTS_S3_PREFIX"],
658-
logger=logging.getLogger(),
655+
DEFAULTS["ARTIFACTS_S3_CACHE_FILE"],
659656
)
660657

661658
if artifacts_data:
662-
flavors = parse_flavors_commit(
663-
commit,
664-
version=version,
665-
query_s3=True,
666-
s3_objects=artifacts_data,
667-
logger=logging.getLogger(),
668-
)
659+
flavors = get_flavors_from_s3_artifacts(artifacts_data, version, commit)
669660
else:
670661
logging.warning("No artifacts data available from S3")
671662

@@ -1207,7 +1198,7 @@ def merge_existing_s3_data(bucket_name, bucket_key, local_file, new_data):
12071198

12081199
def download_all_s3_files(bucket_name, bucket_prefix):
12091200
"""Download all release files from S3 bucket."""
1210-
s3_client = get_s3_client()
1201+
s3_client = boto3.client("s3")
12111202

12121203
try:
12131204
# List all objects in the bucket with the given prefix

glrd/update.py

Lines changed: 20 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,14 @@
77
import boto3
88

99
from glrd.manage import download_all_s3_files, upload_all_local_files
10-
from glrd.util import DEFAULTS, ERROR_CODES, get_version
11-
12-
from python_gardenlinux_lib.flavors.parse_flavors import parse_flavors_commit
13-
from python_gardenlinux_lib.s3.s3 import get_s3_artifacts
10+
from glrd.util import (
11+
DEFAULTS,
12+
ERROR_CODES,
13+
get_version,
14+
get_flavors_from_git,
15+
get_s3_artifacts_data,
16+
get_flavors_from_s3_artifacts,
17+
)
1418

1519
logger = logging.getLogger(__name__)
1620

@@ -168,30 +172,23 @@ def update_flavors(release):
168172
commit = release["git"]["commit"]
169173
version = release["version"]
170174

171-
# First try flavors.yaml
172-
flavors = parse_flavors_commit(
173-
commit, version=version, query_s3=False, logger=logger
174-
)
175+
# First try flavors.yaml using gardenlinux library
176+
flavors = get_flavors_from_git(commit)
175177

176178
# If no flavors found, try S3
177179
if not flavors:
178180
logger.info(
179181
f"No flavors found in flavors.yaml for {release['name']}, checking S3..."
180182
)
181-
artifacts_data = get_s3_artifacts(
183+
# Get S3 artifacts using gardenlinux library
184+
artifacts_data = get_s3_artifacts_data(
182185
DEFAULTS["ARTIFACTS_S3_BUCKET_NAME"],
183186
DEFAULTS["ARTIFACTS_S3_PREFIX"],
184-
logger=logger,
187+
DEFAULTS["ARTIFACTS_S3_CACHE_FILE"],
185188
)
186189

187190
if artifacts_data:
188-
flavors = parse_flavors_commit(
189-
commit,
190-
version=version,
191-
query_s3=True,
192-
s3_objects=artifacts_data,
193-
logger=logger,
194-
)
191+
flavors = get_flavors_from_s3_artifacts(artifacts_data, version, commit)
195192
else:
196193
logger.warning(f"No artifacts data available from S3 for {release['name']}")
197194

@@ -291,8 +288,11 @@ def process_releases(args):
291288
logging.info(
292289
f"Fetching artifacts data from S3 bucket {DEFAULTS['ARTIFACTS_S3_BUCKET_NAME']}"
293290
)
294-
artifacts_data = get_s3_artifacts(
295-
DEFAULTS["ARTIFACTS_S3_BUCKET_NAME"], DEFAULTS["ARTIFACTS_S3_PREFIX"]
291+
# Get S3 artifacts using gardenlinux library
292+
artifacts_data = get_s3_artifacts_data(
293+
DEFAULTS["ARTIFACTS_S3_BUCKET_NAME"],
294+
DEFAULTS["ARTIFACTS_S3_PREFIX"],
295+
DEFAULTS["ARTIFACTS_S3_CACHE_FILE"],
296296
)
297297

298298
if not artifacts_data or not artifacts_data.get("artifacts"):
@@ -400,12 +400,7 @@ def process_releases(args):
400400
update_source_repo_attribute([release])
401401

402402
# Get flavors for this commit using artifacts data
403-
flavors = parse_flavors_commit(
404-
commit,
405-
version=version,
406-
query_s3=True,
407-
s3_objects=artifacts_data,
408-
)
403+
flavors = get_flavors_from_s3_artifacts(artifacts_data, version, commit)
409404
if flavors:
410405
release["flavors"] = flavors
411406
modified = True

glrd/util.py

Lines changed: 150 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,22 @@
1+
import importlib.metadata
12
import logging
23
import os
34
import re
45
import signal
56
import sys
67
from datetime import datetime
8+
from pathlib import Path
9+
from tempfile import TemporaryDirectory
10+
from typing import Any, Dict, List, Optional
711

8-
import importlib.metadata
912
import pytz
1013
import yaml
14+
from git import Repo
15+
16+
from gardenlinux.constants import GL_REPOSITORY_URL
17+
from gardenlinux.flavors import Parser
18+
from gardenlinux.s3 import Bucket
19+
1120

1221
ERROR_CODES = {
1322
"validation_error": 1,
@@ -50,6 +59,7 @@
5059
"ARTIFACTS_S3_BUCKET_NAME": "gardenlinux-github-releases",
5160
"ARTIFACTS_S3_PREFIX": "objects/",
5261
"ARTIFACTS_S3_BASE_URL": ("https://gardenlinux-github-releases.s3.amazonaws.com"),
62+
"ARTIFACTS_S3_CACHE_FILE": "artifacts-cache.json",
5363
# Garden Linux repository
5464
"GL_REPO_NAME": "gardenlinux",
5565
"GL_REPO_OWNER": "gardenlinux",
@@ -144,3 +154,142 @@ def ignore_aliases(self, data):
144154

145155

146156
signal.signal(signal.SIGPIPE, handle_broken_pipe_error)
157+
158+
159+
def get_flavors_from_git(commit: str) -> List[str]:
160+
"""
161+
Get flavors from Git repository using gardenlinux library.
162+
163+
Args:
164+
commit: Git commit hash (or 'latest')
165+
166+
Returns:
167+
List of flavor strings
168+
"""
169+
170+
try:
171+
with TemporaryDirectory() as git_directory:
172+
repo = Repo.clone_from(
173+
GL_REPOSITORY_URL, git_directory, no_origin=True, sparse=True
174+
)
175+
176+
# Checkout specific commit if provided
177+
if commit and commit != "latest":
178+
repo.git.checkout(commit)
179+
180+
flavors_file = Path(repo.working_dir, "flavors.yaml")
181+
if flavors_file.exists():
182+
with flavors_file.open("r") as fp:
183+
flavors_data = fp.read()
184+
flavors_yaml = yaml.safe_load(flavors_data)
185+
parser = Parser(flavors_yaml)
186+
combinations = parser.filter()
187+
all_flavors = set(combination for _, combination in combinations)
188+
flavors = sorted(all_flavors)
189+
logging.info(f"Found {len(flavors)} flavors in Git")
190+
return flavors
191+
else:
192+
logging.warning("flavors.yaml not found in repository")
193+
return []
194+
except Exception as exc:
195+
logging.debug(f"Could not get flavors from Git: {exc}")
196+
return []
197+
198+
199+
def get_s3_artifacts_data(
200+
bucket_name: str,
201+
prefix: str,
202+
cache_file: Optional[str] = None,
203+
cache_ttl: int = 3600,
204+
) -> Optional[Dict]:
205+
"""
206+
Get S3 artifacts data using gardenlinux library with caching support.
207+
208+
Args:
209+
bucket_name: S3 bucket name
210+
prefix: S3 prefix
211+
cache_file: Optional cache file path for S3 object keys
212+
cache_ttl: Cache time-to-live in seconds (default: 1 hour)
213+
214+
Returns:
215+
Dictionary containing S3 artifacts data with 'index' and 'artifacts' keys
216+
"""
217+
218+
try:
219+
bucket = Bucket(bucket_name)
220+
221+
artifacts = bucket.read_cache_file_or_filter(
222+
cache_file, cache_ttl=cache_ttl, Prefix=prefix
223+
)
224+
225+
index = {}
226+
for key in artifacts:
227+
try:
228+
parts = key.split("/")
229+
if len(parts) >= 3:
230+
version_commit = parts[1]
231+
if "-" in version_commit:
232+
version_part, commit_part = version_commit.split("-", 1)
233+
if version_part not in index:
234+
index[version_part] = []
235+
index[version_part].append(key)
236+
except Exception as e:
237+
logging.debug(f"Could not parse version from key {key}: {e}")
238+
239+
result = {"index": index, "artifacts": artifacts}
240+
logging.info(f"Found {len(artifacts)} artifacts and {len(index)} index entries")
241+
return result
242+
except Exception as e:
243+
logging.error(f"Error getting S3 artifacts: {e}")
244+
return None
245+
246+
247+
def get_flavors_from_s3_artifacts(
248+
artifacts_data: Dict, version: Dict[str, Any], commit: str
249+
) -> List[str]:
250+
"""
251+
Extract flavors from S3 artifacts data.
252+
253+
Args:
254+
artifacts_data: S3 artifacts data dictionary
255+
version: Version dictionary with major, minor, micro
256+
commit: Git commit hash
257+
258+
Returns:
259+
List of flavor strings
260+
"""
261+
262+
try:
263+
version_info = f"{version['major']}.{version.get('minor', 0)}"
264+
commit_short = commit[:8]
265+
266+
# Try index lookup first
267+
search_key = f"{version_info}-{commit_short}"
268+
if search_key in artifacts_data.get("index", {}):
269+
flavors = artifacts_data["index"][search_key]
270+
logging.debug(f"Found flavors in S3 index for {search_key}")
271+
return flavors
272+
else:
273+
# Search through artifacts
274+
found_flavors = set()
275+
for key in artifacts_data.get("artifacts", []):
276+
if version_info in key and commit_short in key:
277+
try:
278+
parts = key.split("/")
279+
if len(parts) >= 2:
280+
flavor_with_version = parts[1]
281+
flavor = flavor_with_version.rsplit(f"-{version_info}", 1)[
282+
0
283+
]
284+
if flavor:
285+
found_flavors.add(flavor)
286+
except Exception as e:
287+
logging.debug(f"Error parsing artifact key {key}: {e}")
288+
continue
289+
flavors = sorted(found_flavors)
290+
if flavors:
291+
logging.info(f"Found {len(flavors)} flavors in S3 artifacts")
292+
return flavors
293+
except Exception as e:
294+
logging.error(f"Error processing S3 artifacts: {e}")
295+
return []

0 commit comments

Comments
 (0)