@@ -44,6 +44,9 @@ pub enum ReleaseCommands {
4444 /// Uninstall a release
4545 #[ command( aliases( [ "rm" , "un" ] ) ) ]
4646 Uninstall ( ReleaseUninstallArgs ) ,
47+
48+ // Upgrade a release
49+ Upgrade ( ReleaseUpgradeArgs ) ,
4750}
4851
4952#[ derive( Debug , Args ) ]
@@ -83,6 +86,25 @@ pub struct ReleaseInstallArgs {
8386 local_cluster : CommonClusterArgs ,
8487}
8588
89+ #[ derive( Debug , Args ) ]
90+ pub struct ReleaseUpgradeArgs {
91+ /// Release to upgrade to
92+ #[ arg( name = "RELEASE" ) ]
93+ release : String ,
94+
95+ /// List of product operators to upgrade
96+ #[ arg( short, long = "include" , group = "products" ) ]
97+ included_products : Vec < String > ,
98+
99+ /// Blacklist of product operators to install
100+ #[ arg( short, long = "exclude" , group = "products" ) ]
101+ excluded_products : Vec < String > ,
102+
103+ /// Namespace in the cluster used to deploy the operators
104+ #[ arg( long, default_value = DEFAULT_OPERATOR_NAMESPACE , visible_aliases( [ "operator-ns" ] ) ) ]
105+ pub operator_namespace : String ,
106+ }
107+
86108#[ derive( Debug , Args ) ]
87109pub struct ReleaseUninstallArgs {
88110 /// Name of the release to uninstall
@@ -111,6 +133,9 @@ pub enum CmdError {
111133 #[ snafu( display( "failed to install release" ) ) ]
112134 ReleaseInstall { source : release:: Error } ,
113135
136+ #[ snafu( display( "failed to upgrade CRDs for release" ) ) ]
137+ CrdUpgrade { source : release:: Error } ,
138+
114139 #[ snafu( display( "failed to uninstall release" ) ) ]
115140 ReleaseUninstall { source : release:: Error } ,
116141
@@ -146,6 +171,7 @@ impl ReleaseArgs {
146171 ReleaseCommands :: Describe ( args) => describe_cmd ( args, cli, release_list) . await ,
147172 ReleaseCommands :: Install ( args) => install_cmd ( args, cli, release_list) . await ,
148173 ReleaseCommands :: Uninstall ( args) => uninstall_cmd ( args, cli, release_list) . await ,
174+ ReleaseCommands :: Upgrade ( args) => upgrade_cmd ( args, cli, release_list) . await ,
149175 }
150176 }
151177}
@@ -314,6 +340,60 @@ async fn install_cmd(
314340 }
315341}
316342
343+ #[ instrument( skip( cli, release_list) ) ]
344+ async fn upgrade_cmd (
345+ args : & ReleaseUpgradeArgs ,
346+ cli : & Cli ,
347+ release_list : release:: ReleaseList ,
348+ ) -> Result < String , CmdError > {
349+ debug ! ( release = %args. release, "Upgrading release" ) ;
350+ Span :: current ( ) . pb_set_style ( & ProgressStyle :: with_template ( "" ) . unwrap ( ) ) ;
351+
352+ match release_list. get ( & args. release ) {
353+ Some ( release) => {
354+ let mut output = cli. result ( ) ;
355+ let client = Client :: new ( ) . await . context ( KubeClientCreateSnafu ) ?;
356+
357+ // Uninstall the old operator release first
358+ release
359+ . uninstall ( & args. operator_namespace )
360+ . context ( ReleaseUninstallSnafu ) ?;
361+
362+ // Upgrade the CRDs for all the operators to be upgraded
363+ release
364+ . upgrade_crds (
365+ & args. included_products ,
366+ & args. excluded_products ,
367+ & args. operator_namespace ,
368+ & client,
369+ )
370+ . await
371+ . context ( CrdUpgradeSnafu ) ?;
372+
373+ // Install the new operator release
374+ release
375+ . install (
376+ & args. included_products ,
377+ & args. excluded_products ,
378+ & args. operator_namespace ,
379+ & ChartSourceType :: from ( cli. chart_type ( ) ) ,
380+ )
381+ . await
382+ . context ( ReleaseInstallSnafu ) ?;
383+
384+ output
385+ . with_command_hint (
386+ "stackablectl operator installed" ,
387+ "list installed operators" ,
388+ )
389+ . with_output ( format ! ( "Upgraded to release '{}'" , args. release) ) ;
390+
391+ Ok ( output. render ( ) )
392+ }
393+ None => Ok ( "No such release" . into ( ) ) ,
394+ }
395+ }
396+
317397#[ instrument( skip( cli, release_list) ) ]
318398async fn uninstall_cmd (
319399 args : & ReleaseUninstallArgs ,
0 commit comments