diff --git a/asciidoc/components/system-upgrade-controller.adoc b/asciidoc/components/system-upgrade-controller.adoc index 6d4b9e79..ec9aa381 100644 --- a/asciidoc/components/system-upgrade-controller.adoc +++ b/asciidoc/components/system-upgrade-controller.adoc @@ -165,14 +165,14 @@ Make sure that the version of the fleet-cli you download matches the version of + [,bash,subs="attributes"] ---- -curl -L -o fleet-cli https://github.com/rancher/fleet/releases/download/v{version-fleet}/fleet-linux-amd64 +curl -L -o fleet-cli https://github.com/rancher/fleet/releases/download/{version-fleet}/fleet-linux-amd64 ---- *** Linux ARM: + [,bash,subs="attributes"] ---- -curl -L -o fleet-cli https://github.com/rancher/fleet/releases/download/v{version-fleet}/fleet-linux-arm64 +curl -L -o fleet-cli https://github.com/rancher/fleet/releases/download/{version-fleet}/fleet-linux-arm64 ---- . Make `fleet-cli` executable: diff --git a/asciidoc/concepts/observability.adoc b/asciidoc/concepts/observability.adoc deleted file mode 100644 index 46097c4a..00000000 --- a/asciidoc/concepts/observability.adoc +++ /dev/null @@ -1,16 +0,0 @@ -[#concepts-observability] -= Observability -:revdate: 2024-03-06 -:page-revdate: {revdate} -:experimental: - -ifdef::env-github[] -:imagesdir: ../images/ -:tip-caption: :bulb: -:note-caption: :information_source: -:important-caption: :heavy_exclamation_mark: -:caution-caption: :fire: -:warning-caption: :warning: -endif::[] - -Coming soon diff --git a/asciidoc/concepts/terms.adoc b/asciidoc/concepts/terms.adoc deleted file mode 100644 index 0fafa9f1..00000000 --- a/asciidoc/concepts/terms.adoc +++ /dev/null @@ -1,21 +0,0 @@ -[glossary] -= Terminology -:revdate: 2024-03-06 -:page-revdate: {revdate} -:experimental: - -ifdef::env-github[] -:imagesdir: ../images/ -:tip-caption: :bulb: -:note-caption: :information_source: -:important-caption: :heavy_exclamation_mark: -:caution-caption: :fire: -:warning-caption: :warning: -endif::[] - -There is a lot of terminology used in this space. Let's keep track of what means what. - -Kubernetes:: TBD -Container:: TBD -Cluster API:: TBD - diff --git a/asciidoc/day2/fleet-helm-upgrade.adoc b/asciidoc/day2/fleet-helm-upgrade.adoc index 9b6df483..379af08c 100644 --- a/asciidoc/day2/fleet-helm-upgrade.adoc +++ b/asciidoc/day2/fleet-helm-upgrade.adoc @@ -28,7 +28,7 @@ Depending on what your environment supports, you can take one of the following o . Host your chart's Fleet resources on a local Git server that is accessible by your `management cluster`. -. Use Fleet's CLI to link:https://fleet.rancher.io/bundle-add#convert-a-helm-chart-into-a-bundle[convert a Helm chart into a Bundle] that you can directly use and will not need to be hosted somewhere. Fleet's CLI can be retrieved from their link:https://github.com/rancher/fleet/releases/tag/v{version-fleet}[release] page, for Mac users there is a link:https://formulae.brew.sh/formula/fleet-cli[fleet-cli] Homebrew Formulae. +. Use Fleet's CLI to link:https://fleet.rancher.io/bundle-add#convert-a-helm-chart-into-a-bundle[convert a Helm chart into a Bundle] that you can directly use and will not need to be hosted somewhere. Fleet's CLI can be retrieved from their link:https://github.com/rancher/fleet/releases/tag/{version-fleet}[release] page, for Mac users there is a link:https://formulae.brew.sh/formula/fleet-cli[fleet-cli] Homebrew Formulae. ==== Find the required assets for your Edge release version @@ -418,7 +418,7 @@ endif::[] + [NOTE] ==== -Fleet's CLI can be retrieved from their link:https://github.com/rancher/fleet/releases/tag/v{version-fleet}[release] *Assets* page (`fleet-linux-amd64`). +Fleet's CLI can be retrieved from their link:https://github.com/rancher/fleet/releases/tag/{version-fleet}[release] *Assets* page (`fleet-linux-amd64`). For Mac users there is a link:https://formulae.brew.sh/formula/fleet-cli[fleet-cli] Homebrew Formulae. ==== @@ -593,7 +593,7 @@ Make sure that the Fleet includes the changes that have been made by the `genera . For an environment that does not support GitOps (e.g. is air-gapped and does not allow local Git server usage): -.. Download the `fleet-cli` binary from the `rancher/fleet` link:https://github.com/rancher/fleet/releases/tag/v{version-fleet}[release] page (`fleet-linux-amd64` for Linux). For Mac users, there is a Homebrew Formulae that can be used - link:https://formulae.brew.sh/formula/fleet-cli[fleet-cli]. +.. Download the `fleet-cli` binary from the `rancher/fleet` link:https://github.com/rancher/fleet/releases/tag/{version-fleet}[release] page (`fleet-linux-amd64` for Linux). For Mac users, there is a Homebrew Formulae that can be used - link:https://formulae.brew.sh/formula/fleet-cli[fleet-cli]. .. Navigate to the `eib-charts-upgrader` Fleet: + diff --git a/asciidoc/edge-book/edge.adoc b/asciidoc/edge-book/edge.adoc index f9d4ced5..ba0f86de 100755 --- a/asciidoc/edge-book/edge.adoc +++ b/asciidoc/edge-book/edge.adoc @@ -146,8 +146,6 @@ include::../tips/metal3.adoc[leveloffset=+1] [partintro] How to integrate third-party tools -// include::../integrations/linkerd.adoc[leveloffset=+1] - include::../integrations/nats.adoc[leveloffset=+1] include::../integrations/nvidia-slemicro.adoc[leveloffset=+1] @@ -227,12 +225,3 @@ include::../troubleshooting/collecting-diagnostics-for-support.adoc[] include::./releasenotes.adoc[leveloffset=+2] -// include::./version-matrix.adoc[leveloffset=+2] - -// Additional information - -// include::../concepts/observability.adoc[leveloffset=+2] - -// include::../concepts/terms.adoc[leveloffset=+2] - - diff --git a/asciidoc/edge-book/version-matrix.adoc b/asciidoc/edge-book/version-matrix.adoc deleted file mode 100644 index 68899ce9..00000000 --- a/asciidoc/edge-book/version-matrix.adoc +++ /dev/null @@ -1,40 +0,0 @@ -[#component-version-matrix] -= Component Versions -:revdate: 2025-09-17 -:page-revdate: {revdate} -:experimental: - -ifdef::env-github[] -:imagesdir: ../images/ -:tip-caption: :bulb: -:note-caption: :information_source: -:important-caption: :heavy_exclamation_mark: -:caution-caption: :fire: -:warning-caption: :warning: -endif::[] - - -.Supported Component Versions -[options="header"] -|====== -| Name | Version | Chart Version -| SUSE Linux Micro | {version-operatingsystem} | N/A -| Rancher Prime | {version-rancher-prime} | {version-rancher-prime} -| Fleet | {version-fleet} | {version-fleet-chart} -| K3s | {version-kubernetes-k3s} | N/A -| RKE2 | {version-kubernetes-rke2} | N/A -| Metal^3^ | {version-metal3-chart} | {version-metal3-chart} -| MetalLB | {version-metallb-chart} | {version-metallb-chart} -| Elemental | {version-elemental-operator} | {version-elemental-operator-chart} -| Edge Image Builder | {version-eib} | N/A -| NM Configurator | {version-nm-configurator} | N/A -| SUSE Storage | {version-longhorn} | {version-longhorn-chart} -| SUSE Security| {version-neuvector} | {version-neuvector-chart} -| KubeVirt | {version-kubevirt} | {version-kubevirt-chart} -| Containerized Data Importer | {version-cdi} | {version-cdi-chart} -| KubeVirt Dashboard Extension | {version-kubevirt-dashboard-extension-chart} | {version-kubevirt-dashboard-extension-chart} -| Endpoint Copier Operator | {version-endpoint-copier-operator} | {version-endpoint-copier-operator-chart} -| SR-IOV | {version-sriov-network-operator-chart} | {version-sriov-network-operator-chart} -| Akri Dashboard Extension | {version-akri-dashboard-extension-chart} | {version-akri-dashboard-extension-chart} -| Akri (Tech Preview) | latest | latest -|====== diff --git a/asciidoc/edge-book/versions.adoc b/asciidoc/edge-book/versions.adoc index 5faab71d..95b06a74 100644 --- a/asciidoc/edge-book/versions.adoc +++ b/asciidoc/edge-book/versions.adoc @@ -1,5 +1,7 @@ +// NOTE - Generated by versions.adoc.j2, do not modify versions.adoc directly! + // ============================================================================ -:revdate: 2026-01-13 +:revdate: 2026-03-23 :page-revdate: {revdate} // Automatic Version Substitutions // @@ -17,7 +19,7 @@ :version-mlm: 5.0.6 // == Edge Image Builder == -:version-eib: 1.3.2 +:version-eib: 1.3.3 :version-eib-api-latest: 1.3 // KubeVirt @@ -27,16 +29,15 @@ :version-kubevirt-release: v0.6.0 // == Component Versions == -:version-rancher-prime: 2.13.1 +:version-rancher-prime: 2.13.3 :version-cert-manager: 1.19.2 -:version-elemental-operator: 1.8.0 -:version-longhorn: 1.10.1 +:version-elemental-operator: 1.8.1 +:version-longhorn: 1.10.2 :version-neuvector: 5.4.8 -:version-kubevirt: 1.5.2 +:version-kubevirt: 0.6.0 :version-endpoint-copier-operator: 0.3.0 -:version-suc: 0.17.0 -:version-nm-configurator: 0.3.5 -:version-fleet: 0.14.1 +:version-suc: v0.17.0 +:version-fleet: v0.14.3 :version-cdi: 0.6.0 :version-nvidia-device-plugin: 0.14.5 :version-kiwi-builder: 10.2.29.1 @@ -46,15 +47,14 @@ // == Non-Release Manifest Charts == :version-suc-chart: 108.0.0 -:version-upgrade-controller-chart: 305.0.3+up0.1.3 +:version-upgrade-controller-chart: 305.0.3_up0.1.3 :version-nvidia-device-plugin-chart: v0.14.5 // == Release Tags == :release-tag-eib: release-1.3 -:release-tag-edge-charts: release-3.5 :release-tag-telco-cloud: release-3.5 -:release-tag-fleet-examples: release-3.5.0 -:release-tag-rancher: v2.13.1 +:release-tag-fleet-examples: release-3.5.1 +:release-tag-rancher: v2.13.3 // ============================================================================ @@ -64,29 +64,23 @@ // and should not be renamed without thinking through the implications. // ============================================================================ -:version-kubernetes-k3s: v1.34.2+k3s1 -:version-kubernetes-rke2: v1.34.2+rke2r1 +:version-kubernetes-k3s: v1.34.4+k3s1 +:version-kubernetes-rke2: v1.34.4+rke2r1 :version-operatingsystem: 6.2 -:version-akri-chart: 305.0.0+up0.12.20 -:version-akri-dashboard-extension-chart: 305.0.4+up1.3.2 :version-cdi-chart: 305.0.1+up0.6.0 -:version-elemental-operator-chart: 1.8.0 -:version-elemental-operator-crds-chart: 1.8.0 :version-endpoint-copier-operator-chart: 305.0.1+up0.3.0 -:version-fleet-chart: 108.0.1+up0.14.1 :version-kubevirt-chart: 305.0.1+up0.6.0 :version-kubevirt-dashboard-extension-chart: 305.0.4+up1.3.3 -:version-longhorn-chart: 1.10.1 -:version-longhorn-docs: 1.10.1 -:version-metal3-chart: 305.0.21+up0.13.0 +:version-longhorn-chart: 1.10.2 +:version-longhorn-crd-chart: +:version-longhorn-docs: 1.10.2 +:version-metal3-chart: 305.0.23+up0.13.1 :version-metallb-chart: 305.0.1+up0.15.2 -:version-neuvector-chart: 108.0.1+up2.8.10 -:version-neuvector-crd-chart: 108.0.1+up2.8.10 -:version-neuvector-dashboard-extension-chart: 2.1.5 -:version-rancher-chart: 2.13.1 -:version-rancher-turtles-providers-chart: 305.0.4+up0.25.1 +:version-neuvector-chart: 108.0.2+up2.8.11 +:version-neuvector-crd-chart: 108.0.2+up2.8.11 +:version-rancher-turtles-providers-chart: 305.0.5+up0.25.4 :version-sriov-crd-chart: 305.0.4+up1.6.0 :version-sriov-network-operator-chart: 305.0.4+up1.6.0 :version-sriov-upstream: 1.6.0 diff --git a/asciidoc/edge-book/versions.adoc.j2 b/asciidoc/edge-book/versions.adoc.j2 new file mode 100644 index 00000000..d541c358 --- /dev/null +++ b/asciidoc/edge-book/versions.adoc.j2 @@ -0,0 +1,147 @@ +// NOTE - Generated by versions.adoc.j2, do not modify versions.adoc directly! +{% set release_manifest_edge_version = spec.releaseVersion %} +{%- set release_manifest_edge_version_short = spec.releaseVersion.split(".")[:2] | join(".") %} +{%- set release_manifest_rke2_version = spec.components.kubernetes.rke2.version %} +{%- set release_manifest_k3s_version = spec.components.kubernetes.k3s.version %} +{%- set release_manifest_slmicro_version = spec.components.operatingSystem.version %} +{%- set release_manifest_rancher_version = spec.components.workloads.helm | selectattr("releaseName", "equalto", "rancher") | map(attribute="version") | list | first %} +{%- set release_manifest_longhorn_version = spec.components.workloads.helm | selectattr("releaseName", "equalto", "longhorn") | map(attribute="version") | list | first %} +{%- set release_manifest_longhorn_crd_version = spec.components.workloads.helm | selectattr("releaseName", "equalto", "longhorn") | map(attribute="dependencyCharts") | first | map(attribute="version") | list | first %} +{%- set release_manifest_neuvector_version = spec.components.workloads.helm | selectattr("releaseName", "equalto", "neuvector") | map(attribute="version") | list | first %} +{%- set release_manifest_neuvector_crd_version = spec.components.workloads.helm | selectattr("releaseName", "equalto", "neuvector") | map(attribute="dependencyCharts") | first | map(attribute="version") | list | first %} +{%- set release_manifest_neuvector_dashboard_version = spec.components.workloads.helm | selectattr("releaseName", "equalto", "neuvector") | map(attribute="addonCharts") | first | map(attribute="version") | list | first %} +{%- set release_manifest_chart_major = release_manifest_edge_version_short | replace(".", "0") %} +{%- set release_manifest_metallb_version = spec.components.workloads.helm | selectattr("releaseName", "equalto", "metallb") | map(attribute="version") | list | first %} +{%- set release_manifest_eco_version = spec.components.workloads.helm | selectattr("releaseName", "equalto", "endpoint-copier-operator") | map(attribute="version") | list | first %} +{%- set release_manifest_cdi_version = spec.components.workloads.helm | selectattr("releaseName", "equalto", "cdi") | map(attribute="version") | list | first %} +{%- set release_manifest_akri_version = spec.components.workloads.helm | selectattr("releaseName", "equalto", "akri") | map(attribute="version") | list | first %} +{%- set release_manifest_akri_dashboard_version = spec.components.workloads.helm | selectattr("releaseName", "equalto", "akri") | map(attribute="addonCharts") | first | map(attribute="version") | list | first %} +{%- set release_manifest_metal3_version = spec.components.workloads.helm | selectattr("releaseName", "equalto", "metal3") | map(attribute="version") | list | first %} +{%- set release_manifest_kubevirt_version = spec.components.workloads.helm | selectattr("releaseName", "equalto", "kubevirt") | map(attribute="version") | list | first %} +{%- set release_manifest_kubevirt_dashboard_version = spec.components.workloads.helm | selectattr("releaseName", "equalto", "kubevirt") | map(attribute="addonCharts") | first | map(attribute="version") | list | first %} +{%- set release_manifest_elemental_version = spec.components.workloads.helm | selectattr("releaseName", "equalto", "elemental-operator") | map(attribute="version") | list | first %} +{%- set release_manifest_elemental_crd_version = spec.components.workloads.helm | selectattr("releaseName", "equalto", "elemental-operator") | map(attribute="dependencyCharts") | first | map(attribute="version") | list | first %} +{%- set release_manifest_elemental_dashboard_version = spec.components.workloads.helm | selectattr("releaseName", "equalto", "elemental-operator") | map(attribute="addonCharts") | first | map(attribute="version") | list | first %} +{%- set release_manifest_sriov_version = spec.components.workloads.helm | selectattr("releaseName", "equalto", "sriov-network-operator") | map(attribute="version") | list | first %} +{%- set release_manifest_sriov_crd_version = spec.components.workloads.helm | selectattr("releaseName", "equalto", "sriov-network-operator") | map(attribute="dependencyCharts") | first | map(attribute="version") | list | first %} +{%- set release_manifest_turtles_providers_version = spec.components.workloads.helm | selectattr("releaseName", "equalto", "rancher-turtles-providers") | map(attribute="version") | list | first %} +{%- set release_manifest_cert_manager_version = spec.components.workloads.helm | selectattr("releaseName", "equalto", "cert-manager") | map(attribute="version") | list | first %} +// ============================================================================ +:revdate: %%REVDATE%% +:page-revdate: {revdate} +// Automatic Version Substitutions +// +// The values in here are used throughout the documentation. Updating them here +// will propagate throughout the rest of the documentation. See the section at +// the bottom for details on versioning instances that cannot be handled in this +// fashion. +// ============================================================================ + +// == General Edge == +:version-edge: {{ release_manifest_edge_version_short }} +:version-edge-registry: {{ release_manifest_edge_version_short }} + +// == Multi-Linux Manager == +:version-mlm: 5.0.6 + +// == Edge Image Builder == +:version-eib: {{ version_eib }} +:version-eib-api-latest: 1.3 + +// KubeVirt +// This is used in download URLs and filenames from upstream, so it must have +// the leading "v". If needed, a separate version-kubevirt should be created +// with simply the version number itself. +:version-kubevirt-release: v{{ release_manifest_kubevirt_version .split("+up") | last }} + +// == Component Versions == +:version-rancher-prime: {{ release_manifest_rancher_version }} +:version-cert-manager: {{ release_manifest_cert_manager_version }} +:version-elemental-operator: {{ release_manifest_elemental_version }} +:version-longhorn: {{ release_manifest_longhorn_version.split("+up") | last }} +:version-neuvector: 5.4.8 +:version-kubevirt: {{ release_manifest_kubevirt_version .split("+up") | last }} +:version-endpoint-copier-operator: {{ release_manifest_eco_version.split("+up") | last }} +:version-suc: {{ version_suc }} +:version-fleet: {{ version_fleet }} +:version-cdi: {{ release_manifest_cdi_version.split("+up") | last }} +:version-nvidia-device-plugin: 0.14.5 +:version-kiwi-builder: {{ version_kiwi_builder }} + +// == Nessie == +:version-nessie: {{ version_nessie }} + +// == Non-Release Manifest Charts == +:version-suc-chart: {{ version_suc_chart }} +:version-upgrade-controller-chart: {{ version_upgrade_controller_chart }} +:version-nvidia-device-plugin-chart: v0.14.5 + +// == Release Tags == +:release-tag-eib: release-1.3 +:release-tag-telco-cloud: release-{{ release_manifest_edge_version_short }} +:release-tag-fleet-examples: release-{{ release_manifest_edge_version }} +:release-tag-rancher: v{{ release_manifest_rancher_version }} + + +// ============================================================================ +// Release Manifest Versions +// +// The following are derived from the `releaseName` field of the release manifest +// and should not be renamed without thinking through the implications. +// ============================================================================ + +:version-kubernetes-k3s: {{ release_manifest_k3s_version }} +:version-kubernetes-rke2: {{ release_manifest_rke2_version }} + +:version-operatingsystem: {{ release_manifest_slmicro_version }} + +:version-cdi-chart: {{ release_manifest_cdi_version }} +:version-endpoint-copier-operator-chart: {{ release_manifest_eco_version }} +:version-kubevirt-chart: {{ release_manifest_kubevirt_version }} +:version-kubevirt-dashboard-extension-chart: {{ release_manifest_kubevirt_dashboard_version }} +:version-longhorn-chart: {{ release_manifest_longhorn_version }} +:version-longhorn-crd-chart: {{ release_manifest_longhorn_crd_version }} +:version-longhorn-docs: {{ release_manifest_longhorn_version.split("+up") | last }} +:version-metal3-chart: {{ release_manifest_metal3_version }} +:version-metallb-chart: {{ release_manifest_metallb_version }} +:version-neuvector-chart: {{ release_manifest_neuvector_version }} +:version-neuvector-crd-chart: {{ release_manifest_neuvector_crd_version }} +:version-rancher-turtles-providers-chart: {{ release_manifest_turtles_providers_version }} +:version-sriov-crd-chart: {{ release_manifest_sriov_crd_version }} +:version-sriov-network-operator-chart: {{ release_manifest_sriov_version }} +:version-sriov-upstream: {{ release_manifest_sriov_version.split("+up") | last }} + +// capi-provider-metal3 +// edu, Oct 9, 2025 :: Used to link the CRDs on the docs site like +// https://doc.crds.dev/github.com/metal3-io/cluster-api-provider-metal3/infrastructure.cluster.x-k8s.io/Metal3MachineTemplate/v1beta1@v1.11.0#spec-template-spec-hostSelector-matchLabels +:version-capi-provider-metal3: v1beta1@v1.10.2 + +// ============================================================================ +// Derived Version Entries +// +// The following are derived from previously defined versions, ensure they +// are not using elements defined below them +// +// ============================================================================ + +// == SUSE Linux Micro == +:micro-base-image-raw: SL-Micro.x86_64-{version-operatingsystem}-Base-GM.raw +:micro-base-rt-image-raw: SL-Micro.x86_64-{version-operatingsystem}-Base-RT-GM.raw +:micro-base-rt-image-iso: SL-Micro.x86_64-{version-operatingsystem}-Base-RT-SelfInstall-GM.install.iso +:micro-base-image-iso: SL-Micro.x86_64-{version-operatingsystem}-Base-SelfInstall-GM.install.iso +:micro-default-image-iso: SL-Micro.x86_64-{version-operatingsystem}-Default-SelfInstall-GM.install.iso + + +// ============================================================================ +// Manual Version Entries +// +// The following files mention versions that cannot be handled through +// substitution. For example, EIB definitions that contain a list of +// images to embed. These files should be manually reviewed on a per-release +// basis to ensure accuracy. +// ============================================================================ + +// asciidoc/guides/air-gapped-eib-deployments.adoc +// asciidoc/product/atip-management-cluster.adoc +// asciidoc/product/atip-automated-provision.adoc +// asciidoc/edge-book/releasenotes.adoc diff --git a/asciidoc/integrations/linkerd.adoc b/asciidoc/integrations/linkerd.adoc deleted file mode 100644 index 7cae6db6..00000000 --- a/asciidoc/integrations/linkerd.adoc +++ /dev/null @@ -1,16 +0,0 @@ -[#integrations-linkerd] -= Linkerd Service Mesh -:revdate: 2024-04-22 -:page-revdate: {revdate} -:experimental: - -ifdef::env-github[] -:imagesdir: ../images/ -:tip-caption: :bulb: -:note-caption: :information_source: -:important-caption: :heavy_exclamation_mark: -:caution-caption: :fire: -:warning-caption: :warning: -endif::[] - -link:linkerd.io[Linkerd] is a lightweight service mesh for Kubernetes that "adds security, observability, and reliability" without requiring extra complexity. diff --git a/scripts/.gitignore b/scripts/.gitignore new file mode 100644 index 00000000..84eeb693 --- /dev/null +++ b/scripts/.gitignore @@ -0,0 +1 @@ +_release_manifest.yaml diff --git a/scripts/README.md b/scripts/README.md new file mode 100644 index 00000000..96039d6e --- /dev/null +++ b/scripts/README.md @@ -0,0 +1,9 @@ +# SUSE Edge documentation scripts + +These scripts are used to simplify the maintenance of the documentation in this repo + + + +## Update release versions + +The `versions_update.py` script updates the `versions.adoc` using data from the Factory `release_manifest.yaml` diff --git a/scripts/versions_update.py b/scripts/versions_update.py new file mode 100755 index 00000000..80c471f8 --- /dev/null +++ b/scripts/versions_update.py @@ -0,0 +1,288 @@ +#!/usr/bin/env python3 +""" +Generate versions.adoc from release manifest in container image. +Uses ORAS library for OCI registry interaction. +""" + +import oras.client +import requests +import tempfile +import tarfile +import gzip +import io +import yaml +import argparse +import re +import hashlib +import json +import base64 +from datetime import date +from jinja2 import Environment, FileSystemLoader +from pathlib import Path + + +def parse_version(version_str): + """Parse version string into tuple for comparison.""" + # Remove 'v' prefix if present + version_str = version_str.lstrip('v') + + # Extract numeric parts + parts = re.findall(r'\d+', version_str) + return tuple(int(p) for p in parts) if parts else (0,) + + +def get_latest_version_tag(repository): + """Get the latest version tag from the repository.""" + client = oras.client.OrasClient() + + print(f"Discovering tags for {repository}") + tags = client.get_tags(repository) + + # Filter out non-version tags (signatures, attestations) + version_tags = [ + tag for tag in tags + if not tag.endswith(('.sig', '.att')) and re.match(r'^\d+\.\d+', tag) + ] + + if not version_tags: + raise ValueError(f"No version tags found in {repository}") + + # Sort by semantic version + version_tags.sort(key=parse_version, reverse=True) + latest = version_tags[0] + + print(f"✓ Latest version: {latest}") + return latest + + +def get_latest_version_tag_with_prefix(repository, prefix): + """Get the latest version tag from the repository that starts with the given prefix.""" + client = oras.client.OrasClient() + + print(f"Discovering tags for {repository} with prefix {prefix}") + tags = client.get_tags(repository) + + # Filter for tags with the prefix, excluding signatures and attestations + version_tags = [ + tag for tag in tags + if tag.startswith(prefix) and not tag.endswith(('.sig', '.att')) + ] + + if not version_tags: + raise ValueError(f"No version tags found with prefix {prefix} in {repository}") + + # Sort by semantic version + version_tags.sort(key=parse_version, reverse=True) + latest = version_tags[0] + + print(f"✓ Latest version with prefix {prefix}: {latest}") + return latest + + +def find_file_in_layer(layer_path, target_file): + """Search for a file in a gzipped tar layer.""" + with open(layer_path, 'rb') as f: + layer_data = f.read() + + try: + stream = io.BytesIO(gzip.decompress(layer_data)) + except: + stream = io.BytesIO(layer_data) + + try: + with tarfile.open(fileobj=stream, mode='r') as tar: + for member in tar.getmembers(): + if member.name.lstrip('/') == target_file.lstrip('/'): + f = tar.extractfile(member) + return f.read().decode('utf-8') if f else None + except: + pass + return None + + +def fetch_release_manifest(image_ref, target_file="release_manifest.yaml"): + """Fetch release manifest from container image using ORAS.""" + print(f"Fetching release manifest from {image_ref}") + + client = oras.client.OrasClient() + + with tempfile.TemporaryDirectory() as tmpdir: + layers = client.pull(target=image_ref, outdir=tmpdir) + + for i, layer_path in enumerate(layers): + content = find_file_in_layer(layer_path, target_file) + if content: + print(f"✓ Found {target_file} in layer {i+1}") + return content + + raise FileNotFoundError(f"File {target_file} not found in image") + + +def get_image_version_from_rancher(rancher_version, image_name): + """Get image version from Rancher image list.""" + url = f"https://prime.ribs.rancher.io/rancher/v{rancher_version}/rancher-images.txt" + + response = requests.get(url) + response.raise_for_status() + + search_pattern = f"{image_name}:" + for line in response.text.splitlines(): + if search_pattern in line and not line.startswith('#'): + # Extract tag after colon + tag = line.split(':')[-1].strip() + print(f"✓ Found {image_name} version: {tag}") + return tag + + raise ValueError(f"{image_name} not found in rancher-images.txt for v{rancher_version}") + + +def get_suc_chart_version_from_rancher(rancher_version): + """Get system-upgrade-controller chart version from Rancher Dockerfile.""" + url = f"https://raw.githubusercontent.com/rancher/rancher/v{rancher_version}/package/Dockerfile" + + response = requests.get(url) + response.raise_for_status() + + for line in response.text.splitlines(): + if 'CATTLE_SYSTEM_UPGRADE_CONTROLLER_CHART_VERSION' in line: + # Extract version from ENV line (format: ENV CATTLE_SYSTEM_UPGRADE_CONTROLLER_CHART_VERSION=108.0.0) + version = line.split('=')[-1].strip() + print(f"✓ Found system-upgrade-controller chart version: {version}") + return version + + raise ValueError(f"CATTLE_SYSTEM_UPGRADE_CONTROLLER_CHART_VERSION not found in Dockerfile for v{rancher_version}") + +def render_template(template_path, manifest_data, output_path): + """Render Jinja2 template with manifest data.""" + template_file = Path(template_path) + + # Load template + env = Environment(loader=FileSystemLoader(template_file.parent)) + template = env.get_template(template_file.name) + + # Render template with manifest data + output = template.render(manifest_data) + + # Replace %%REVDATE%% with current date + revision_date = date.today().strftime('%Y-%m-%d') + output = output.replace('%%REVDATE%%', revision_date) + + # Write output + output_file = Path(output_path) + output_file.write_text(output) + print(f"✓ Generated {output_path}") + + +def main(): + parser = argparse.ArgumentParser( + description='Generate versions.adoc from release manifest in container image' + ) + parser.add_argument( + '--image', + default='registry.suse.com/edge/3.5/release-manifest', + help='Container image reference without tag (default: registry.suse.com/edge/3.5/release-manifest)' + ) + parser.add_argument( + '--tag', + help='Specific tag to use (if not specified, discovers latest version)' + ) + parser.add_argument( + '--template', + default='../asciidoc/edge-book/versions.adoc.j2', + help='Path to Jinja2 template (default: ../asciidoc/edge-book/versions.adoc.j2)' + ) + parser.add_argument( + '--output', + default='../asciidoc/edge-book/versions.adoc', + help='Output file path (default: ../asciidoc/edge-book/versions.adoc)' + ) + + args = parser.parse_args() + + # Parse image reference - handle both with and without tag + if ':' in args.image: + # Tag included in --image, split it + repository, image_tag = args.image.rsplit(':', 1) + else: + repository = args.image + image_tag = None + + # Determine which tag to use + if args.tag: + # Use explicit --tag parameter + tag = args.tag + elif image_tag: + # Use tag from --image parameter + tag = image_tag + else: + # Discover latest tag + tag = get_latest_version_tag(repository) + + # Build full image reference + image_ref = f"{repository}:{tag}" + + # Fetch release manifest from container image + manifest_yaml = fetch_release_manifest(image_ref) + + # Parse YAML + manifest_data = yaml.safe_load(manifest_yaml) + + # Add additional version data + # Get versions from other images in the same registry path + registry_base = '/'.join(repository.split('/')[:-1]) # Get base path without image name + + kiwi_builder_repo = f"{registry_base}/kiwi-builder" + kiwi_builder_version = get_latest_version_tag(kiwi_builder_repo) + # Strip suffix after hyphen (e.g., 10.2.29.1-1.1 -> 10.2.29.1) + manifest_data['version_kiwi_builder'] = kiwi_builder_version.split('-')[0] + + eib_repo = f"{registry_base}/edge-image-builder" + eib_version = get_latest_version_tag(eib_repo) + # Strip suffix after hyphen (e.g., 1.3.3-4.4 -> 1.3.3) + manifest_data['version_eib'] = eib_version.split('-')[0] + + nessie_repo = f"{registry_base}/nessie" + nessie_version = get_latest_version_tag(nessie_repo) + # Strip suffix after hyphen + manifest_data['version_nessie'] = nessie_version.split('-')[0] + + # Get upgrade-controller chart version + # Extract major.minor from release version (e.g., 3.5.0 -> 3.5) + release_version = manifest_data.get('spec', {}).get('releaseVersion', '') + if release_version: + version_parts = release_version.split('.')[:2] # Get major.minor + chart_prefix = version_parts[0] + '0' + version_parts[1] # e.g., 3.5 -> 305 + # Charts are at registry.suse.com/edge/charts/upgrade-controller (not version-specific) + registry_name = repository.split('/')[0] + upgrade_controller_repo = f"{registry_name}/edge/charts/upgrade-controller" + upgrade_controller_version = get_latest_version_tag_with_prefix(upgrade_controller_repo, chart_prefix) + # Strip suffix after hyphen (e.g., 305.0.3_up0.1.3-4.1 -> 305.0.3_up0.1.3) + manifest_data['version_upgrade_controller_chart'] = upgrade_controller_version.split('-')[0] + + # Get SUC and Fleet versions from Rancher image list + # Extract rancher version from manifest + rancher_version = None + for helm in manifest_data.get('spec', {}).get('components', {}).get('workloads', {}).get('helm', []): + if helm.get('releaseName') == 'rancher': + rancher_version = helm.get('version') + break + + if rancher_version: + print(f"Fetching Rancher image list from https://prime.ribs.rancher.io/rancher/v{rancher_version}/rancher-images.txt") + suc_version = get_image_version_from_rancher(rancher_version, 'rancher/system-upgrade-controller') + manifest_data['version_suc'] = suc_version + + fleet_version = get_image_version_from_rancher(rancher_version, 'rancher/fleet') + manifest_data['version_fleet'] = fleet_version + + suc_chart_version = get_suc_chart_version_from_rancher(rancher_version) + manifest_data['version_suc_chart'] = suc_chart_version + else: + print("⚠ Warning: Rancher version not found in manifest, skipping SUC and Fleet versions") + + # Render template + render_template(args.template, manifest_data, args.output) + + +if __name__ == "__main__": + main()