@@ -61,6 +61,9 @@ pub enum Error {
6161 #[ snafu( display( "failed to install Helm release" ) ) ]
6262 InstallRelease { source : InstallReleaseError } ,
6363
64+ #[ snafu( display( "failed to upgrade/install Helm release" ) ) ]
65+ UpgradeRelease { source : InstallReleaseError } ,
66+
6467 #[ snafu( display( "failed to uninstall Helm release ({error})" ) ) ]
6568 UninstallRelease { error : String } ,
6669}
@@ -248,6 +251,78 @@ pub fn install_release_from_repo_or_registry(
248251 } )
249252}
250253
254+ /// Upgrades a Helm release from a repo or registry.
255+ ///
256+ /// This function expects the fully qualified Helm release name. In case of our
257+ /// operators this is: `<PRODUCT_NAME>-operator`.
258+ #[ instrument( skip( values_yaml) , fields( with_values = values_yaml. is_some( ) , indicatif. pb_show = true ) ) ]
259+ pub fn upgrade_or_install_release_from_repo_or_registry (
260+ release_name : & str ,
261+ ChartVersion {
262+ chart_source,
263+ chart_name,
264+ chart_version,
265+ } : ChartVersion ,
266+ values_yaml : Option < & str > ,
267+ namespace : & str ,
268+ suppress_output : bool ,
269+ ) -> Result < InstallReleaseStatus , Error > {
270+ // Ideally, each Helm invocation would spawn_blocking instead in/around helm_sys,
271+ // but that requires a larger refactoring
272+ block_in_place ( || {
273+ debug ! ( "Install/Upgrade Helm release from repo" ) ;
274+ Span :: current ( )
275+ . pb_set_message ( format ! ( "Installing/Upgrading {chart_name} Helm chart" ) . as_str ( ) ) ;
276+
277+ if check_release_exists ( release_name, namespace) ? {
278+ let release = get_release ( release_name, namespace) ?. ok_or ( Error :: InstallRelease {
279+ source : InstallReleaseError :: NoSuchRelease {
280+ name : release_name. to_owned ( ) ,
281+ } ,
282+ } ) ?;
283+
284+ let current_version = release. version ;
285+
286+ match chart_version {
287+ Some ( chart_version) => {
288+ if chart_version == current_version {
289+ return Ok ( InstallReleaseStatus :: ReleaseAlreadyInstalledWithVersion {
290+ requested_version : chart_version. to_string ( ) ,
291+ release_name : release_name. to_string ( ) ,
292+ current_version,
293+ } ) ;
294+ }
295+ }
296+ None => {
297+ return Ok ( InstallReleaseStatus :: ReleaseAlreadyInstalledUnspecified {
298+ release_name : release_name. to_string ( ) ,
299+ current_version,
300+ } ) ;
301+ }
302+ }
303+ }
304+
305+ let full_chart_name = format ! ( "{chart_source}/{chart_name}" ) ;
306+ let chart_version = chart_version. unwrap_or ( HELM_DEFAULT_CHART_VERSION ) ;
307+
308+ debug ! (
309+ release_name,
310+ chart_version, full_chart_name, "Installing Helm release"
311+ ) ;
312+
313+ upgrade_release (
314+ release_name,
315+ & full_chart_name,
316+ chart_version,
317+ values_yaml,
318+ namespace,
319+ suppress_output,
320+ ) ?;
321+
322+ Ok ( InstallReleaseStatus :: Installed ( release_name. to_string ( ) ) )
323+ } )
324+ }
325+
251326/// Installs a Helm release.
252327///
253328/// This function expects the fully qualified Helm release name. In case of our
@@ -281,6 +356,43 @@ fn install_release(
281356 Ok ( ( ) )
282357}
283358
359+ /// Upgrades a Helm release.
360+ /// If a release with the specified `chart_name` does not already exist,
361+ /// this function installs it instead.
362+ ///
363+ /// This function expects the fully qualified Helm release name. In case of our
364+ /// operators this is: `<PRODUCT_NAME>-operator`.
365+ #[ instrument( fields( with_values = values_yaml. is_some( ) ) ) ]
366+ fn upgrade_release (
367+ release_name : & str ,
368+ chart_name : & str ,
369+ chart_version : & str ,
370+ values_yaml : Option < & str > ,
371+ namespace : & str ,
372+ suppress_output : bool ,
373+ ) -> Result < ( ) , Error > {
374+ let result = helm_sys:: upgrade_or_install_helm_release (
375+ release_name,
376+ chart_name,
377+ chart_version,
378+ values_yaml. unwrap_or ( "" ) ,
379+ namespace,
380+ suppress_output,
381+ ) ;
382+
383+ if let Some ( error) = helm_sys:: to_helm_error ( & result) {
384+ error ! (
385+ "Go wrapper function go_upgrade_or_install_helm_release encountered an error: {error}"
386+ ) ;
387+
388+ return Err ( Error :: UpgradeRelease {
389+ source : InstallReleaseError :: HelmWrapper { error } ,
390+ } ) ;
391+ }
392+
393+ Ok ( ( ) )
394+ }
395+
284396/// Uninstall a Helm release.
285397///
286398/// This function expects the fully qualified Helm release name. In case of our
0 commit comments