diff --git a/.github/workflows/publish-docs.yml b/.github/workflows/publish-docs.yml deleted file mode 100644 index cf3ecaf3..00000000 --- a/.github/workflows/publish-docs.yml +++ /dev/null @@ -1,67 +0,0 @@ -# This workflow builds and deploys the Docusaurus documentation to GitHub Pages -# when changes are pushed to the main branch. -name: Deploy Docusaurus to GitHub Pages - -on: - workflow_dispatch: - push: - branches: - - main - paths: - - 'web/**' - -# Prevent parallel deployments when multiple commits are pushed to main -# in a short time. -concurrency: - group: "pages" - cancel-in-progress: false - -permissions: read-all - -jobs: - build: - runs-on: ubuntu-latest - permissions: - contents: read - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Setup Node - uses: actions/setup-node@v4 - with: - # Use the latest LTS version of Node.js already installed on the runner. - node-version: latest - check-latest: 'false' - cache: yarn - cache-dependency-path: web/yarn.lock - - - name: Setup Pages - uses: actions/configure-pages@v5 - - - name: Install dependencies - working-directory: web - run: yarn install --frozen-lockfile --non-interactive - - - name: Build website - working-directory: web - run: yarn build - - - name: Upload artifact - uses: actions/upload-pages-artifact@v3 - with: - path: web/build - - deploy: - permissions: - pages: write - id-token: write - environment: - name: github-pages - url: ${{ steps.deployment.outputs.page_url }} - needs: build - runs-on: ubuntu-latest - steps: - - name: Deploy to GitHub Pages - id: deployment - uses: actions/deploy-pages@v4 diff --git a/api/v1/objectstore_types.go b/api/v1/objectstore_types.go index 80c4742a..c33f085a 100644 --- a/api/v1/objectstore_types.go +++ b/api/v1/objectstore_types.go @@ -75,6 +75,12 @@ type RecoveryWindow struct { // The last successful backup time LastSuccessfulBackupTime *metav1.Time `json:"lastSuccussfulBackupTime,omitempty"` + + // The timestamp of the first WAL file successfully submitted to the object store + FirstWALSubmissionTime *metav1.Time `json:"firstWALSubmissionTime,omitempty"` + + // The timestamp of the last WAL file successfully submitted to the object store + LastWALSubmissionTime *metav1.Time `json:"lastWALSubmissionTime,omitempty"` } // +kubebuilder:object:root=true diff --git a/api/v1/zz_generated.deepcopy.go b/api/v1/zz_generated.deepcopy.go index 11fb2aea..f7b60c42 100644 --- a/api/v1/zz_generated.deepcopy.go +++ b/api/v1/zz_generated.deepcopy.go @@ -157,6 +157,14 @@ func (in *RecoveryWindow) DeepCopyInto(out *RecoveryWindow) { in, out := &in.LastSuccessfulBackupTime, &out.LastSuccessfulBackupTime *out = (*in).DeepCopy() } + if in.FirstWALSubmissionTime != nil { + in, out := &in.FirstWALSubmissionTime, &out.FirstWALSubmissionTime + *out = (*in).DeepCopy() + } + if in.LastWALSubmissionTime != nil { + in, out := &in.LastWALSubmissionTime, &out.LastWALSubmissionTime + *out = (*in).DeepCopy() + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RecoveryWindow. diff --git a/config/crd/bases/barmancloud.cnpg.io_objectstores.yaml b/config/crd/bases/barmancloud.cnpg.io_objectstores.yaml index 6fb87b51..7dfcdddc 100644 --- a/config/crd/bases/barmancloud.cnpg.io_objectstores.yaml +++ b/config/crd/bases/barmancloud.cnpg.io_objectstores.yaml @@ -609,10 +609,20 @@ spec: restored. format: date-time type: string + firstWALSubmissionTime: + description: The timestamp of the first WAL file successfully + submitted to the object store + format: date-time + type: string lastSuccussfulBackupTime: description: The last successful backup time format: date-time type: string + lastWALSubmissionTime: + description: The timestamp of the last WAL file successfully + submitted to the object store + format: date-time + type: string type: object description: ServerRecoveryWindow maps each server to its recovery window diff --git a/containers/sidecar-requirements.txt b/containers/sidecar-requirements.txt index 632b4ca3..d6c282f0 100644 --- a/containers/sidecar-requirements.txt +++ b/containers/sidecar-requirements.txt @@ -545,9 +545,9 @@ python-snappy==0.7.3 \ --hash=sha256:074c0636cfcd97e7251330f428064050ac81a52c62ed884fc2ddebbb60ed7f50 \ --hash=sha256:40216c1badfb2d38ac781ecb162a1d0ec40f8ee9747e610bcfefdfa79486cee3 # via barman -requests==2.32.3 \ - --hash=sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760 \ - --hash=sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6 +requests==2.32.4 \ + --hash=sha256:27babd3cda2a6d50b30443204ee89830707d396671944c998b5975b031ac2b2c \ + --hash=sha256:27d0316682c8a29834d3264820024b62a36942083d52caf2f14c0591336d3422 # via # azure-core # google-api-core diff --git a/internal/cnpgi/common/wal.go b/internal/cnpgi/common/wal.go index 0da8a396..ef8dfbcc 100644 --- a/internal/cnpgi/common/wal.go +++ b/internal/cnpgi/common/wal.go @@ -17,6 +17,7 @@ import ( walUtils "github.com/cloudnative-pg/machinery/pkg/fileutils/wals" "github.com/cloudnative-pg/machinery/pkg/log" apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" "sigs.k8s.io/controller-runtime/pkg/client" @@ -184,6 +185,12 @@ func (w WALServiceImplementation) Archive( } } + // Update WAL submission timing in ObjectStore status after successful archiving + if err := w.updateWALSubmissionTime(ctx, &objectStore, configuration.ServerName); err != nil { + contextLogger.Error(err, "failed to update WAL submission time in ObjectStore status") + // Don't fail the archiving operation for status update errors + } + return &wal.WALArchiveResult{}, nil } @@ -469,3 +476,30 @@ func isEndOfWALStream(results []barmanRestorer.Result) bool { return false } + +// updateWALSubmissionTime updates the WAL submission timing in the ObjectStore status +func (w WALServiceImplementation) updateWALSubmissionTime( + ctx context.Context, + objectStore *barmancloudv1.ObjectStore, + serverName string, +) error { + now := metav1.NewTime(time.Now()) + + if objectStore.Status.ServerRecoveryWindow == nil { + objectStore.Status.ServerRecoveryWindow = make(map[string]barmancloudv1.RecoveryWindow) + } + + recoveryWindow := objectStore.Status.ServerRecoveryWindow[serverName] + + // Set first WAL submission time if not already set + if recoveryWindow.FirstWALSubmissionTime == nil { + recoveryWindow.FirstWALSubmissionTime = &now + } + + // Always update last WAL submission time + recoveryWindow.LastWALSubmissionTime = &now + + objectStore.Status.ServerRecoveryWindow[serverName] = recoveryWindow + + return w.Client.Status().Update(ctx, objectStore) +} diff --git a/internal/cnpgi/instance/retention.go b/internal/cnpgi/instance/retention.go index 6b68dfb7..37f475e1 100644 --- a/internal/cnpgi/instance/retention.go +++ b/internal/cnpgi/instance/retention.go @@ -176,14 +176,21 @@ func (c *CatalogMaintenanceRunnable) updateRecoveryWindow( return ptr.To(metav1.NewTime(*t)) } + if objectStore.Status.ServerRecoveryWindow == nil { + objectStore.Status.ServerRecoveryWindow = make(map[string]barmancloudv1.RecoveryWindow) + } + + // get existing recovery window to preserve WAL submission timing + existingWindow := objectStore.Status.ServerRecoveryWindow[serverName] + recoveryWindow := barmancloudv1.RecoveryWindow{ FirstRecoverabilityPoint: convertTime(backupList.GetFirstRecoverabilityPoint()), LastSuccessfulBackupTime: convertTime(backupList.GetLastSuccessfulBackupTime()), + // preserve existing WAL submission timing + FirstWALSubmissionTime: existingWindow.FirstWALSubmissionTime, + LastWALSubmissionTime: existingWindow.LastWALSubmissionTime, } - if objectStore.Status.ServerRecoveryWindow == nil { - objectStore.Status.ServerRecoveryWindow = make(map[string]barmancloudv1.RecoveryWindow) - } objectStore.Status.ServerRecoveryWindow[serverName] = recoveryWindow return c.Client.Status().Update(ctx, objectStore) diff --git a/kubernetes/kustomization.yaml b/kubernetes/kustomization.yaml index b4ebc9e3..f264f94e 100644 --- a/kubernetes/kustomization.yaml +++ b/kubernetes/kustomization.yaml @@ -11,9 +11,9 @@ resources: - ../config/rbac images: - name: plugin-barman-cloud - newName: ghcr.io/cloudnative-pg/plugin-barman-cloud-testing + newName: ghcr.io/edkadigital/plugin-barman-cloud-testing newTag: main secretGenerator: - literals: - - SIDECAR_IMAGE=ghcr.io/cloudnative-pg/plugin-barman-cloud-sidecar-testing:main + - SIDECAR_IMAGE=ghcr.io/edkadigital/plugin-barman-cloud-sidecar-testing:main name: plugin-barman-cloud diff --git a/manifest.yaml b/manifest.yaml index c43ef4b5..e4adbb52 100644 --- a/manifest.yaml +++ b/manifest.yaml @@ -608,10 +608,20 @@ spec: restored. format: date-time type: string + firstWALSubmissionTime: + description: The timestamp of the first WAL file successfully + submitted to the object store + format: date-time + type: string lastSuccussfulBackupTime: description: The last successful backup time format: date-time type: string + lastWALSubmissionTime: + description: The timestamp of the last WAL file successfully + submitted to the object store + format: date-time + type: string type: object description: ServerRecoveryWindow maps each server to its recovery window @@ -927,7 +937,7 @@ spec: secretKeyRef: key: SIDECAR_IMAGE name: plugin-barman-cloud-8tfddg42gf - image: ghcr.io/cloudnative-pg/plugin-barman-cloud-testing:main + image: ghcr.io/edkadigital/plugin-barman-cloud-testing:main name: barman-cloud ports: - containerPort: 9090 diff --git a/web/docs/images.md b/web/docs/images.md index f6c32d34..816d0792 100644 --- a/web/docs/images.md +++ b/web/docs/images.md @@ -16,7 +16,7 @@ The Barman Cloud Plugin is distributed using two container images: The plugin image contains the logic required to operate the Barman Cloud Plugin within your Kubernetes environment with CloudNativePG. It is published on the -GitHub Container Registry at `ghcr.io/cloudnative-pg/plugin-barman-cloud`. +GitHub Container Registry at `ghcr.io/edkadigital/plugin-barman-cloud`. This image is built from the [`Dockerfile.plugin`](https://github.com/cloudnative-pg/plugin-barman-cloud/blob/main/containers/Dockerfile.plugin) @@ -28,7 +28,7 @@ The sidecar image is used within each PostgreSQL pod in the cluster. It includes the latest supported version of Barman Cloud and is responsible for performing WAL archiving and backups on behalf of CloudNativePG. -It is available at `ghcr.io/cloudnative-pg/plugin-barman-cloud-sidecar` and is +It is available at `ghcr.io/edkadigital/plugin-barman-cloud-sidecar` and is built from the [`Dockerfile.sidecar`](https://github.com/cloudnative-pg/plugin-barman-cloud/blob/main/containers/Dockerfile.sidecar). diff --git a/web/versioned_docs/version-0.4.0/images.md b/web/versioned_docs/version-0.4.0/images.md index f6c32d34..816d0792 100644 --- a/web/versioned_docs/version-0.4.0/images.md +++ b/web/versioned_docs/version-0.4.0/images.md @@ -16,7 +16,7 @@ The Barman Cloud Plugin is distributed using two container images: The plugin image contains the logic required to operate the Barman Cloud Plugin within your Kubernetes environment with CloudNativePG. It is published on the -GitHub Container Registry at `ghcr.io/cloudnative-pg/plugin-barman-cloud`. +GitHub Container Registry at `ghcr.io/edkadigital/plugin-barman-cloud`. This image is built from the [`Dockerfile.plugin`](https://github.com/cloudnative-pg/plugin-barman-cloud/blob/main/containers/Dockerfile.plugin) @@ -28,7 +28,7 @@ The sidecar image is used within each PostgreSQL pod in the cluster. It includes the latest supported version of Barman Cloud and is responsible for performing WAL archiving and backups on behalf of CloudNativePG. -It is available at `ghcr.io/cloudnative-pg/plugin-barman-cloud-sidecar` and is +It is available at `ghcr.io/edkadigital/plugin-barman-cloud-sidecar` and is built from the [`Dockerfile.sidecar`](https://github.com/cloudnative-pg/plugin-barman-cloud/blob/main/containers/Dockerfile.sidecar). diff --git a/web/versioned_docs/version-0.4.1/images.md b/web/versioned_docs/version-0.4.1/images.md index f6c32d34..816d0792 100644 --- a/web/versioned_docs/version-0.4.1/images.md +++ b/web/versioned_docs/version-0.4.1/images.md @@ -16,7 +16,7 @@ The Barman Cloud Plugin is distributed using two container images: The plugin image contains the logic required to operate the Barman Cloud Plugin within your Kubernetes environment with CloudNativePG. It is published on the -GitHub Container Registry at `ghcr.io/cloudnative-pg/plugin-barman-cloud`. +GitHub Container Registry at `ghcr.io/edkadigital/plugin-barman-cloud`. This image is built from the [`Dockerfile.plugin`](https://github.com/cloudnative-pg/plugin-barman-cloud/blob/main/containers/Dockerfile.plugin) @@ -28,7 +28,7 @@ The sidecar image is used within each PostgreSQL pod in the cluster. It includes the latest supported version of Barman Cloud and is responsible for performing WAL archiving and backups on behalf of CloudNativePG. -It is available at `ghcr.io/cloudnative-pg/plugin-barman-cloud-sidecar` and is +It is available at `ghcr.io/edkadigital/plugin-barman-cloud-sidecar` and is built from the [`Dockerfile.sidecar`](https://github.com/cloudnative-pg/plugin-barman-cloud/blob/main/containers/Dockerfile.sidecar). diff --git a/web/versioned_docs/version-0.5.0/images.md b/web/versioned_docs/version-0.5.0/images.md index f6c32d34..816d0792 100644 --- a/web/versioned_docs/version-0.5.0/images.md +++ b/web/versioned_docs/version-0.5.0/images.md @@ -16,7 +16,7 @@ The Barman Cloud Plugin is distributed using two container images: The plugin image contains the logic required to operate the Barman Cloud Plugin within your Kubernetes environment with CloudNativePG. It is published on the -GitHub Container Registry at `ghcr.io/cloudnative-pg/plugin-barman-cloud`. +GitHub Container Registry at `ghcr.io/edkadigital/plugin-barman-cloud`. This image is built from the [`Dockerfile.plugin`](https://github.com/cloudnative-pg/plugin-barman-cloud/blob/main/containers/Dockerfile.plugin) @@ -28,7 +28,7 @@ The sidecar image is used within each PostgreSQL pod in the cluster. It includes the latest supported version of Barman Cloud and is responsible for performing WAL archiving and backups on behalf of CloudNativePG. -It is available at `ghcr.io/cloudnative-pg/plugin-barman-cloud-sidecar` and is +It is available at `ghcr.io/edkadigital/plugin-barman-cloud-sidecar` and is built from the [`Dockerfile.sidecar`](https://github.com/cloudnative-pg/plugin-barman-cloud/blob/main/containers/Dockerfile.sidecar).