Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -169,3 +169,6 @@ bandit-report.json

# zot
test-data/zot

s3_downloads/
.github_release_id
3 changes: 2 additions & 1 deletion src/gardenlinux/github/__main__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import argparse

from gardenlinux.constants import GARDENLINUX_GITHUB_RELEASE_BUCKET_NAME
from gardenlinux.logger import LoggerSetup

from .release import create_github_release, upload_to_github_release_page, write_to_release_id_file
Expand Down Expand Up @@ -30,7 +31,7 @@ def main():
args = parser.parse_args()

if args.command == "create":
body = create_github_release_notes(args.tag, args.commit)
body = create_github_release_notes(args.tag, args.commit, GARDENLINUX_GITHUB_RELEASE_BUCKET_NAME)
if args.dry_run:
print("Dry Run ...")
print("This release would be created:")
Expand Down
9 changes: 6 additions & 3 deletions src/gardenlinux/github/release_notes/__init__.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
from .helpers import get_package_list
from .helpers import download_all_metadata_files, get_package_list
from .sections import (
release_notes_changes_section,
release_notes_compare_package_versions_section,
release_notes_image_ids_section,
release_notes_software_components_section,
)


def create_github_release_notes(gardenlinux_version, commitish):
def create_github_release_notes(gardenlinux_version, commitish, releases_s3_bucket_name):
package_list = get_package_list(gardenlinux_version)

output = ""
Expand All @@ -19,7 +20,9 @@ def create_github_release_notes(gardenlinux_version, commitish):
gardenlinux_version, package_list
)

# TODO: image ids
metadata_files = download_all_metadata_files(gardenlinux_version, commitish, releases_s3_bucket_name)

output += release_notes_image_ids_section(metadata_files)

output += "\n"
output += "## Kernel Module Build Container (kmodbuild)"
Expand Down
104 changes: 104 additions & 0 deletions src/gardenlinux/github/release_notes/deployment_platform/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
from gardenlinux.constants import GARDENLINUX_GITHUB_RELEASE_BUCKET_NAME


class DeploymentPlatform():
artifacts_bucket_name = GARDENLINUX_GITHUB_RELEASE_BUCKET_NAME

def short_name(self):
return "generic"

def full_name(self):
return "Generic Deployment Platform"

def published_images_by_regions(self, image_metadata):
published_image_metadata = image_metadata["published_image_metadata"]
flavor_name = image_metadata["s3_key"].split("/")[-1]

regions = []
for pset in published_image_metadata:
for p in published_image_metadata[pset]:
regions.append({"region": p["region_id"], "image_id": p["image_id"]})

return {"flavor": flavor_name, "regions": regions}

def image_extension(self):
return "raw"

def artifact_for_flavor(self, flavor, markdown_format=True):
base_url = f"https://{self.__class__.artifacts_bucket_name}.s3.amazonaws.com/objects"
filename = f"{flavor}.{self.image_extension()}"
download_url = f"{base_url}/{flavor}/{filename}"
if markdown_format:
return f"[{filename}]({download_url})"
else:
return download_url

def region_details(self, image_metadata):
"""
Generate the detailed region information for the collapsible section
"""
details = ""

match self.published_images_by_regions(image_metadata):
case {"regions": regions}:
for region in regions:
match region:
case {
"region": region_name,
"image_id": image_id,
"image_name": image_name,
}:
details += f"**{region_name}:** {image_id} ({image_name})<br>"
case {"region": region_name, "image_id": image_id}:
details += f"**{region_name}:** {image_id}<br>"
case {"details": details_dict}:
for key, value in details_dict.items():
details += f"**{key.replace('_', ' ').title()}:** {value}<br>"
case {
"gallery_images": gallery_images,
"marketplace_images": marketplace_images,
}:
if gallery_images:
details += "**Gallery Images:**<br>"
for img in gallery_images:
details += f"• {img['hyper_v_generation']} ({img['azure_cloud']}): {img['image_id']}<br>"
if marketplace_images:
details += "**Marketplace Images:**<br>"
for img in marketplace_images:
details += f"• {img['hyper_v_generation']}: {img['urn']}<br>"
case {"gallery_images": gallery_images}:
details += "**Gallery Images:**<br>"
for img in gallery_images:
details += f"• {img['hyper_v_generation']} ({img['azure_cloud']}): {img['image_id']}<br>"
case {"marketplace_images": marketplace_images}:
details += "**Marketplace Images:**<br>"
for img in marketplace_images:
details += f"• {img['hyper_v_generation']}: {img['urn']}<br>"

return details

def summary_text(self, image_metadata):
"""
Generate the summary text for the collapsible section
"""
match self.published_images_by_regions(image_metadata):
case {"regions": regions}:
count = len(regions)
return f"{count} regions"
case {"details": _}:
return "Global availability"
case {
"gallery_images": gallery_images,
"marketplace_images": marketplace_images,
}:
gallery_count = len(gallery_images)
marketplace_count = len(marketplace_images)
return f"{gallery_count} gallery + {marketplace_count} marketplace images"
case {"gallery_images": gallery_images}:
gallery_count = len(gallery_images)
return f"{gallery_count} gallery images"
case {"marketplace_images": marketplace_images}:
marketplace_count = len(marketplace_images)
return f"{marketplace_count} marketplace images"
case _:
return "Details available"
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from . import DeploymentPlatform


class AliCloud(DeploymentPlatform):
def short_name(self):
return "ali"

def full_name(self):
return "Alibaba Cloud"

def image_extension(self):
return "qcow2"
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
from . import DeploymentPlatform


class AmazonWebServices(DeploymentPlatform):
def short_name(self):
return "aws"

def full_name(self):
return "Amazon Web Services"

def published_images_by_regions(self, image_metadata):
published_image_metadata = image_metadata["published_image_metadata"]
flavor_name = image_metadata["s3_key"].split("/")[-1]

regions = []
for pset in published_image_metadata:
for p in published_image_metadata[pset]:
regions.append({"region": p["aws_region_id"], "image_id": p["ami_id"]})

return {"flavor": flavor_name, "regions": regions}
45 changes: 45 additions & 0 deletions src/gardenlinux/github/release_notes/deployment_platform/azure.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
from . import DeploymentPlatform


class Azure(DeploymentPlatform):
def short_name(self):
return "azure"

def full_name(self):
return "Microsoft Azure"

def image_extension(self):
return "vhd"

def published_images_by_regions(self, image_metadata):
published_image_metadata = image_metadata["published_image_metadata"]
flavor_name = image_metadata["s3_key"].split("/")[-1]

gallery_images = []
marketplace_images = []

for pset in published_image_metadata:
if pset == "published_gallery_images":
for gallery_image in published_image_metadata[pset]:
gallery_images.append(
{
"hyper_v_generation": gallery_image["hyper_v_generation"],
"azure_cloud": gallery_image["azure_cloud"],
"image_id": gallery_image["community_gallery_image_id"],
}
)

if pset == "published_marketplace_images":
for market_image in published_image_metadata[pset]:
marketplace_images.append(
{
"hyper_v_generation": market_image["hyper_v_generation"],
"urn": market_image["urn"],
}
)

return {
"flavor": flavor_name,
"gallery_images": gallery_images,
"marketplace_images": marketplace_images,
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
from . import DeploymentPlatform


class GoogleCloud(DeploymentPlatform):
def short_name(self):
return "gcp"

def full_name(self):
return "Google Cloud Platform"

def image_extension(self):
return "gcpimage.tar.gz"

def published_images_by_regions(self, image_metadata):
published_image_metadata = image_metadata["published_image_metadata"]
flavor_name = image_metadata["s3_key"].split("/")[-1]

details = {}
if "gcp_image_name" in published_image_metadata:
details["image_name"] = published_image_metadata["gcp_image_name"]
if "gcp_project_name" in published_image_metadata:
details["project"] = published_image_metadata["gcp_project_name"]
details["availability"] = "Global (all regions)"

return {"flavor": flavor_name, "details": details}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
from . import DeploymentPlatform


class OpenStack(DeploymentPlatform):
def short_name(self):
return "openstack"

def full_name(self):
return "OpenStack"

def published_images_by_regions(self, image_metadata):
published_image_metadata = image_metadata["published_image_metadata"]
flavor_name = image_metadata["s3_key"].split("/")[-1]

regions = []
if "published_openstack_images" in published_image_metadata:
for image in published_image_metadata["published_openstack_images"]:
regions.append(
{
"region": image["region_name"],
"image_id": image["image_id"],
"image_name": image["image_name"],
}
)

return {"flavor": flavor_name, "regions": regions}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from .openstack import OpenStack


class OpenStackBareMetal(OpenStack):
def short_name(self):
return "openstackbaremetal"

def full_name(self):
return "OpenStack Baremetal"
19 changes: 16 additions & 3 deletions src/gardenlinux/github/release_notes/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
from gardenlinux.apt import DebsrcFile, GardenLinuxRepo
from gardenlinux.apt.package_repo_info import compare_repo
from gardenlinux.constants import (
GARDENLINUX_GITHUB_RELEASE_BUCKET_NAME,
GL_DEB_REPO_BASE_URL,
IMAGE_VARIANTS,
REQUESTS_TIMEOUTS,
Expand Down Expand Up @@ -49,7 +48,7 @@ def compare_apt_repo_versions(previous_version, current_version):
return output


def download_all_metadata_files(version, commitish):
def download_all_metadata_files(version, commitish, s3_bucket_name):
repo = Repo(".")
commit = repo.commit(commitish)
flavors_data = commit.tree["flavors.yaml"].data_stream.read().decode("utf-8")
Expand All @@ -60,7 +59,7 @@ def download_all_metadata_files(version, commitish):
shutil.rmtree(local_dest_path)
local_dest_path.mkdir(mode=0o755, exist_ok=False)

s3_artifacts = S3Artifacts(GARDENLINUX_GITHUB_RELEASE_BUCKET_NAME)
s3_artifacts = S3Artifacts(s3_bucket_name)

commitish_short = commitish[:8]

Expand Down Expand Up @@ -116,3 +115,17 @@ def download_metadata_file(
s3_artifacts.bucket.download_file(
release_object.key, artifacts_dir.joinpath(f"{cname}.s3_metadata.yaml")
)


def get_variant_from_flavor(flavor_name):
"""
Determine the variant from a flavor name by checking for variant suffixes.
Returns the variant key (e.g., 'legacy', 'usi', 'tpm2_trustedboot').
"""
match flavor_name:
case name if "_usi" in name:
return "usi"
case name if "_tpm2_trustedboot" in name:
return "tpm2_trustedboot"
case _:
return "legacy"
Loading
Loading