Skip to content

Commit b2214ae

Browse files
committed
images info for release notes
1 parent 1199aab commit b2214ae

File tree

10 files changed

+360
-3
lines changed

10 files changed

+360
-3
lines changed

src/gardenlinux/github/release_notes/__init__.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
from .helpers import get_package_list
1+
from .helpers import download_all_metadata_files, get_package_list
22
from .sections import (
33
release_notes_changes_section,
44
release_notes_compare_package_versions_section,
5+
release_notes_image_ids_section,
56
release_notes_software_components_section,
67
)
78

@@ -19,7 +20,9 @@ def create_github_release_notes(gardenlinux_version, commitish):
1920
gardenlinux_version, package_list
2021
)
2122

22-
# TODO: image ids
23+
metadata_files = download_all_metadata_files(gardenlinux_version, commitish)
24+
25+
output += release_notes_image_ids_section(metadata_files)
2326

2427
output += "\n"
2528
output += "## Kernel Module Build Container (kmodbuild)"
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
from gardenlinux.constants import GARDENLINUX_GITHUB_RELEASE_BUCKET_NAME
2+
3+
4+
class DeploymentPlatform():
5+
artifacts_bucket_name = GARDENLINUX_GITHUB_RELEASE_BUCKET_NAME
6+
7+
def full_name(self):
8+
return "Generic Deployment Platform"
9+
10+
def published_images_by_regions(self, image_metadata):
11+
published_image_metadata = image_metadata["published_image_metadata"]
12+
flavor_name = image_metadata["s3_key"].split("/")[-1]
13+
14+
regions = []
15+
for pset in published_image_metadata:
16+
for p in published_image_metadata[pset]:
17+
regions.append({"region": p["region_id"], "image_id": p["image_id"]})
18+
19+
return {"flavor": flavor_name, "regions": regions}
20+
21+
def image_extension(self):
22+
return "raw"
23+
24+
def artifact_for_flavor(self, flavor):
25+
base_url = f"https://{self.__class__.artifacts_bucket_name}.s3.amazonaws.com/objects"
26+
filename = f"{flavor}.{self.image_extension()}"
27+
download_url = f"{base_url}/{flavor}/{filename}"
28+
return f"[{filename}]({download_url})"
29+
30+
def region_details(self):
31+
"""
32+
Generate the detailed region information for the collapsible section
33+
"""
34+
details = ""
35+
36+
match self.published_images_by_regions():
37+
case {"regions": regions}:
38+
for region in regions:
39+
match region:
40+
case {
41+
"region": region_name,
42+
"image_id": image_id,
43+
"image_name": image_name,
44+
}:
45+
details += f"**{region_name}:** {image_id} ({image_name})<br>"
46+
case {"region": region_name, "image_id": image_id}:
47+
details += f"**{region_name}:** {image_id}<br>"
48+
case {"details": details_dict}:
49+
for key, value in details_dict.items():
50+
details += f"**{key.replace('_', ' ').title()}:** {value}<br>"
51+
case {
52+
"gallery_images": gallery_images,
53+
"marketplace_images": marketplace_images,
54+
}:
55+
if gallery_images:
56+
details += "**Gallery Images:**<br>"
57+
for img in gallery_images:
58+
details += f"• {img['hyper_v_generation']} ({img['azure_cloud']}): {img['image_id']}<br>"
59+
if marketplace_images:
60+
details += "**Marketplace Images:**<br>"
61+
for img in marketplace_images:
62+
details += f"• {img['hyper_v_generation']}: {img['urn']}<br>"
63+
case {"gallery_images": gallery_images}:
64+
details += "**Gallery Images:**<br>"
65+
for img in gallery_images:
66+
details += f"• {img['hyper_v_generation']} ({img['azure_cloud']}): {img['image_id']}<br>"
67+
case {"marketplace_images": marketplace_images}:
68+
details += "**Marketplace Images:**<br>"
69+
for img in marketplace_images:
70+
details += f"• {img['hyper_v_generation']}: {img['urn']}<br>"
71+
72+
return details
73+
74+
def summary_text(self):
75+
"""
76+
Generate the summary text for the collapsible section
77+
"""
78+
match self.published_images_by_regions():
79+
case {"regions": regions}:
80+
count = len(regions)
81+
return f"{count} regions"
82+
case {"details": _}:
83+
return "Global availability"
84+
case {
85+
"gallery_images": gallery_images,
86+
"marketplace_images": marketplace_images,
87+
}:
88+
gallery_count = len(gallery_images)
89+
marketplace_count = len(marketplace_images)
90+
return f"{gallery_count} gallery + {marketplace_count} marketplace images"
91+
case {"gallery_images": gallery_images}:
92+
gallery_count = len(gallery_images)
93+
return f"{gallery_count} gallery images"
94+
case {"marketplace_images": marketplace_images}:
95+
marketplace_count = len(marketplace_images)
96+
return f"{marketplace_count} marketplace images"
97+
case _:
98+
return "Details available"
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
from . import DeploymentPlatform
2+
3+
4+
class AliCloud(DeploymentPlatform):
5+
def full_name(self):
6+
return "Alibaba Cloud"
7+
8+
def image_extension(self):
9+
return "qcow2"
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
from . import DeploymentPlatform
2+
3+
4+
class AmazonWebServices(DeploymentPlatform):
5+
def full_name(self):
6+
return "Amazon Web Services"
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
from . import DeploymentPlatform
2+
3+
4+
class Azure(DeploymentPlatform):
5+
def full_name(self):
6+
return "Microsoft Azure"
7+
8+
def image_extension(self):
9+
return "vhd"
10+
11+
def published_images_by_regions(self, image_metadata):
12+
published_image_metadata = image_metadata["published_image_metadata"]
13+
flavor_name = image_metadata["s3_key"].split("/")[-1]
14+
15+
gallery_images = []
16+
marketplace_images = []
17+
18+
for pset in published_image_metadata:
19+
if pset == "published_gallery_images":
20+
for gallery_image in published_image_metadata[pset]:
21+
gallery_images.append(
22+
{
23+
"hyper_v_generation": gallery_image["hyper_v_generation"],
24+
"azure_cloud": gallery_image["azure_cloud"],
25+
"image_id": gallery_image["community_gallery_image_id"],
26+
}
27+
)
28+
29+
if pset == "published_marketplace_images":
30+
for market_image in published_image_metadata[pset]:
31+
marketplace_images.append(
32+
{
33+
"hyper_v_generation": market_image["hyper_v_generation"],
34+
"urn": market_image["urn"],
35+
}
36+
)
37+
38+
return {
39+
"flavor": flavor_name,
40+
"gallery_images": gallery_images,
41+
"marketplace_images": marketplace_images,
42+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
from . import DeploymentPlatform
2+
3+
4+
class GoogleCloud(DeploymentPlatform):
5+
def full_name(self):
6+
return "Google Cloud Platform"
7+
8+
def image_extension(self):
9+
return "gcpimage.tar.gz"
10+
11+
def published_images_by_regions(self, image_metadata):
12+
published_image_metadata = image_metadata["published_image_metadata"]
13+
flavor_name = image_metadata["s3_key"].split("/")[-1]
14+
15+
details = {}
16+
if "gcp_image_name" in published_image_metadata:
17+
details["image_name"] = published_image_metadata["gcp_image_name"]
18+
if "gcp_project_name" in published_image_metadata:
19+
details["project"] = published_image_metadata["gcp_project_name"]
20+
details["availability"] = "Global (all regions)"
21+
22+
return {"flavor": flavor_name, "details": details}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
from . import DeploymentPlatform
2+
3+
4+
class OpenStack(DeploymentPlatform):
5+
def full_name(self):
6+
return "OpenStack"
7+
8+
def published_images_by_regions(self, image_metadata):
9+
published_image_metadata = image_metadata["published_image_metadata"]
10+
flavor_name = image_metadata["s3_key"].split("/")[-1]
11+
12+
regions = []
13+
if "published_openstack_images" in published_image_metadata:
14+
for image in published_image_metadata["published_openstack_images"]:
15+
regions.append(
16+
{
17+
"region": image["region_name"],
18+
"image_id": image["image_id"],
19+
"image_name": image["image_name"],
20+
}
21+
)
22+
23+
return {"flavor": flavor_name, "regions": regions}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
from .openstack import OpenStack
2+
3+
4+
class OpenStackBareMetal(OpenStack):
5+
def full_name(self):
6+
return "OpenStack Baremetal"

src/gardenlinux/github/release_notes/helpers.py

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,3 +116,51 @@ def download_metadata_file(
116116
s3_artifacts.bucket.download_file(
117117
release_object.key, artifacts_dir.joinpath(f"{cname}.s3_metadata.yaml")
118118
)
119+
120+
121+
def get_variant_from_flavor(flavor_name):
122+
"""
123+
Determine the variant from a flavor name by checking for variant suffixes.
124+
Returns the variant key (e.g., 'legacy', 'usi', 'tpm2_trustedboot').
125+
"""
126+
match flavor_name:
127+
case name if "_usi" in name:
128+
return "usi"
129+
case name if "_tpm2_trustedboot" in name:
130+
return "tpm2_trustedboot"
131+
case _:
132+
return "legacy"
133+
134+
135+
def get_platform_display_name(platform, clouds):
136+
"""
137+
Get the display name for a platform.
138+
"""
139+
match platform:
140+
case "ali" | "openstackbaremetal" | "openstack" | "azure" | "gcp" | "aws":
141+
return clouds[platform]
142+
case _:
143+
return platform.upper()
144+
145+
146+
def get_platform_release_note_data(metadata, platform):
147+
"""
148+
Get the appropriate cloud release note data based on platform.
149+
Returns the structured data dictionary.
150+
"""
151+
match platform:
152+
case "ali":
153+
return _ali_release_note(metadata)
154+
case "aws":
155+
return _aws_release_note(metadata)
156+
case "gcp":
157+
return _gcp_release_note(metadata)
158+
case "azure":
159+
return _azure_release_note(metadata)
160+
case "openstack":
161+
return _openstack_release_note(metadata)
162+
case "openstackbaremetal":
163+
return _openstackbaremetal_release_note(metadata)
164+
case _:
165+
LOGGER.error(f"unknown platform {platform}")
166+
return None

0 commit comments

Comments
 (0)