Skip to content

Commit 0350ee7

Browse files
authored
feat(updater): add fire and forget mode (#309)
1 parent 71044ba commit 0350ee7

File tree

4 files changed

+73
-0
lines changed

4 files changed

+73
-0
lines changed

cmd/argo-watcher/argocd/argo_status_updater.go

+8
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,9 @@ func (updater *ArgoStatusUpdater) WaitForRollout(task models.Task) {
9595

9696
// get application status
9797
status := application.GetRolloutStatus(task.ListImages(), updater.registryProxyUrl, updater.acceptSuspended)
98+
if application.IsFireAndForgetModeActive() {
99+
status = models.ArgoRolloutAppSuccess
100+
}
98101
if status == models.ArgoRolloutAppSuccess {
99102
log.Info().Str("id", task.Id).Msg("App is running on the expected version.")
100103
// deployment success
@@ -213,6 +216,11 @@ func (updater *ArgoStatusUpdater) waitRollout(task models.Task) (*models.Applica
213216
_ = retry.Do(func() error {
214217
application, err = updater.argo.api.GetApplication(task.App)
215218

219+
if application.IsFireAndForgetModeActive() {
220+
log.Debug().Str("id", task.Id).Msg("Fire and forge mode is active, skipping checks...")
221+
return nil
222+
}
223+
216224
if err != nil {
217225
// check if ArgoCD didn't have the app
218226
if task.IsAppNotFoundError(err) {

docs/git-integration.md

+10
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,16 @@ sandbox/charts/demo/.argocd-source-demo.yaml
7878

7979
> This is not an ideal solution, but so far it is the only way to reliably determine the correct override file to update.
8080

81+
### Fire and forget mode
82+
83+
In rare cases, we need to force update an application without waiting for image to be detected by ArgoCD as a running. For example for Applications with `CronJob` only.
84+
85+
The following annotation will force argo-watcher to just update the image, and consider application `deployed`:
86+
87+
```bash
88+
argo-watcher/fire-and-forget: "true"
89+
```
90+
8191
### Additional information
8292

8393
- The `app` alias is intended to correspond with an alias specified in the `argo-watcher/ALIAS.helm.image-tag` annotation.

internal/models/argo.go

+9
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ const (
2525
managedGitBranch = "argo-watcher/write-back-branch"
2626
managedGitPath = "argo-watcher/write-back-path"
2727
managedGitFile = "argo-watcher/write-back-filename"
28+
fireAndForgetAnnotation = "argo-watcher/fire-and-forget"
2829
)
2930

3031
type ApplicationOperationResource struct {
@@ -286,6 +287,14 @@ func (app *Application) UpdateGitImageTag(task *Task) error {
286287
return nil
287288
}
288289

290+
// IsFireAndForgetModeActive checks if 'fire-and-forget' mode is enabled in Application's annotations.
291+
func (app *Application) IsFireAndForgetModeActive() bool {
292+
if app.Metadata.Annotations == nil {
293+
return false
294+
}
295+
return app.Metadata.Annotations[fireAndForgetAnnotation] == "true"
296+
}
297+
289298
// extractManagedImages extracts the managed images from the application's annotations.
290299
// It returns a map of the managed images, where the key is the application alias and the value is the image name.
291300
func extractManagedImages(annotations map[string]string) (map[string]string, error) {

internal/models/argo_test.go

+46
Original file line numberDiff line numberDiff line change
@@ -386,3 +386,49 @@ func TestExtractManagedImages(t *testing.T) {
386386
})
387387
}
388388
}
389+
390+
func TestIsFireAndForgetModeActive(t *testing.T) {
391+
tt := []struct {
392+
name string
393+
app Application
394+
want bool
395+
}{
396+
{
397+
name: "FireAndForget mode active",
398+
app: Application{
399+
Metadata: ApplicationMetadata{
400+
Annotations: map[string]string{
401+
fireAndForgetAnnotation: "true",
402+
},
403+
},
404+
},
405+
want: true,
406+
},
407+
{
408+
name: "FireAndForget mode inactive",
409+
app: Application{
410+
Metadata: ApplicationMetadata{
411+
Annotations: map[string]string{
412+
fireAndForgetAnnotation: "false",
413+
},
414+
},
415+
},
416+
want: false,
417+
},
418+
{
419+
name: "Annotations are nil",
420+
app: Application{
421+
Metadata: ApplicationMetadata{
422+
Annotations: nil,
423+
},
424+
},
425+
want: false,
426+
},
427+
}
428+
429+
for _, tc := range tt {
430+
t.Run(tc.name, func(t *testing.T) {
431+
assert.Equal(t, tc.want, tc.app.IsFireAndForgetModeActive())
432+
})
433+
}
434+
}

0 commit comments

Comments
 (0)