Skip to content

Commit

Permalink
Improve Application updates when write-back method is ArgoCD (#965) (#…
Browse files Browse the repository at this point in the history
…981)

Signed-off-by: Álvaro Aguilar-Tablada Espinosa <[email protected]>
Co-authored-by: Álvaro Aguilar-Tablada Espinosa <[email protected]>
  • Loading branch information
chengfang and aaguilartablada authored Dec 20, 2024
1 parent 57138ca commit 11e4c20
Show file tree
Hide file tree
Showing 2 changed files with 108 additions and 5 deletions.
79 changes: 79 additions & 0 deletions pkg/argocd/argocd.go
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,55 @@ func mergeHelmParams(src []v1alpha1.HelmParameter, merge []v1alpha1.HelmParamete
return retParams
}

// GetHelmImage gets the image set in Application source matching new image
// or an empty string if match is not found
func GetHelmImage(app *v1alpha1.Application, newImage *image.ContainerImage) (string, error) {

if appType := getApplicationType(app); appType != ApplicationTypeHelm {
return "", fmt.Errorf("cannot set Helm params on non-Helm application")
}

var hpImageName, hpImageTag, hpImageSpec string

hpImageSpec = newImage.GetParameterHelmImageSpec(app.Annotations)
hpImageName = newImage.GetParameterHelmImageName(app.Annotations)
hpImageTag = newImage.GetParameterHelmImageTag(app.Annotations)

if hpImageSpec == "" {
if hpImageName == "" {
hpImageName = common.DefaultHelmImageName
}
if hpImageTag == "" {
hpImageTag = common.DefaultHelmImageTag
}
}

appSource := getApplicationSource(app)

if appSource.Helm == nil {
return "", nil
}

if appSource.Helm.Parameters == nil {
return "", nil
}

if hpImageSpec != "" {
if p := getHelmParam(appSource.Helm.Parameters, hpImageSpec); p != nil {
return p.Value, nil
}
} else {
imageName := getHelmParam(appSource.Helm.Parameters, hpImageName)
imageTag := getHelmParam(appSource.Helm.Parameters, hpImageTag)
if imageName == nil || imageTag == nil {
return "", nil
}
return imageName.Value + ":" + imageTag.Value, nil
}

return "", nil
}

// SetHelmImage sets image parameters for a Helm application
func SetHelmImage(app *v1alpha1.Application, newImage *image.ContainerImage) error {
if appType := getApplicationType(app); appType != ApplicationTypeHelm {
Expand Down Expand Up @@ -438,6 +487,36 @@ func SetHelmImage(app *v1alpha1.Application, newImage *image.ContainerImage) err
return nil
}

// GetKustomizeImage gets the image set in Application source matching new image
// or an empty string if match is not found
func GetKustomizeImage(app *v1alpha1.Application, newImage *image.ContainerImage) (string, error) {
if appType := getApplicationType(app); appType != ApplicationTypeKustomize {
return "", fmt.Errorf("cannot set Kustomize image on non-Kustomize application")
}

ksImageName := newImage.GetParameterKustomizeImageName(app.Annotations)

appSource := getApplicationSource(app)

if appSource.Kustomize == nil {
return "", nil
}

ksImages := appSource.Kustomize.Images

if ksImages == nil {
return "", nil
}

for _, a := range ksImages {
if a.Match(v1alpha1.KustomizeImage(ksImageName)) {
return string(a), nil
}
}

return "", nil
}

// SetKustomizeImage sets a Kustomize image for given application
func SetKustomizeImage(app *v1alpha1.Application, newImage *image.ContainerImage) error {
if appType := getApplicationType(app); appType != ApplicationTypeKustomize {
Expand Down
34 changes: 29 additions & 5 deletions pkg/argocd/update.go
Original file line number Diff line number Diff line change
Expand Up @@ -286,20 +286,32 @@ func UpdateApplication(updateConf *UpdateConfiguration, state *SyncIterationStat
}

if needsUpdate(updateableImage, applicationImage, latest) {
appImageWithTag := applicationImage.WithTag(latest)
appImageFullNameWithTag := appImageWithTag.GetFullNameWithTag()

// Check if new image is already set in Application Spec when write back is set to argocd
// and compare with new image
appImageSpec, err := getAppImage(&updateConf.UpdateApp.Application, appImageWithTag)
if err != nil {
continue
}
if appImageSpec == appImageFullNameWithTag {
imgCtx.Infof("New image %s already set in spec", appImageFullNameWithTag)
continue
}

imgCtx.Infof("Setting new image to %s", applicationImage.WithTag(latest).GetFullNameWithTag())
needUpdate = true
imgCtx.Infof("Setting new image to %s", appImageFullNameWithTag)

err = setAppImage(&updateConf.UpdateApp.Application, applicationImage.WithTag(latest))
err = setAppImage(&updateConf.UpdateApp.Application, appImageWithTag)

if err != nil {
imgCtx.Errorf("Error while trying to update image: %v", err)
result.NumErrors += 1
continue
} else {
containerImageNew := applicationImage.WithTag(latest)
imgCtx.Infof("Successfully updated image '%s' to '%s', but pending spec update (dry run=%v)", updateableImage.GetFullNameWithTag(), containerImageNew.GetFullNameWithTag(), updateConf.DryRun)
changeList = append(changeList, ChangeEntry{containerImageNew, updateableImage.ImageTag, containerImageNew.ImageTag})
imgCtx.Infof("Successfully updated image '%s' to '%s', but pending spec update (dry run=%v)", updateableImage.GetFullNameWithTag(), appImageFullNameWithTag, updateConf.DryRun)
changeList = append(changeList, ChangeEntry{appImageWithTag, updateableImage.ImageTag, appImageWithTag.ImageTag})
result.NumImagesUpdated += 1
}
} else {
Expand Down Expand Up @@ -382,6 +394,18 @@ func needsUpdate(updateableImage *image.ContainerImage, applicationImage *image.
return !updateableImage.ImageTag.Equals(latest) || applicationImage.KustomizeImage != nil && applicationImage.DiffersFrom(updateableImage, false)
}

func getAppImage(app *v1alpha1.Application, img *image.ContainerImage) (string, error) {
var err error
if appType := GetApplicationType(app); appType == ApplicationTypeKustomize {
return GetKustomizeImage(app, img)
} else if appType == ApplicationTypeHelm {
return GetHelmImage(app, img)
} else {
err = fmt.Errorf("could not update application %s - neither Helm nor Kustomize application", app)
return "", err
}
}

func setAppImage(app *v1alpha1.Application, img *image.ContainerImage) error {
var err error
if appType := GetApplicationType(app); appType == ApplicationTypeKustomize {
Expand Down

0 comments on commit 11e4c20

Please sign in to comment.