Compare commits

...

3 Commits

Author SHA1 Message Date
Gabriel José Mouallem Rodrigues
9faccee9bf
Merge eefb45ca5a into dd799d8ed1 2026-07-13 09:21:08 +02:00
Niccolò Fei
dd799d8ed1
ci: fix image tag mismatch when running via workflow_dispatch (#995)
Closes #994

Signed-off-by: Niccolò Fei <niccolo.fei@enterprisedb.com>
2026-07-13 14:26:17 +08:00
Gabriel Jose Mouallem Rodrigues
eefb45ca5a fix: add retry logic to updateRecoveryWindow for concurrent status updates
When backup completion and retention policy enforcement run concurrently,
both call updateRecoveryWindow to update the ObjectStore status. This can
cause "object has been modified" errors due to Kubernetes optimistic
concurrency control.

This change wraps the status update in retry.RetryOnConflict, matching
the pattern already used in setLastFailedBackupTime in the same file.
The retry logic fetches a fresh copy of the ObjectStore before each
update attempt, ensuring the resourceVersion is current.

Fixes #758

Signed-off-by: Gabriel Mouallem <gabriel@latitude.sh>
2026-02-03 15:01:30 -03:00
2 changed files with 31 additions and 17 deletions

View File

@ -360,7 +360,9 @@ tasks:
SIDECAR_IMAGE_NAME: ghcr.io/{{.GITHUB_REPOSITORY}}-sidecar{{if not (hasPrefix "refs/tags/v" .GITHUB_REF)}}-testing{{end}} SIDECAR_IMAGE_NAME: ghcr.io/{{.GITHUB_REPOSITORY}}-sidecar{{if not (hasPrefix "refs/tags/v" .GITHUB_REF)}}-testing{{end}}
# remove /merge suffix from the branch name. This is a workaround for the GitHub workflow on PRs, # remove /merge suffix from the branch name. This is a workaround for the GitHub workflow on PRs,
# where the branch name is suffixed with /merge. Prepend pr- to the branch name on PRs. # where the branch name is suffixed with /merge. Prepend pr- to the branch name on PRs.
IMAGE_VERSION: '{{regexReplaceAll "(\\d+)/merge" .GITHUB_REF_NAME "pr-${1}"}}' # Any remaining "/" (e.g. from namespaced branches like "dev/foo") is replaced with "-" since
# "/" is not a valid character in a Docker tag.
IMAGE_VERSION: '{{replace "/" "-" (regexReplaceAll "(\\d+)/merge" .GITHUB_REF_NAME "pr-${1}")}}'
env: env:
# renovate: datasource=git-refs depName=docker lookupName=https://github.com/purpleclay/daggerverse currentValue=main # renovate: datasource=git-refs depName=docker lookupName=https://github.com/purpleclay/daggerverse currentValue=main
DAGGER_DOCKER_SHA: ee12c1a4a2630e194ec20c5a9959183e3a78c192 DAGGER_DOCKER_SHA: ee12c1a4a2630e194ec20c5a9959183e3a78c192
@ -450,7 +452,9 @@ tasks:
SIDECAR_IMAGE_NAME: ghcr.io/{{.GITHUB_REPOSITORY}}-sidecar{{if not (hasPrefix "refs/tags/v" .GITHUB_REF)}}-testing{{end}} SIDECAR_IMAGE_NAME: ghcr.io/{{.GITHUB_REPOSITORY}}-sidecar{{if not (hasPrefix "refs/tags/v" .GITHUB_REF)}}-testing{{end}}
# remove /merge suffix from the branch name. This is a workaround for the GitHub workflow on PRs, # remove /merge suffix from the branch name. This is a workaround for the GitHub workflow on PRs,
# where the branch name is suffixed with /merge. Prepend pr- to the branch name on PRs. # where the branch name is suffixed with /merge. Prepend pr- to the branch name on PRs.
IMAGE_VERSION: '{{regexReplaceAll "(\\d+)/merge" .GITHUB_REF_NAME "pr-${1}"}}' # Any remaining "/" (e.g. from namespaced branches like "dev/foo") is replaced with "-" since
# "/" is not a valid character in a Docker tag.
IMAGE_VERSION: '{{replace "/" "-" (regexReplaceAll "(\\d+)/merge" .GITHUB_REF_NAME "pr-${1}")}}'
env: env:
# renovate: datasource=git-refs depName=kustomize lookupName=https://github.com/sagikazarmark/daggerverse currentValue=main # renovate: datasource=git-refs depName=kustomize lookupName=https://github.com/sagikazarmark/daggerverse currentValue=main
DAGGER_KUSTOMIZE_SHA: ff27cd50f6b4eed2e3753c520632cd6099e1ce52 DAGGER_KUSTOMIZE_SHA: ff27cd50f6b4eed2e3753c520632cd6099e1ce52

View File

@ -33,7 +33,8 @@ import (
) )
// updateRecoveryWindow updates the recovery window inside the object // updateRecoveryWindow updates the recovery window inside the object
// store status subresource // store status subresource. It uses retry logic to handle concurrent
// updates from backup completion and retention policy enforcement.
func updateRecoveryWindow( func updateRecoveryWindow(
ctx context.Context, ctx context.Context,
c client.Client, c client.Client,
@ -41,24 +42,33 @@ func updateRecoveryWindow(
objectStore *barmancloudv1.ObjectStore, objectStore *barmancloudv1.ObjectStore,
serverName string, serverName string,
) error { ) error {
// Set the recovery window inside the barman object store object objectStoreKey := client.ObjectKeyFromObject(objectStore)
convertTime := func(t *time.Time) *metav1.Time {
if t == nil { return retry.RetryOnConflict(retry.DefaultBackoff, func() error {
return nil var freshObjectStore barmancloudv1.ObjectStore
if err := c.Get(ctx, objectStoreKey, &freshObjectStore); err != nil {
return err
} }
return ptr.To(metav1.NewTime(*t))
}
recoveryWindow := objectStore.Status.ServerRecoveryWindow[serverName] // Set the recovery window inside the barman object store object
recoveryWindow.FirstRecoverabilityPoint = convertTime(backupList.GetFirstRecoverabilityPoint()) convertTime := func(t *time.Time) *metav1.Time {
recoveryWindow.LastSuccessfulBackupTime = convertTime(backupList.GetLastSuccessfulBackupTime()) if t == nil {
return nil
}
return ptr.To(metav1.NewTime(*t))
}
if objectStore.Status.ServerRecoveryWindow == nil { recoveryWindow := freshObjectStore.Status.ServerRecoveryWindow[serverName]
objectStore.Status.ServerRecoveryWindow = make(map[string]barmancloudv1.RecoveryWindow) recoveryWindow.FirstRecoverabilityPoint = convertTime(backupList.GetFirstRecoverabilityPoint())
} recoveryWindow.LastSuccessfulBackupTime = convertTime(backupList.GetLastSuccessfulBackupTime())
objectStore.Status.ServerRecoveryWindow[serverName] = recoveryWindow
return c.Status().Update(ctx, objectStore) if freshObjectStore.Status.ServerRecoveryWindow == nil {
freshObjectStore.Status.ServerRecoveryWindow = make(map[string]barmancloudv1.RecoveryWindow)
}
freshObjectStore.Status.ServerRecoveryWindow[serverName] = recoveryWindow
return c.Status().Update(ctx, &freshObjectStore)
})
} }
// setLastFailedBackupTime sets the last failed backup time in the // setLastFailedBackupTime sets the last failed backup time in the