2019-02-09 08:02:57 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								/ *  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								Copyright  The  Helm  Authors .  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								Licensed  under  the  Apache  License ,  Version  2.0  ( the  "License" ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								you  may  not  use  this  file  except  in  compliance  with  the  License .  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								You  may  obtain  a  copy  of  the  License  at  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    http : //www.apache.org/licenses/LICENSE-2.0
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								Unless  required  by  applicable  law  or  agreed  to  in  writing ,  software  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								distributed  under  the  License  is  distributed  on  an  "AS IS"  BASIS ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								WITHOUT  WARRANTIES  OR  CONDITIONS  OF  ANY  KIND ,  either  express  or  implied .  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								See  the  License  for  the  specific  language  governing  permissions  and  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								limitations  under  the  License .  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								* /  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								package  action  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								import  (  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"bytes" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"fmt" 
							 
						 
					
						
							
								
									
										
										
										
											2019-09-24 06:13:02 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"strings" 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-17 10:01:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"time" 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-09 08:02:57 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"github.com/pkg/errors" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-09-10 03:30:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"helm.sh/helm/v3/pkg/chartutil" 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-04 02:27:05 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"helm.sh/helm/v3/pkg/release" 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-17 10:01:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									helmtime  "helm.sh/helm/v3/pkg/time" 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-09 08:02:57 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								)  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Rollback is the action for rolling back to a given release.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// It provides the implementation of 'helm rollback'.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  Rollback  struct  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									cfg  * Configuration 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-09-24 06:13:02 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									Version        int 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-17 10:01:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									Timeout        time . Duration 
							 
						 
					
						
							
								
									
										
										
										
											2019-09-24 06:13:02 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									Wait           bool 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-03 19:48:29 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									WaitForJobs    bool 
							 
						 
					
						
							
								
									
										
										
										
											2019-09-24 06:13:02 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									DisableHooks   bool 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									DryRun         bool 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Recreate       bool  // will (if true) recreate pods after a rollback.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Force          bool  // will (if true) force resource upgrade through uninstall/recreate if needed
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									CleanupOnFail  bool 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-09 17:40:36 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									MaxHistory     int  // MaxHistory limits the maximum number of revisions saved per release
 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-09 08:02:57 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// NewRollback creates a new Rollback object with the given configuration.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  NewRollback ( cfg  * Configuration )  * Rollback  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  & Rollback { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										cfg :  cfg , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Run executes 'helm rollback' against the given release.
  
						 
					
						
							
								
									
										
										
										
											2019-08-20 01:22:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( r  * Rollback )  Run ( name  string )  error  {  
						 
					
						
							
								
									
										
										
										
											2019-08-26 05:46:12 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  :=  r . cfg . KubeClient . IsReachable ( ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-07-09 17:40:36 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									r . cfg . Releases . MaxHistory  =  r . MaxHistory 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-02-09 08:02:57 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									r . cfg . Log ( "preparing rollback of %s" ,  name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									currentRelease ,  targetRelease ,  err  :=  r . prepareRollback ( name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-20 01:22:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  err 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-09 08:02:57 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! r . DryRun  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										r . cfg . Log ( "creating rolled back release for %s" ,  name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  :=  r . cfg . Releases . Create ( targetRelease ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-20 01:22:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  err 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-09 08:02:57 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2019-09-24 06:13:02 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-02-09 08:02:57 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									r . cfg . Log ( "performing rollback of %s" ,  name ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-20 01:22:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  _ ,  err  :=  r . performRollback ( currentRelease ,  targetRelease ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  err 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-09 08:02:57 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! r . DryRun  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										r . cfg . Log ( "updating status for rolled back release for %s" ,  name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  :=  r . cfg . Releases . Update ( targetRelease ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-20 01:22:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  err 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-09 08:02:57 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-20 01:22:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-09 08:02:57 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// prepareRollback finds the previous release and prepares a new release object with
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// the previous release's configuration
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( r  * Rollback )  prepareRollback ( name  string )  ( * release . Release ,  * release . Release ,  error )  {  
						 
					
						
							
								
									
										
										
										
											2020-09-10 03:30:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  :=  chartutil . ValidateReleaseName ( name ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-09 08:02:57 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										return  nil ,  nil ,  errors . Errorf ( "prepareRollback: Release name is invalid: %s" ,  name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  r . Version  <  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  nil ,  errInvalidRevision 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									currentRelease ,  err  :=  r . cfg . Releases . Last ( name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									previousVersion  :=  r . Version 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  r . Version  ==  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										previousVersion  =  currentRelease . Version  -  1 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									r . cfg . Log ( "rolling back %s (current: v%d, target: v%d)" ,  name ,  currentRelease . Version ,  previousVersion ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									previousRelease ,  err  :=  r . cfg . Releases . Get ( name ,  previousVersion ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Store a new release object with previous release's configuration
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									targetRelease  :=  & release . Release { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Name :       name , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Namespace :  currentRelease . Namespace , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Chart :      previousRelease . Chart , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Config :     previousRelease . Config , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Info :  & release . Info { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											FirstDeployed :  currentRelease . Info . FirstDeployed , 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-17 10:01:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											LastDeployed :   helmtime . Now ( ) , 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-09 08:02:57 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											Status :         release . StatusPendingRollback , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Notes :          previousRelease . Info . Notes , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// Because we lose the reference to previous version elsewhere, we set the
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// message here, and only override it later if we experience failure.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Description :  fmt . Sprintf ( "Rollback to %d" ,  previousVersion ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Version :   currentRelease . Version  +  1 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Manifest :  previousRelease . Manifest , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Hooks :     previousRelease . Hooks , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  currentRelease ,  targetRelease ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( r  * Rollback )  performRollback ( currentRelease ,  targetRelease  * release . Release )  ( * release . Release ,  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  r . DryRun  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										r . cfg . Log ( "dry run for %s" ,  targetRelease . Name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  targetRelease ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-10-09 03:55:19 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									current ,  err  :=  r . cfg . KubeClient . Build ( bytes . NewBufferString ( currentRelease . Manifest ) ,  false ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-07-25 04:24:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  targetRelease ,  errors . Wrap ( err ,  "unable to build kubernetes objects from current release manifest" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-09 03:55:19 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									target ,  err  :=  r . cfg . KubeClient . Build ( bytes . NewBufferString ( targetRelease . Manifest ) ,  false ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-07-25 04:24:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  targetRelease ,  errors . Wrap ( err ,  "unable to build kubernetes objects from new release manifest" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-02-09 08:02:57 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									// pre-rollback hooks
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! r . DisableHooks  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-07-26 02:45:03 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err  :=  r . cfg . execHook ( targetRelease ,  release . HookPreRollback ,  r . Timeout ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-09 08:02:57 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											return  targetRelease ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										r . cfg . Log ( "rollback hooks disabled for %s" ,  targetRelease . Name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-07-25 04:24:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									results ,  err  :=  r . cfg . KubeClient . Update ( current ,  target ,  r . Force ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-07-04 03:05:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-07-25 04:24:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-09 08:02:57 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										msg  :=  fmt . Sprintf ( "Rollback %q failed: %s" ,  targetRelease . Name ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										r . cfg . Log ( "warning: %s" ,  msg ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										currentRelease . Info . Status  =  release . StatusSuperseded 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										targetRelease . Info . Status  =  release . StatusFailed 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										targetRelease . Info . Description  =  msg 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-27 02:11:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										r . cfg . recordRelease ( currentRelease ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										r . cfg . recordRelease ( targetRelease ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-09-24 06:13:02 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  r . CleanupOnFail  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											r . cfg . Log ( "Cleanup on fail set, cleaning up %d resources" ,  len ( results . Created ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											_ ,  errs  :=  r . cfg . KubeClient . Delete ( results . Created ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  errs  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												var  errorList  [ ] string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												for  _ ,  e  :=  range  errs  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													errorList  =  append ( errorList ,  e . Error ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  targetRelease ,  errors . Wrapf ( fmt . Errorf ( "unable to cleanup resources: %s" ,  strings . Join ( errorList ,  ", " ) ) ,  "an error occurred while cleaning up resources. original rollback error: %s" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											r . cfg . Log ( "Resource cleanup complete" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-09 08:02:57 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										return  targetRelease ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-07-25 04:24:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  r . Recreate  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// NOTE: Because this is not critical for a release to succeed, we just
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// log if an error occurs and continue onward. If we ever introduce log
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// levels, we should make these error level logs so users are notified
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// that they'll need to go do the cleanup on their own
 
							 
						 
					
						
							
								
									
										
										
										
											2019-07-31 01:48:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err  :=  recreate ( r . cfg ,  results . Updated ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-07-25 04:24:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											r . cfg . Log ( err . Error ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-07-04 03:05:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  r . Wait  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-05 17:13:15 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  r . WaitForJobs  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  :=  r . cfg . KubeClient . WaitWithJobs ( target ,  r . Timeout ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												targetRelease . SetStatus ( release . StatusFailed ,  fmt . Sprintf ( "Release %q failed: %s" ,  targetRelease . Name ,  err . Error ( ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												r . cfg . recordRelease ( currentRelease ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												r . cfg . recordRelease ( targetRelease ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  targetRelease ,  errors . Wrapf ( err ,  "release %s failed" ,  targetRelease . Name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  :=  r . cfg . KubeClient . Wait ( target ,  r . Timeout ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												targetRelease . SetStatus ( release . StatusFailed ,  fmt . Sprintf ( "Release %q failed: %s" ,  targetRelease . Name ,  err . Error ( ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												r . cfg . recordRelease ( currentRelease ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												r . cfg . recordRelease ( targetRelease ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  targetRelease ,  errors . Wrapf ( err ,  "release %s failed" ,  targetRelease . Name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2019-07-04 03:05:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-02-09 08:02:57 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									// post-rollback hooks
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! r . DisableHooks  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-07-26 02:45:03 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err  :=  r . cfg . execHook ( targetRelease ,  release . HookPostRollback ,  r . Timeout ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-09 08:02:57 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											return  targetRelease ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									deployed ,  err  :=  r . cfg . Releases . DeployedAll ( currentRelease . Name ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-02-22 01:22:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  &&  ! strings . Contains ( err . Error ( ) ,  "has no deployed releases" )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-09 08:02:57 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Supersede all previous deployments, see issue #2941.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  _ ,  rel  :=  range  deployed  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										r . cfg . Log ( "superseding previous deployment %d" ,  rel . Version ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rel . Info . Status  =  release . StatusSuperseded 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-27 02:11:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										r . cfg . recordRelease ( rel ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-09 08:02:57 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									targetRelease . Info . Status  =  release . StatusDeployed 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  targetRelease ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}