diff --git a/Cargo.lock b/Cargo.lock index 100f6188..600b48dd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3145,9 +3145,9 @@ checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f" [[package]] name = "rustls-webpki" -version = "0.103.12" +version = "0.103.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8279bb85272c9f10811ae6a6c547ff594d6a7f3c6c6b02ee9726d1d0dcfcdd06" +checksum = "61c429a8649f110dddef65e2a5ad240f747e85f7758a6bccc7e5777bd33f756e" dependencies = [ "aws-lc-rs", "ring", diff --git a/Cargo.nix b/Cargo.nix index db19601b..9abd0950 100644 --- a/Cargo.nix +++ b/Cargo.nix @@ -10491,9 +10491,9 @@ rec { }; "rustls-webpki" = rec { crateName = "rustls-webpki"; - version = "0.103.12"; + version = "0.103.13"; edition = "2021"; - sha256 = "01nxzkfd1l96jzp04svc7iznlkarzx3wb9p63a0i17rc4y2vnyc2"; + sha256 = "0vkm7z9pnxz5qz66p2kmyy2pwx0g4jnsbqk5xzfhs4czcjl2ki31"; libName = "webpki"; dependencies = [ { diff --git a/rust/stackable-cockpit/src/helm.rs b/rust/stackable-cockpit/src/helm.rs index 76528584..baad9ee1 100644 --- a/rust/stackable-cockpit/src/helm.rs +++ b/rust/stackable-cockpit/src/helm.rs @@ -38,6 +38,40 @@ pub struct ChartRepo { pub url: String, } +/// The kind of source a chart repo URL refers to. +/// +/// [Self::Oci] and [Self::Local] don't need special handling, but [Self::Repo] +/// needs to call `helm::add_repo`. +/// +/// Note: We don't yet support local repositories, so an error should be emitted +/// if the source is [Self::Local]. +#[derive(Debug, PartialEq)] +pub enum ChartSourceKind { + /// OCI registry (url starts with `oci://`) + Oci, + + /// Traditional index.yaml-based repository (url starts with `http://` or `https://`) + Repo, + + /// Local filesystem path (not yet supported) + /// + /// This is the fallback if not oci or http(s). + Local, +} + +impl ChartRepo { + /// Determine the kind of chart source based on the URL scheme. + pub fn source_kind(&self) -> ChartSourceKind { + if self.url.starts_with("oci://") { + ChartSourceKind::Oci + } else if self.url.starts_with("http://") || self.url.starts_with("https://") { + ChartSourceKind::Repo + } else { + ChartSourceKind::Local + } + } +} + #[derive(Debug, Snafu)] pub enum Error { #[snafu(display("failed to parse URL"))] @@ -505,3 +539,27 @@ where serde_yaml::from_str(&index_file_content).context(DeserializeYamlSnafu) } + +#[cfg(test)] +mod tests { + use rstest::rstest; + + use super::*; + + #[rstest] + #[case("oci://oci.stackable.tech/sdp-charts", ChartSourceKind::Oci)] + #[case( + "https://repo.stackable.tech/repository/helm-stable", + ChartSourceKind::Repo + )] + #[case("http://example.com/charts", ChartSourceKind::Repo)] + #[case("./charts/my-chart", ChartSourceKind::Local)] + #[case("/absolute/path/to/chart", ChartSourceKind::Local)] + fn source_kind(#[case] url: &str, #[case] expected: ChartSourceKind) { + let repo = ChartRepo { + name: "test".to_owned(), + url: url.to_owned(), + }; + assert_eq!(repo.source_kind(), expected); + } +} diff --git a/rust/stackable-cockpit/src/platform/manifests.rs b/rust/stackable-cockpit/src/platform/manifests.rs index 6e5dd45d..36531ded 100644 --- a/rust/stackable-cockpit/src/platform/manifests.rs +++ b/rust/stackable-cockpit/src/platform/manifests.rs @@ -56,6 +56,10 @@ pub enum Error { source: helm::Error, }, + /// This error indicates that the Helm chart source kind is not supported. + #[snafu(display("local Helm chart sources are not yet supported (source: {chart_source:?})"))] + UnsupportedChartSource { chart_source: String }, + /// This error indicates that Helm chart options could not be serialized /// into YAML. #[snafu(display("failed to serialize Helm chart options"))] @@ -104,12 +108,23 @@ pub trait InstallManifestsExt { info!(helm_chart.name, helm_chart.version, "Installing Helm chart",); - // Assumption: that all manifest helm charts refer to repos not registries - helm::add_repo(&helm_chart.repo.name, &helm_chart.repo.url).context( - AddHelmRepositorySnafu { - repo_name: helm_chart.repo.name.clone(), - }, - )?; + let chart_source = match helm_chart.repo.source_kind() { + helm::ChartSourceKind::Repo => { + helm::add_repo(&helm_chart.repo.name, &helm_chart.repo.url).context( + AddHelmRepositorySnafu { + repo_name: helm_chart.repo.name.clone(), + }, + )?; + &helm_chart.repo.name + } + helm::ChartSourceKind::Oci => &helm_chart.repo.url, + helm::ChartSourceKind::Local => { + return UnsupportedChartSourceSnafu { + chart_source: helm_chart.repo.url.clone(), + } + .fail(); + } + }; // Serialize chart options to string let values_yaml = serde_yaml::to_string(&helm_chart.options) @@ -119,7 +134,7 @@ pub trait InstallManifestsExt { helm::upgrade_or_install_release_from_repo_or_registry( &helm_chart.release_name, helm::ChartVersion { - chart_source: &helm_chart.repo.name, + chart_source, chart_name: &helm_chart.name, chart_version: Some(&helm_chart.version), }, diff --git a/rust/stackablectl/CHANGELOG.md b/rust/stackablectl/CHANGELOG.md index bc493c58..91507e68 100644 --- a/rust/stackablectl/CHANGELOG.md +++ b/rust/stackablectl/CHANGELOG.md @@ -10,9 +10,11 @@ All notable changes to this project will be documented in this file. - Add `uninstall` subcommand for `demo`/`stack` commands ([#429]). - Add confirmation prompt to `install` subcommand for namespace selection ([#429]). - Add `--assume-yes` option for running commands non-interactively ([#429]). +- Support Helm charts sourced from OCI registries in demo/stack manifests ([#440]). [#429]: https://github.com/stackabletech/stackable-cockpit/pull/429 [#438]: https://github.com/stackabletech/stackable-cockpit/pull/438 +[#440]: https://github.com/stackabletech/stackable-cockpit/pull/440 ## [1.4.0] - 2026-03-18