@@ -20,7 +20,6 @@ import (
2020	"encoding/json" 
2121	"errors" 
2222	"fmt" 
23- 	"reflect" 
2423	"strings" 
2524
2625	jsonpatch "gomodules.xyz/jsonpatch/v3" 
@@ -33,7 +32,6 @@ import (
3332	"helm.sh/helm/v3/pkg/storage/driver" 
3433	apiextv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" 
3534	apiextv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" 
36- 	apiequality "k8s.io/apimachinery/pkg/api/equality" 
3735	apierrors "k8s.io/apimachinery/pkg/api/errors" 
3836	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 
3937	"k8s.io/apimachinery/pkg/runtime" 
@@ -127,9 +125,13 @@ func (m *manager) Sync(ctx context.Context) error {
127125	m .deployedRelease  =  deployedRelease 
128126	m .isInstalled  =  true 
129127
130- 	m .isUpgradeRequired , err  =  m .isUpgrade (deployedRelease )
128+ 	// Get the next candidate release to determine if an upgrade is necessary. 
129+ 	candidateRelease , err  :=  m .getCandidateRelease (m .namespace , m .releaseName , m .chart , m .values )
131130	if  err  !=  nil  {
132- 		return  fmt .Errorf ("failed to get upgrade status: %w" , err )
131+ 		return  fmt .Errorf ("failed to get candidate release: %w" , err )
132+ 	}
133+ 	if  deployedRelease .Manifest  !=  candidateRelease .Manifest  {
134+ 		m .isUpgradeRequired  =  true 
133135	}
134136	return  nil 
135137}
@@ -138,43 +140,6 @@ func notFoundErr(err error) bool {
138140	return  err  !=  nil  &&  strings .Contains (err .Error (), "not found" )
139141}
140142
141- // This is caused by the different logic of loading from local and loading from secret 
142- // For example, the Raw field, which has the tag `json:"-"`, causes the Unmarshal to be lost when it into Release 
143- // We need to make them follow the JSON tag 
144- // see: https://github.com/helm/helm/blob/cf0c6fed519d48101cd69ce01a355125215ee46f/pkg/storage/driver/util.go#L81 
145- func  equalJSONStruct (a , b  interface {}) (bool , error ) {
146- 	if  reflect .ValueOf (a ).IsNil () ||  reflect .ValueOf (b ).IsNil () {
147- 		return  apiequality .Semantic .DeepEqual (a , b ), nil 
148- 	}
149- 
150- 	aBuf , bBuf  :=  & bytes.Buffer {}, & bytes.Buffer {}
151- 	err  :=  json .NewEncoder (aBuf ).Encode (a )
152- 	if  err  !=  nil  {
153- 		return  false , err 
154- 	}
155- 	err  =  json .NewEncoder (bBuf ).Encode (b )
156- 	return  aBuf .String () ==  bBuf .String (), err 
157- }
158- 
159- func  (m  manager ) isUpgrade (deployedRelease  * rpb.Release ) (bool , error ) {
160- 	if  deployedRelease  ==  nil  {
161- 		return  false , nil 
162- 	}
163- 
164- 	// Judging whether to skip updates 
165- 	skip  :=  m .namespace  ==  deployedRelease .Namespace 
166- 	skip  =  skip  &&  m .releaseName  ==  deployedRelease .Name 
167- 
168- 	ok , err  :=  equalJSONStruct (m .chart , deployedRelease .Chart )
169- 	if  err  !=  nil  {
170- 		return  false , err 
171- 	}
172- 	skip  =  skip  &&  ok 
173- 
174- 	ok , err  =  equalJSONStruct (m .values , deployedRelease .Config )
175- 	return  ! (skip  &&  ok ), err 
176- }
177- 
178143func  (m  manager ) getDeployedRelease () (* rpb.Release , error ) {
179144	deployedRelease , err  :=  m .storageBackend .Deployed (m .releaseName )
180145	if  err  !=  nil  {
@@ -186,6 +151,14 @@ func (m manager) getDeployedRelease() (*rpb.Release, error) {
186151	return  deployedRelease , nil 
187152}
188153
154+ func  (m  manager ) getCandidateRelease (namespace , name  string , chart  * cpb.Chart ,
155+ 	values  map [string ]interface {}) (* rpb.Release , error ) {
156+ 	upgrade  :=  action .NewUpgrade (m .actionConfig )
157+ 	upgrade .Namespace  =  namespace 
158+ 	upgrade .DryRun  =  true 
159+ 	return  upgrade .Run (name , chart , values )
160+ }
161+ 
189162// InstallRelease performs a Helm release install. 
190163func  (m  manager ) InstallRelease (ctx  context.Context , opts  ... InstallOption ) (* rpb.Release , error ) {
191164	install  :=  action .NewInstall (m .actionConfig )
0 commit comments