Merge branch 'main' into correct-cluster-serviceaccount

This commit is contained in:
Toomas Pelberg 2026-09-03 23:38:15 +03:00 committed by GitHub
commit f68774e02e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
222 changed files with 4855 additions and 16644 deletions

View File

@ -6,14 +6,18 @@ on:
permissions: read-all permissions: read-all
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
jobs: jobs:
ci: ci:
runs-on: ubuntu-latest runs-on: ${{ vars.CI_RUNNERS || 'ubuntu-latest' }}
permissions: permissions:
packages: write contents: read
contents: write
steps: steps:
- name: Cleanup Disk - name: Cleanup Disk
if: vars.CI_RUNNERS == '' || vars.CI_RUNNERS == 'ubuntu-latest'
uses: jlumbroso/free-disk-space@v1.3.1 uses: jlumbroso/free-disk-space@v1.3.1
with: with:
android: true android: true
@ -23,6 +27,7 @@ jobs:
large-packages: false large-packages: false
swap-storage: false swap-storage: false
- name: Cleanup docker cache - name: Cleanup docker cache
if: vars.CI_RUNNERS == '' || vars.CI_RUNNERS == 'ubuntu-latest'
run: | run: |
echo "-------------Disk info before cleanup----------------" echo "-------------Disk info before cleanup----------------"
df -h df -h
@ -32,24 +37,43 @@ jobs:
df -h df -h
echo "-----------------------------------------------------" echo "-----------------------------------------------------"
- name: Checkout - name: Checkout
uses: actions/checkout@v6 uses: actions/checkout@v7.0.1
# We need the full history for the commitlint task # We need the full history for the commitlint task
with: with:
fetch-depth: 0 fetch-depth: 0
ref: ${{ github.event.pull_request.head.sha }} ref: ${{ github.event.pull_request.head.sha }}
- name: Install QEMU static binaries
uses: docker/setup-qemu-action@v4
- name: Install Task - name: Install Task
uses: arduino/setup-task@v2 uses: arduino/setup-task@v3.0.0
- name: Install Dagger - name: Install Dagger
env: env:
# renovate: datasource=github-tags depName=dagger/dagger versioning=semver # renovate: datasource=github-tags depName=dagger/dagger versioning=semver
DAGGER_VERSION: 0.20.8 DAGGER_VERSION: 0.21.9
run: | run: |
curl -L https://dl.dagger.io/dagger/install.sh | BIN_DIR=$HOME/.local/bin sh curl -L https://dl.dagger.io/dagger/install.sh | BIN_DIR=$HOME/.local/bin sh
- name: Run CI task - name: Run CI task
run: | run: |
task ci task ci
publish:
runs-on: ${{ vars.CI_RUNNERS || 'ubuntu-latest' }}
permissions:
contents: read
packages: write
steps:
- name: Checkout
uses: actions/checkout@v7.0.1
with:
ref: ${{ github.event.pull_request.head.sha }}
- name: Install QEMU static binaries
uses: docker/setup-qemu-action@v4
- name: Install Task
uses: arduino/setup-task@v3.0.0
- name: Install Dagger
env:
# renovate: datasource=github-tags depName=dagger/dagger versioning=semver
DAGGER_VERSION: 0.21.9
run: |
curl -L https://dl.dagger.io/dagger/install.sh | BIN_DIR=$HOME/.local/bin sh
- name: Write manifest - name: Write manifest
run: | run: |
task manifest task manifest

View File

@ -20,15 +20,15 @@ permissions: read-all
jobs: jobs:
build: build:
runs-on: ubuntu-latest runs-on: ${{ vars.CI_RUNNERS || 'ubuntu-latest' }}
permissions: permissions:
contents: read contents: read
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v6 uses: actions/checkout@v7.0.1
- name: Setup Node - name: Setup Node
uses: actions/setup-node@v6 uses: actions/setup-node@v7
with: with:
# Use the latest LTS version of Node.js already installed on the runner. # Use the latest LTS version of Node.js already installed on the runner.
node-version: latest node-version: latest
@ -60,7 +60,7 @@ jobs:
name: github-pages name: github-pages
url: ${{ steps.deployment.outputs.page_url }} url: ${{ steps.deployment.outputs.page_url }}
needs: build needs: build
runs-on: ubuntu-latest runs-on: ${{ vars.CI_RUNNERS || 'ubuntu-latest' }}
steps: steps:
- name: Deploy to GitHub Pages - name: Deploy to GitHub Pages
id: deployment id: deployment

View File

@ -9,7 +9,7 @@ permissions: read-all
jobs: jobs:
release-please: release-please:
runs-on: ubuntu-latest runs-on: ${{ vars.CI_RUNNERS || 'ubuntu-latest' }}
permissions: permissions:
contents: write contents: write
pull-requests: write pull-requests: write
@ -19,19 +19,19 @@ jobs:
# We'll use the cli until there's a fix for # We'll use the cli until there's a fix for
# https://github.com/googleapis/release-please/issues/2280. # https://github.com/googleapis/release-please/issues/2280.
- name: Checkout - name: Checkout
uses: actions/checkout@v6 uses: actions/checkout@v7.0.1
- name: Install node - name: Install node
uses: actions/setup-node@v6 uses: actions/setup-node@v7
with: with:
node-version: 24 node-version: 24
- name: Install QEMU static binaries - name: Install QEMU static binaries
uses: docker/setup-qemu-action@v4 uses: docker/setup-qemu-action@v4
- name: Install Task - name: Install Task
uses: arduino/setup-task@v2 uses: arduino/setup-task@v3.0.0
- name: Install Dagger - name: Install Dagger
env: env:
# renovate: datasource=github-tags depName=dagger/dagger versioning=semver # renovate: datasource=github-tags depName=dagger/dagger versioning=semver
DAGGER_VERSION: 0.20.8 DAGGER_VERSION: 0.21.9
run: | run: |
curl -L https://dl.dagger.io/dagger/install.sh | BIN_DIR=$HOME/.local/bin sh curl -L https://dl.dagger.io/dagger/install.sh | BIN_DIR=$HOME/.local/bin sh
- name: Create image and manifest - name: Create image and manifest

View File

@ -7,21 +7,21 @@ permissions: read-all
jobs: jobs:
release-publish-artifacts: release-publish-artifacts:
runs-on: ubuntu-latest runs-on: ${{ vars.CI_RUNNERS || 'ubuntu-latest' }}
permissions: permissions:
packages: write packages: write
contents: write contents: write
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v6 uses: actions/checkout@v7.0.1
- name: Install QEMU static binaries - name: Install QEMU static binaries
uses: docker/setup-qemu-action@v4 uses: docker/setup-qemu-action@v4
- name: Install Task - name: Install Task
uses: arduino/setup-task@v2 uses: arduino/setup-task@v3.0.0
- name: Install Dagger - name: Install Dagger
env: env:
# renovate: datasource=github-tags depName=dagger/dagger versioning=semver # renovate: datasource=github-tags depName=dagger/dagger versioning=semver
DAGGER_VERSION: 0.20.8 DAGGER_VERSION: 0.21.9
run: | run: |
curl -L https://dl.dagger.io/dagger/install.sh | BIN_DIR=$HOME/.local/bin sh curl -L https://dl.dagger.io/dagger/install.sh | BIN_DIR=$HOME/.local/bin sh
- name: Create image and manifest - name: Create image and manifest

View File

@ -1,3 +1,3 @@
{ {
".": "0.12.0" ".": "0.15.0"
} }

View File

@ -1,5 +1,83 @@
# Changelog # Changelog
## [0.15.0](https://github.com/cloudnative-pg/plugin-barman-cloud/compare/v0.14.0...v0.15.0) (2026-09-03)
### Features
* **deps:** Bump Barman version to 3.20.0 ([#1090](https://github.com/cloudnative-pg/plugin-barman-cloud/issues/1090)) ([1bb6bab](https://github.com/cloudnative-pg/plugin-barman-cloud/commit/1bb6bab640f5adf038c86e33c96d42765d2aa708))
* Serve restore hooks from the instance sidecar ([#1025](https://github.com/cloudnative-pg/plugin-barman-cloud/issues/1025)) ([7bb01a8](https://github.com/cloudnative-pg/plugin-barman-cloud/commit/7bb01a865b15c0f5f608c8bfbc7561daadf2de3d))
### Bug Fixes
* **deps:** Update all non-major go dependencies ([#1041](https://github.com/cloudnative-pg/plugin-barman-cloud/issues/1041)) ([9a3cc0d](https://github.com/cloudnative-pg/plugin-barman-cloud/commit/9a3cc0d35492697a31ddc13b87f269cca3e83ea5))
* **deps:** Update all non-major go dependencies ([#1086](https://github.com/cloudnative-pg/plugin-barman-cloud/issues/1086)) ([31b2553](https://github.com/cloudnative-pg/plugin-barman-cloud/commit/31b25538bf6d8fadf2cd28c15b23c9c81ae22fac))
* **deps:** Update kubernetes monorepo to v0.37.0 ([#1084](https://github.com/cloudnative-pg/plugin-barman-cloud/issues/1084)) ([b15b661](https://github.com/cloudnative-pg/plugin-barman-cloud/commit/b15b661648792cb2cb899ee628b8a3aa909c3fc8))
* **deps:** Update module google.golang.org/grpc to v1.83.2 ([#1073](https://github.com/cloudnative-pg/plugin-barman-cloud/issues/1073)) ([b3d948c](https://github.com/cloudnative-pg/plugin-barman-cloud/commit/b3d948ce821c68be1d99c84c679e020b5f3db363))
## [0.14.0](https://github.com/cloudnative-pg/plugin-barman-cloud/compare/v0.13.0...v0.14.0) (2026-07-29)
### Features
* Honor the operator's check_empty_wal_archive decision ([#1009](https://github.com/cloudnative-pg/plugin-barman-cloud/issues/1009)) ([7bcb74b](https://github.com/cloudnative-pg/plugin-barman-cloud/commit/7bcb74b987a3cca232c6f8021157eb711a1289b0))
### Bug Fixes
* **deps:** Update all non-major go dependencies ([#963](https://github.com/cloudnative-pg/plugin-barman-cloud/issues/963)) ([f949241](https://github.com/cloudnative-pg/plugin-barman-cloud/commit/f94924105b51b7b015338d4ec2c71904ef8d095c))
* **deps:** Update all non-major go dependencies ([#979](https://github.com/cloudnative-pg/plugin-barman-cloud/issues/979)) ([bf52833](https://github.com/cloudnative-pg/plugin-barman-cloud/commit/bf5283359478071f116464c14a7a3d3d0a358eea))
* **deps:** Update all non-major go dependencies ([#982](https://github.com/cloudnative-pg/plugin-barman-cloud/issues/982)) ([5f84ecc](https://github.com/cloudnative-pg/plugin-barman-cloud/commit/5f84ecce4a9433da27346d194f6a4b456d59f75f))
* **deps:** Update all non-major go dependencies to 53ffbf0 ([#973](https://github.com/cloudnative-pg/plugin-barman-cloud/issues/973)) ([7190349](https://github.com/cloudnative-pg/plugin-barman-cloud/commit/719034947061f72ce8fcc919f5e209aa7fd7d874))
* **deps:** Update all non-major go dependencies to 592f761 ([#972](https://github.com/cloudnative-pg/plugin-barman-cloud/issues/972)) ([2fa63c4](https://github.com/cloudnative-pg/plugin-barman-cloud/commit/2fa63c4bc28c03fbb79e3751a001868e991b8917))
* **deps:** Update all non-major go dependencies to 8d9302e ([#975](https://github.com/cloudnative-pg/plugin-barman-cloud/issues/975)) ([0c687cb](https://github.com/cloudnative-pg/plugin-barman-cloud/commit/0c687cbbf13f4ce5ca1690d4dcf768d76cb4731a))
* **deps:** Update all non-major go dependencies to v2.30.0 ([#957](https://github.com/cloudnative-pg/plugin-barman-cloud/issues/957)) ([61b82ce](https://github.com/cloudnative-pg/plugin-barman-cloud/commit/61b82ce250e95f04d49d0fb427e79364f2d900c0))
* **deps:** Update documentation dependencies to v3.10.2 ([#1001](https://github.com/cloudnative-pg/plugin-barman-cloud/issues/1001)) ([88f2e29](https://github.com/cloudnative-pg/plugin-barman-cloud/commit/88f2e296746f495d3e7b27cd7297e772d53f61e9))
* **deps:** Update github.com/cloudnative-pg/barman-cloud digest to 950b0f5 ([#1022](https://github.com/cloudnative-pg/plugin-barman-cloud/issues/1022)) ([98537c4](https://github.com/cloudnative-pg/plugin-barman-cloud/commit/98537c4d0e899e136e85237b29020a9bbbf9f5aa))
* **deps:** Update k8s.io/utils digest to a95e086 ([#968](https://github.com/cloudnative-pg/plugin-barman-cloud/issues/968)) ([f7f0136](https://github.com/cloudnative-pg/plugin-barman-cloud/commit/f7f0136520b1032698b26e33e6eff1caa01173f5))
* **deps:** Update k8s.io/utils digest to be93311 ([#986](https://github.com/cloudnative-pg/plugin-barman-cloud/issues/986)) ([2cc4e99](https://github.com/cloudnative-pg/plugin-barman-cloud/commit/2cc4e9905db6b1d1c5788dd6093a1a7d330d9064))
* **deps:** Update kubernetes monorepo to v0.36.2 ([#958](https://github.com/cloudnative-pg/plugin-barman-cloud/issues/958)) ([030b28c](https://github.com/cloudnative-pg/plugin-barman-cloud/commit/030b28c4b9aee205f7a43f1fcc4da363b50839d9))
* **deps:** Update kubernetes monorepo to v0.36.3 ([#1031](https://github.com/cloudnative-pg/plugin-barman-cloud/issues/1031)) ([ce81794](https://github.com/cloudnative-pg/plugin-barman-cloud/commit/ce8179442b49e0686ec05505b4ba79360b54ec8c))
* **deps:** Update module github.com/cloudnative-pg/cnpg-i to v0.6.0 ([#1021](https://github.com/cloudnative-pg/plugin-barman-cloud/issues/1021)) ([13450a3](https://github.com/cloudnative-pg/plugin-barman-cloud/commit/13450a370d16fda87c128fc3a2f420f5b0cc442b))
* **deps:** Update module google.golang.org/grpc to v1.82.1 ([#1008](https://github.com/cloudnative-pg/plugin-barman-cloud/issues/1008)) ([3c27364](https://github.com/cloudnative-pg/plugin-barman-cloud/commit/3c273641e3fb8027011be74ebb09d0ba91f71c7b))
* **docs:** Fix broken anchor link in concepts.md ([#1013](https://github.com/cloudnative-pg/plugin-barman-cloud/issues/1013)) ([9c84d06](https://github.com/cloudnative-pg/plugin-barman-cloud/commit/9c84d069edc39c2848813aff5fd13c13c2ac8ff9))
* Inject barman sidecar in replica clusters bootstrapped with pg_basebackup ([#965](https://github.com/cloudnative-pg/plugin-barman-cloud/issues/965)) ([eb5e860](https://github.com/cloudnative-pg/plugin-barman-cloud/commit/eb5e8607752d60bf36b4a9ddcaa5bb447f323012))
* Reduce startupProbe periodSeconds without losing failure tolerance ([#992](https://github.com/cloudnative-pg/plugin-barman-cloud/issues/992)) ([bf95543](https://github.com/cloudnative-pg/plugin-barman-cloud/commit/bf955430cb58987bbbe3cd2925ea06700cf85609)), refs [#991](https://github.com/cloudnative-pg/plugin-barman-cloud/issues/991)
* Restore WAL from replica source during designated primary promotion ([#966](https://github.com/cloudnative-pg/plugin-barman-cloud/issues/966)) ([c34b232](https://github.com/cloudnative-pg/plugin-barman-cloud/commit/c34b2329ea39f9a1030d9d1225aa4d0a276255eb))
* **walrestore:** Serve pg_rewind without prefetching and flag machinery ([#1007](https://github.com/cloudnative-pg/plugin-barman-cloud/issues/1007)) ([fb3f0f9](https://github.com/cloudnative-pg/plugin-barman-cloud/commit/fb3f0f9dabba85d87af85418d58b2f8224ed6305))
## [0.13.0](https://github.com/cloudnative-pg/plugin-barman-cloud/compare/v0.12.0...v0.13.0) (2026-06-10)
### Features
* Configure k8s recommended labels on subresources ([#865](https://github.com/cloudnative-pg/plugin-barman-cloud/issues/865)) ([4bbaf18](https://github.com/cloudnative-pg/plugin-barman-cloud/commit/4bbaf18cd30174229d98e23151d2d257c90b561a)), closes [#545](https://github.com/cloudnative-pg/plugin-barman-cloud/issues/545)
* Pass additionalCommandArgs to barman-cloud-restore ([#914](https://github.com/cloudnative-pg/plugin-barman-cloud/issues/914)) ([c5f149b](https://github.com/cloudnative-pg/plugin-barman-cloud/commit/c5f149b86a38fd2af33045d785c2e9a69a7e340a)), closes [#821](https://github.com/cloudnative-pg/plugin-barman-cloud/issues/821)
### Bug Fixes
* Add lz4 compression support for base backups ([#868](https://github.com/cloudnative-pg/plugin-barman-cloud/issues/868)) ([e30154b](https://github.com/cloudnative-pg/plugin-barman-cloud/commit/e30154b938b053f688b5ab520000233e164df6b6)), closes [#867](https://github.com/cloudnative-pg/plugin-barman-cloud/issues/867)
* Classify WAL restore errors with precise gRPC statuses ([#927](https://github.com/cloudnative-pg/plugin-barman-cloud/issues/927)) ([aaf6120](https://github.com/cloudnative-pg/plugin-barman-cloud/commit/aaf6120eaaf96d805d26fe4550b1f9c14dd8e02f))
* **deps:** Update all non-major go dependencies ([#877](https://github.com/cloudnative-pg/plugin-barman-cloud/issues/877)) ([a81f6e3](https://github.com/cloudnative-pg/plugin-barman-cloud/commit/a81f6e3d73ee348df22439f2daf062f4be598910))
* **deps:** Update all non-major go dependencies ([#898](https://github.com/cloudnative-pg/plugin-barman-cloud/issues/898)) ([acdbfb8](https://github.com/cloudnative-pg/plugin-barman-cloud/commit/acdbfb8b10f93cf52f874ec893905709d9bcaa8b))
* **deps:** Update all non-major go dependencies to 5d46599 ([#940](https://github.com/cloudnative-pg/plugin-barman-cloud/issues/940)) ([40aa4b2](https://github.com/cloudnative-pg/plugin-barman-cloud/commit/40aa4b21b88e2e323226c391078240d365653de9))
* **deps:** Update all non-major go dependencies to 8e1642e ([#939](https://github.com/cloudnative-pg/plugin-barman-cloud/issues/939)) ([f708825](https://github.com/cloudnative-pg/plugin-barman-cloud/commit/f7088258fd0ca1bca2e7dc15753be495d7dcc022))
* **deps:** Update all non-major go dependencies to bd68198 ([#950](https://github.com/cloudnative-pg/plugin-barman-cloud/issues/950)) ([787d2b3](https://github.com/cloudnative-pg/plugin-barman-cloud/commit/787d2b35ad4f86a0c125e4996194ec8fe7957de7))
* **deps:** Update documentation dependencies to v3.10.1 ([#878](https://github.com/cloudnative-pg/plugin-barman-cloud/issues/878)) ([6cf473d](https://github.com/cloudnative-pg/plugin-barman-cloud/commit/6cf473d5e8a16e204364b53bb0718d541c8c99ac))
* **deps:** Update k8s.io/utils digest to ff6756f ([#894](https://github.com/cloudnative-pg/plugin-barman-cloud/issues/894)) ([b7389e1](https://github.com/cloudnative-pg/plugin-barman-cloud/commit/b7389e18e5ec216a601722bb6686b11c49745b03))
* **deps:** Update kubernetes monorepo to v0.35.4 ([#853](https://github.com/cloudnative-pg/plugin-barman-cloud/issues/853)) ([21f811a](https://github.com/cloudnative-pg/plugin-barman-cloud/commit/21f811a3f22b8f87ca9230a131f57f832c086fcf))
* **deps:** Update kubernetes monorepo to v0.36.1 ([#909](https://github.com/cloudnative-pg/plugin-barman-cloud/issues/909)) ([99eb4a3](https://github.com/cloudnative-pg/plugin-barman-cloud/commit/99eb4a3fe5f4503c76f9afea08164d8e511c4f5b))
* **deps:** Update module github.com/cloudnative-pg/cloudnative-pg to v1.29.1 [security] ([#902](https://github.com/cloudnative-pg/plugin-barman-cloud/issues/902)) ([ba5063f](https://github.com/cloudnative-pg/plugin-barman-cloud/commit/ba5063f01393309459e02c30078c34b429f8f21b))
* **deps:** Update module github.com/cloudnative-pg/machinery to v0.5.0 ([#925](https://github.com/cloudnative-pg/plugin-barman-cloud/issues/925)) ([ef4b711](https://github.com/cloudnative-pg/plugin-barman-cloud/commit/ef4b7111372877eed087b9178d157dd0d1084bf8))
* **deps:** Update module github.com/onsi/ginkgo/v2 to v2.28.2 ([#874](https://github.com/cloudnative-pg/plugin-barman-cloud/issues/874)) ([8cb32e5](https://github.com/cloudnative-pg/plugin-barman-cloud/commit/8cb32e5a5153347a6b05bf63816bcbc9d94f4d67))
* **deps:** Update module google.golang.org/grpc to v1.81.0 ([#884](https://github.com/cloudnative-pg/plugin-barman-cloud/issues/884)) ([6fdecfd](https://github.com/cloudnative-pg/plugin-barman-cloud/commit/6fdecfde21b7a5cd05bc3f53895243fbf8537770))
* **deps:** Update module sigs.k8s.io/controller-runtime to v0.24.0 ([#880](https://github.com/cloudnative-pg/plugin-barman-cloud/issues/880)) ([58f4fed](https://github.com/cloudnative-pg/plugin-barman-cloud/commit/58f4fed40ba788f76f706e148bebf1892a2dd609))
* **deps:** Update module sigs.k8s.io/controller-runtime to v0.24.1 ([#910](https://github.com/cloudnative-pg/plugin-barman-cloud/issues/910)) ([9be87b0](https://github.com/cloudnative-pg/plugin-barman-cloud/commit/9be87b0d9c87c0df7f1f72caa33bf848fbc16582))
* **docs:** Update broken link to CloudNativePG documentation ([#904](https://github.com/cloudnative-pg/plugin-barman-cloud/issues/904)) ([43f92fb](https://github.com/cloudnative-pg/plugin-barman-cloud/commit/43f92fbcf1f57d95bbca22cb63c9697d75fc0dbc)), closes [#729](https://github.com/cloudnative-pg/plugin-barman-cloud/issues/729)
* **scheme:** Register meta types for CNPG scheme group version ([#943](https://github.com/cloudnative-pg/plugin-barman-cloud/issues/943)) ([bb7845d](https://github.com/cloudnative-pg/plugin-barman-cloud/commit/bb7845dd621115026744c9f1b32cb2fd0cb4a729)), closes [#942](https://github.com/cloudnative-pg/plugin-barman-cloud/issues/942)
## [0.12.0](https://github.com/cloudnative-pg/plugin-barman-cloud/compare/v0.11.0...v0.12.0) (2026-04-13) ## [0.12.0](https://github.com/cloudnative-pg/plugin-barman-cloud/compare/v0.11.0...v0.12.0) (2026-04-13)

View File

@ -1,5 +1,9 @@
# The CODEOWNERS file is used to define individuals or teams that are # This file is generated from componentowners-policy.yaml in
# responsible for code in a repository. For details, please refer to # cloudnative-pg/cnpg-infra — do not hand-edit, propose changes there instead.
# https://docs.github.com/en/free-pro-team@latest/github/creating-cloning-and-archiving-repositories/about-code-owners #
# Path-scoped rules below always include the repo's own general owners
# (the "*" line) in addition to their own specific teams/users, since
# CODEOWNERS only honors the LAST matching pattern for a given path —
# it does not merge an earlier, less-specific rule into a later one.
* @cloudnative-pg/maintainers * @cloudnative-pg/plugin-barman-cloud-owners

View File

@ -9,7 +9,7 @@ vars:
GO_VERSION: GO_VERSION:
sh: sed -n 's/^toolchain go//p' go.mod | grep . || sed -n 's/^go //p' go.mod sh: sed -n 's/^toolchain go//p' go.mod | grep . || sed -n 's/^go //p' go.mod
# renovate: datasource=docker depName=kindest/node versioning=semver # renovate: datasource=docker depName=kindest/node versioning=semver
E2E_KUBERNETES_VERSION: v1.35.1 E2E_KUBERNETES_VERSION: v1.37.0
E2E_CLUSTER_NAME: barman-cloud-plugin-e2e-{{.E2E_KUBERNETES_VERSION}} E2E_CLUSTER_NAME: barman-cloud-plugin-e2e-{{.E2E_KUBERNETES_VERSION}}
REGISTRY_NETWORK: barman-cloud-plugin REGISTRY_NETWORK: barman-cloud-plugin
REGISTRY_NAME: registry.barman-cloud-plugin REGISTRY_NAME: registry.barman-cloud-plugin
@ -21,9 +21,9 @@ tasks:
desc: Run golangci-lint desc: Run golangci-lint
env: env:
# renovate: datasource=git-refs depName=golangci-lint lookupName=https://github.com/sagikazarmark/daggerverse currentValue=main # renovate: datasource=git-refs depName=golangci-lint lookupName=https://github.com/sagikazarmark/daggerverse currentValue=main
DAGGER_GOLANGCI_LINT_SHA: 81b688189377135bd0cf85f3ddba88c4fbb52c2d DAGGER_GOLANGCI_LINT_SHA: ff27cd50f6b4eed2e3753c520632cd6099e1ce52
# renovate: datasource=docker depName=golangci/golangci-lint versioning=semver # renovate: datasource=docker depName=golangci/golangci-lint versioning=semver
GOLANGCI_LINT_VERSION: v2.12.2 GOLANGCI_LINT_VERSION: v2.13.2
cmds: cmds:
- > - >
GITHUB_REF= dagger -sc "github.com/sagikazarmark/daggerverse/golangci-lint@${DAGGER_GOLANGCI_LINT_SHA} GITHUB_REF= dagger -sc "github.com/sagikazarmark/daggerverse/golangci-lint@${DAGGER_GOLANGCI_LINT_SHA}
@ -34,6 +34,7 @@ tasks:
wordlist-ordered: wordlist-ordered:
desc: Order the word list file desc: Order the word list file
run: once
cmds: cmds:
- LANG=C LC_ALL=C sort .wordlist.txt > .wordlist.txt.new - LANG=C LC_ALL=C sort .wordlist.txt > .wordlist.txt.new
- mv -f .wordlist.txt.new .wordlist.txt - mv -f .wordlist.txt.new .wordlist.txt
@ -46,7 +47,7 @@ tasks:
- wordlist-ordered - wordlist-ordered
env: env:
# renovate: datasource=git-refs depName=spellcheck lookupName=https://github.com/cloudnative-pg/daggerverse currentValue=main # renovate: datasource=git-refs depName=spellcheck lookupName=https://github.com/cloudnative-pg/daggerverse currentValue=main
DAGGER_SPELLCHECK_SHA: 537e0ddae55ad0344af8f4454de7f27baeee48fa DAGGER_SPELLCHECK_SHA: 26cd57fb6ad66e88c036b675b0478d38df93962d
cmds: cmds:
- > - >
GITHUB_REF= dagger -s call -m github.com/cloudnative-pg/daggerverse/spellcheck@${DAGGER_SPELLCHECK_SHA} GITHUB_REF= dagger -s call -m github.com/cloudnative-pg/daggerverse/spellcheck@${DAGGER_SPELLCHECK_SHA}
@ -60,12 +61,32 @@ tasks:
desc: Check for conventional commits desc: Check for conventional commits
env: env:
# renovate: datasource=git-refs depName=commitlint lookupName=https://github.com/cloudnative-pg/daggerverse currentValue=main # renovate: datasource=git-refs depName=commitlint lookupName=https://github.com/cloudnative-pg/daggerverse currentValue=main
DAGGER_COMMITLINT_SHA: 537e0ddae55ad0344af8f4454de7f27baeee48fa DAGGER_COMMITLINT_SHA: 26cd57fb6ad66e88c036b675b0478d38df93962d
cmds: cmds:
- > - >
GITHUB_REF= dagger -s call -m github.com/cloudnative-pg/daggerverse/commitlint@${DAGGER_COMMITLINT_SHA} GITHUB_REF= dagger -s call -m github.com/cloudnative-pg/daggerverse/commitlint@${DAGGER_COMMITLINT_SHA}
lint --source . --args "--from=origin/main" stdout lint --source . --args "--from=origin/main" stdout
pip-compile-sidecar:
desc: Regenerate containers/sidecar-requirements.txt with the same Python version as the sidecar image
cmds:
- >
GITHUB_REF= dagger call --no-mod
container from --address=debian:trixie-slim
with-env-variable --name=DEBIAN_FRONTEND --value=noninteractive
with-exec --args="apt-get,update,-qq"
with-exec --args="apt-get,install,-y,-qq,python3,python3-venv,python3-pip,gcc,libpq-dev"
with-exec --args="pip,install,--quiet,--break-system-packages,pip-tools,click<8.5.0"
with-directory --path=/work --source=containers
with-workdir --path=/work
with-exec --args="pip-compile,--allow-unsafe,--generate-hashes,--output-file=sidecar-requirements.txt,--strip-extras,sidecar-requirements.in"
file --path=/work/sidecar-requirements.txt
export --path=containers/sidecar-requirements.txt
sources:
- containers/sidecar-requirements.in
generates:
- containers/sidecar-requirements.txt
uncommitted: uncommitted:
desc: Check for uncommitted changes desc: Check for uncommitted changes
deps: deps:
@ -74,7 +95,7 @@ tasks:
- wordlist-ordered - wordlist-ordered
env: env:
# renovate: datasource=git-refs depName=uncommitted lookupName=https://github.com/cloudnative-pg/daggerverse currentValue=main # renovate: datasource=git-refs depName=uncommitted lookupName=https://github.com/cloudnative-pg/daggerverse currentValue=main
DAGGER_UNCOMMITTED_SHA: 537e0ddae55ad0344af8f4454de7f27baeee48fa DAGGER_UNCOMMITTED_SHA: 26cd57fb6ad66e88c036b675b0478d38df93962d
cmds: cmds:
- GITHUB_REF= dagger -s call -m github.com/cloudnative-pg/daggerverse/uncommitted@${DAGGER_UNCOMMITTED_SHA} check-uncommitted --source . stdout - GITHUB_REF= dagger -s call -m github.com/cloudnative-pg/daggerverse/uncommitted@${DAGGER_UNCOMMITTED_SHA} check-uncommitted --source . stdout
sources: sources:
@ -86,7 +107,7 @@ tasks:
- controller-gen - controller-gen
env: env:
# renovate: datasource=git-refs depName=crd-gen-refs lookupName=https://github.com/cloudnative-pg/daggerverse currentValue=main # renovate: datasource=git-refs depName=crd-gen-refs lookupName=https://github.com/cloudnative-pg/daggerverse currentValue=main
DAGGER_CRDGENREF_SHA: 537e0ddae55ad0344af8f4454de7f27baeee48fa DAGGER_CRDGENREF_SHA: 26cd57fb6ad66e88c036b675b0478d38df93962d
# renovate: datasource=go depName=github.com/elastic/crd-ref-docs # renovate: datasource=go depName=github.com/elastic/crd-ref-docs
CRDREFDOCS_VERSION: v0.3.0 CRDREFDOCS_VERSION: v0.3.0
cmds: cmds:
@ -122,7 +143,7 @@ tasks:
docusaurus-version-is-aligned: docusaurus-version-is-aligned:
desc: Verify that a documentation version exists for the current version of the plugin desc: Verify that a documentation version exists for the current version of the plugin
cmds: cmds:
- $(dagger -s call -m dagger/check-doc-version has-version-documentation --src .) - $(GITHUB_REF= dagger -s call -m dagger/check-doc-version has-version-documentation --src .)
src: src:
- .release-please-manifest.json - .release-please-manifest.json
- ./web/versions.json - ./web/versions.json
@ -206,7 +227,7 @@ tasks:
- start-build-network - start-build-network
vars: vars:
# renovate: datasource=github-tags depName=dagger/dagger versioning=semver # renovate: datasource=github-tags depName=dagger/dagger versioning=semver
DAGGER_VERSION: 0.20.8 DAGGER_VERSION: 0.21.9
DAGGER_ENGINE_IMAGE: registry.dagger.io/engine:v{{ .DAGGER_VERSION }} DAGGER_ENGINE_IMAGE: registry.dagger.io/engine:v{{ .DAGGER_VERSION }}
cmds: cmds:
- > - >
@ -263,7 +284,7 @@ tasks:
run: once run: once
vars: vars:
# renovate: datasource=git-refs depName=kind lookupName=https://github.com/kubernetes-sigs/kind versioning=semver # renovate: datasource=git-refs depName=kind lookupName=https://github.com/kubernetes-sigs/kind versioning=semver
KIND_VERSION: v0.31.0 KIND_VERSION: v0.33.0
cmds: cmds:
- go install sigs.k8s.io/kind@{{.KIND_VERSION}} - go install sigs.k8s.io/kind@{{.KIND_VERSION}}
- kind version | grep -q {{.KIND_VERSION}} - kind version | grep -q {{.KIND_VERSION}}
@ -360,18 +381,20 @@ 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
cmds: cmds:
- > - >
dagger call -m github.com/purpleclay/daggerverse/docker@${DAGGER_DOCKER_SHA} GITHUB_REF= dagger call -m github.com/purpleclay/daggerverse/docker@${DAGGER_DOCKER_SHA}
--registry ghcr.io --username $REGISTRY_USER --password env:REGISTRY_PASSWORD --registry ghcr.io --username $REGISTRY_USER --password env:REGISTRY_PASSWORD
build --dir . --file containers/Dockerfile.plugin --args GO_VERSION={{.GO_VERSION}} --platform linux/amd64 --platform linux/arm64 build --dir . --file containers/Dockerfile.plugin --args GO_VERSION={{.GO_VERSION}} --platform linux/amd64 --platform linux/arm64
publish --ref {{.PLUGIN_IMAGE_NAME}} --tags {{.IMAGE_VERSION}} publish --ref {{.PLUGIN_IMAGE_NAME}} --tags {{.IMAGE_VERSION}}
- > - >
dagger call -m github.com/purpleclay/daggerverse/docker@${DAGGER_DOCKER_SHA} GITHUB_REF= dagger call -m github.com/purpleclay/daggerverse/docker@${DAGGER_DOCKER_SHA}
--registry ghcr.io --username $REGISTRY_USER --password env:REGISTRY_PASSWORD --registry ghcr.io --username $REGISTRY_USER --password env:REGISTRY_PASSWORD
build --dir . --file containers/Dockerfile.sidecar --args GO_VERSION={{.GO_VERSION}} --platform linux/amd64 --platform linux/arm64 build --dir . --file containers/Dockerfile.sidecar --args GO_VERSION={{.GO_VERSION}} --platform linux/amd64 --platform linux/arm64
publish --ref {{.SIDECAR_IMAGE_NAME}} --tags {{.IMAGE_VERSION}} publish --ref {{.SIDECAR_IMAGE_NAME}} --tags {{.IMAGE_VERSION}}
@ -381,7 +404,7 @@ tasks:
run: once run: once
env: env:
# renovate: datasource=git-refs depName=controller-gen lookupName=https://github.com/cloudnative-pg/daggerverse currentValue=main # renovate: datasource=git-refs depName=controller-gen lookupName=https://github.com/cloudnative-pg/daggerverse currentValue=main
DAGGER_CONTROLLER_GEN_SHA: 537e0ddae55ad0344af8f4454de7f27baeee48fa DAGGER_CONTROLLER_GEN_SHA: 26cd57fb6ad66e88c036b675b0478d38df93962d
cmds: cmds:
- > - >
GITHUB_REF= dagger -s call -m github.com/cloudnative-pg/daggerverse/controller-gen@${DAGGER_CONTROLLER_GEN_SHA} GITHUB_REF= dagger -s call -m github.com/cloudnative-pg/daggerverse/controller-gen@${DAGGER_CONTROLLER_GEN_SHA}
@ -450,19 +473,21 @@ 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: 81b688189377135bd0cf85f3ddba88c4fbb52c2d DAGGER_KUSTOMIZE_SHA: ff27cd50f6b4eed2e3753c520632cd6099e1ce52
cmds: cmds:
- > - >
dagger -s call -m https://github.com/sagikazarmark/daggerverse/kustomize@${DAGGER_KUSTOMIZE_SHA} GITHUB_REF= dagger -s call -m https://github.com/sagikazarmark/daggerverse/kustomize@${DAGGER_KUSTOMIZE_SHA}
edit --source . --dir kubernetes edit --source . --dir kubernetes
set image --image plugin-barman-cloud={{.PLUGIN_IMAGE_NAME}}:{{.IMAGE_VERSION}} set image --image plugin-barman-cloud={{.PLUGIN_IMAGE_NAME}}:{{.IMAGE_VERSION}}
set secret --secret plugin-barman-cloud --from-literal SIDECAR_IMAGE={{.SIDECAR_IMAGE_NAME}}:{{.IMAGE_VERSION}} set secret --secret plugin-barman-cloud --from-literal SIDECAR_IMAGE={{.SIDECAR_IMAGE_NAME}}:{{.IMAGE_VERSION}}
directory directory --path kubernetes export --path manifest-build directory directory --path kubernetes export --path manifest-build
- > - >
dagger -s call -m github.com/sagikazarmark/daggerverse/kustomize@${DAGGER_KUSTOMIZE_SHA} GITHUB_REF= dagger -s call -m github.com/sagikazarmark/daggerverse/kustomize@${DAGGER_KUSTOMIZE_SHA}
build --source . --dir manifest-build export --path manifest.yaml build --source . --dir manifest-build export --path manifest.yaml
sources: sources:
- ./config/**/*.yaml - ./config/**/*.yaml
@ -483,13 +508,13 @@ tasks:
- GITHUB_TOKEN - GITHUB_TOKEN
env: env:
# renovate: datasource=git-refs depName=gh lookupName=https://github.com/sagikazarmark/daggerverse # renovate: datasource=git-refs depName=gh lookupName=https://github.com/sagikazarmark/daggerverse
DAGGER_GH_SHA: 81b688189377135bd0cf85f3ddba88c4fbb52c2d DAGGER_GH_SHA: ff27cd50f6b4eed2e3753c520632cd6099e1ce52
preconditions: preconditions:
- sh: "[[ {{.GITHUB_REF}} =~ 'refs/tags/v.*' ]]" - sh: "[[ {{.GITHUB_REF}} =~ 'refs/tags/v.*' ]]"
msg: not a tag, failing msg: not a tag, failing
cmds: cmds:
- > - >
dagger -s call -m github.com/sagikazarmark/daggerverse/gh@${DAGGER_GH_SHA} GITHUB_REF= dagger -s call -m github.com/sagikazarmark/daggerverse/gh@${DAGGER_GH_SHA}
with-source --source . with-source --source .
run --repo {{.GITHUB_REPOSITORY}} --token env:GITHUB_TOKEN run --repo {{.GITHUB_REPOSITORY}} --token env:GITHUB_TOKEN
--cmd "release upload {{.GITHUB_REF_NAME}} manifest.yaml" --cmd "release upload {{.GITHUB_REF_NAME}} manifest.yaml"

View File

@ -176,6 +176,25 @@ spec:
format: int32 format: int32
minimum: 1 minimum: 1
type: integer type: integer
restoreAdditionalCommandArgs:
description: |-
Additional arguments that can be appended to the 'barman-cloud-restore'
command-line invocation. These arguments provide flexibility to customize
the data restore process further, according to specific requirements or
configurations.
Example:
In a scenario where specialized restore options are required, such as setting
a specific read timeout or defining custom behavior, users can use this field
to specify additional command arguments.
Note:
It's essential to ensure that the provided arguments are valid and supported
by the 'barman-cloud-restore' command, to avoid potential errors or unintended
behavior during execution.
items:
type: string
type: array
type: object type: object
destinationPath: destinationPath:
description: |- description: |-
@ -441,7 +460,9 @@ spec:
description: Selects a key of a ConfigMap. description: Selects a key of a ConfigMap.
properties: properties:
key: key:
description: The key to select. description: |-
The key to select from the ConfigMap's Data field.
Keys in the BinaryData field are not currently propagated to container env vars.
type: string type: string
name: name:
default: "" default: ""

View File

@ -55,7 +55,7 @@ COPY containers/sidecar-requirements.txt .
# Create virtualenv and install dependencies # Create virtualenv and install dependencies
RUN python3 -m venv /venv && \ RUN python3 -m venv /venv && \
/venv/bin/pip install --upgrade pip setuptools wheel && \ /venv/bin/pip install --upgrade pip wheel && \
/venv/bin/pip install --no-cache-dir -r sidecar-requirements.txt /venv/bin/pip install --no-cache-dir -r sidecar-requirements.txt
# Download and extract runtime library packages and their dependencies # Download and extract runtime library packages and their dependencies
@ -63,6 +63,9 @@ RUN python3 -m venv /venv && \
# already present in the distroless base image. # already present in the distroless base image.
# Distroless package list from: https://github.com/GoogleContainerTools/distroless/blob/main/base/config.bzl # Distroless package list from: https://github.com/GoogleContainerTools/distroless/blob/main/base/config.bzl
# and https://github.com/GoogleContainerTools/distroless/blob/main/python3/config.bzl # and https://github.com/GoogleContainerTools/distroless/blob/main/python3/config.bzl
# libselinux1/libpcre2-8-0 are pulled in transitively by python3.13-venv's apt metadata,
# but the actual distroless base does not ship them, so they are excluded from the
# "already present" set below to force them to be bundled (tar needs them at runtime).
RUN mkdir -p /dependencies /build/downloads && \ RUN mkdir -p /dependencies /build/downloads && \
cd /build/downloads && \ cd /build/downloads && \
DISTROLESS_PACKAGES="libc6 libssl3t64 libzstd1 zlib1g libgcc-s1 libstdc++6 \ DISTROLESS_PACKAGES="libc6 libssl3t64 libzstd1 zlib1g libgcc-s1 libstdc++6 \
@ -73,10 +76,11 @@ RUN mkdir -p /dependencies /build/downloads && \
libpython3.13-stdlib python3.13-minimal python3.13-venv" && \ libpython3.13-stdlib python3.13-minimal python3.13-venv" && \
apt-cache depends --recurse --no-recommends --no-suggests \ apt-cache depends --recurse --no-recommends --no-suggests \
--no-conflicts --no-breaks --no-replaces --no-enhances \ --no-conflicts --no-breaks --no-replaces --no-enhances \
$DISTROLESS_PACKAGES 2>/dev/null | grep "^\w" | sort -u > /tmp/distroless.txt && \ $DISTROLESS_PACKAGES 2>/dev/null | grep "^\w" | sort -u | \
grep -v -x -E 'libselinux1|libpcre2-8-0' > /tmp/distroless.txt && \
apt-cache depends --recurse --no-recommends --no-suggests \ apt-cache depends --recurse --no-recommends --no-suggests \
--no-conflicts --no-breaks --no-replaces --no-enhances \ --no-conflicts --no-breaks --no-replaces --no-enhances \
libpq5 liblz4-1 libsnappy1v5 2>/dev/null | grep "^\w" | sort -u | \ libpq5 liblz4-1 libsnappy1v5 tar 2>/dev/null | grep "^\w" | sort -u | \
grep -v -F -x -f /tmp/distroless.txt > /tmp/packages.txt && \ grep -v -F -x -f /tmp/distroless.txt > /tmp/packages.txt && \
apt-get download $(cat /tmp/packages.txt) && \ apt-get download $(cat /tmp/packages.txt) && \
for deb in *.deb; do \ for deb in *.deb; do \
@ -102,6 +106,7 @@ LABEL summary="$SUMMARY" \
COPY --from=pythonbuilder /venv /venv COPY --from=pythonbuilder /venv /venv
COPY --from=pythonbuilder /dependencies/usr/lib /usr/lib COPY --from=pythonbuilder /dependencies/usr/lib /usr/lib
COPY --from=pythonbuilder /dependencies/usr/bin/tar /usr/bin/tar
COPY --from=gobuilder /workspace/manager /manager COPY --from=gobuilder /workspace/manager /manager
# Compile all Python bytecode as root to avoid runtime compilation # Compile all Python bytecode as root to avoid runtime compilation

View File

@ -1,3 +1,2 @@
barman[azure,cloud,google,snappy,zstandard,lz4]==3.18.0 barman[azure,cloud,google,snappy,zstandard,lz4]==3.20.0
setuptools==82.0.1
zipp>=3.19.1 # not directly required, pinned by Snyk to avoid a vulnerability zipp>=3.19.1 # not directly required, pinned by Snyk to avoid a vulnerability

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
{ {
"name": "check-doc-version", "name": "check-doc-version",
"engineVersion": "v0.20.6", "engineVersion": "v0.21.8",
"sdk": { "sdk": {
"source": "go" "source": "go"
}, },

View File

@ -1,6 +1,6 @@
module dagger/check-doc-version module dagger/check-doc-version
go 1.25.0 go 1.26.1
require ( require (
github.com/Khan/genqlient v0.8.1 github.com/Khan/genqlient v0.8.1
@ -26,12 +26,12 @@ require (
go.opentelemetry.io/otel/sdk/metric v1.43.0 // indirect go.opentelemetry.io/otel/sdk/metric v1.43.0 // indirect
go.opentelemetry.io/proto/otlp v1.10.0 // indirect go.opentelemetry.io/proto/otlp v1.10.0 // indirect
golang.org/x/sync v0.20.0 // indirect golang.org/x/sync v0.20.0 // indirect
google.golang.org/grpc v1.80.0 // indirect google.golang.org/grpc v1.82.1 // indirect
) )
require ( require (
dagger.io/dagger v0.20.6-0.20260415192040-7058e9313c72
github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/dagger/querybuilder v0.0.0-20260402040506-574a5e81cb59
github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/logr v1.4.3 // indirect
github.com/go-logr/stdr v1.2.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect
github.com/google/uuid v1.6.0 // indirect github.com/google/uuid v1.6.0 // indirect
@ -39,9 +39,9 @@ require (
github.com/sosodev/duration v1.4.0 // indirect github.com/sosodev/duration v1.4.0 // indirect
go.opentelemetry.io/auto/sdk v1.2.1 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.43.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.43.0 // indirect
golang.org/x/net v0.53.0 // indirect golang.org/x/net v0.55.0 // indirect
golang.org/x/sys v0.43.0 // indirect golang.org/x/sys v0.45.0 // indirect
golang.org/x/text v0.36.0 // indirect golang.org/x/text v0.37.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20260414002931-afd174a4e478 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20260414002931-afd174a4e478 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478 // indirect
google.golang.org/protobuf v1.36.11 // indirect google.golang.org/protobuf v1.36.11 // indirect

View File

@ -1,5 +1,3 @@
dagger.io/dagger v0.20.6-0.20260415192040-7058e9313c72 h1:s39e07WvaUU6tLhpojK8ZEIoIbOSn5hHOJra0waenxQ=
dagger.io/dagger v0.20.6-0.20260415192040-7058e9313c72/go.mod h1:ZXg8+pQZaZUC8rAw4V/gPP8aKvKARIJZ+pfcV+RC1es=
github.com/99designs/gqlgen v0.17.89 h1:KzEcxPiMgQoMw3m/E85atUEHyZyt0PbAflMia5Kw8z8= github.com/99designs/gqlgen v0.17.89 h1:KzEcxPiMgQoMw3m/E85atUEHyZyt0PbAflMia5Kw8z8=
github.com/99designs/gqlgen v0.17.89/go.mod h1:GFqruTVGB7ZTdrf1uzOagpXbY7DrEt1pIxnTdhIbWvQ= github.com/99designs/gqlgen v0.17.89/go.mod h1:GFqruTVGB7ZTdrf1uzOagpXbY7DrEt1pIxnTdhIbWvQ=
github.com/Khan/genqlient v0.8.1 h1:wtOCc8N9rNynRLXN3k3CnfzheCUNKBcvXmVv5zt6WCs= github.com/Khan/genqlient v0.8.1 h1:wtOCc8N9rNynRLXN3k3CnfzheCUNKBcvXmVv5zt6WCs=
@ -14,6 +12,8 @@ github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UF
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/dagger/otel-go v1.43.0 h1:AYCnAamWmxtSxigWPTgC+8EWqiWPcDZEegh8y05gdJ8= github.com/dagger/otel-go v1.43.0 h1:AYCnAamWmxtSxigWPTgC+8EWqiWPcDZEegh8y05gdJ8=
github.com/dagger/otel-go v1.43.0/go.mod h1:83CTuXi70zcx1kaym5buqmb7RNzg1E9dEiQSFyLbLdU= github.com/dagger/otel-go v1.43.0/go.mod h1:83CTuXi70zcx1kaym5buqmb7RNzg1E9dEiQSFyLbLdU=
github.com/dagger/querybuilder v0.0.0-20260402040506-574a5e81cb59 h1:g6vfdGRyz6fAjfHz5FyYPZgHy8qcQ31fHrBl1iCOzxw=
github.com/dagger/querybuilder v0.0.0-20260402040506-574a5e81cb59/go.mod h1:jsdUJeYzcbyK1j/EqMGPrQgNYxl/Zfg06vvM9C/xXxs=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
@ -75,22 +75,22 @@ go.opentelemetry.io/proto/otlp v1.10.0 h1:IQRWgT5srOCYfiWnpqUYz9CVmbO8bFmKcwYxpu
go.opentelemetry.io/proto/otlp v1.10.0/go.mod h1:/CV4QoCR/S9yaPj8utp3lvQPoqMtxXdzn7ozvvozVqk= go.opentelemetry.io/proto/otlp v1.10.0/go.mod h1:/CV4QoCR/S9yaPj8utp3lvQPoqMtxXdzn7ozvvozVqk=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
golang.org/x/net v0.53.0 h1:d+qAbo5L0orcWAr0a9JweQpjXF19LMXJE8Ey7hwOdUA= golang.org/x/net v0.55.0 h1:bcvxaJn3e1U6InsFWt1JUq1aSjnRxLzT2rtD2KfkDF8=
golang.org/x/net v0.53.0/go.mod h1:JvMuJH7rrdiCfbeHoo3fCQU24Lf5JJwT9W3sJFulfgs= golang.org/x/net v0.55.0/go.mod h1:L5U2KuzuOe1lY7Z+aWVIKK6qEeJXnXV9yzGA+WCHJww=
golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4= golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4=
golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
golang.org/x/sys v0.43.0 h1:Rlag2XtaFTxp19wS8MXlJwTvoh8ArU6ezoyFsMyCTNI= golang.org/x/sys v0.45.0 h1:dO4czNzziLiiXplLQgBCEpCvXQ3dnkn0SdaZSYdQ+FY=
golang.org/x/sys v0.43.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= golang.org/x/sys v0.45.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
golang.org/x/text v0.36.0 h1:JfKh3XmcRPqZPKevfXVpI1wXPTqbkE5f7JA92a55Yxg= golang.org/x/text v0.37.0 h1:Cqjiwd9eSg8e0QAkyCaQTNHFIIzWtidPahFWR83rTrc=
golang.org/x/text v0.36.0/go.mod h1:NIdBknypM8iqVmPiuco0Dh6P5Jcdk8lJL0CUebqK164= golang.org/x/text v0.37.0/go.mod h1:a5sjxXGs9hsn/AJVwuElvCAo9v8QYLzvavO5z2PiM38=
gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4= gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4=
gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E= gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E=
google.golang.org/genproto/googleapis/api v0.0.0-20260414002931-afd174a4e478 h1:yQugLulqltosq0B/f8l4w9VryjV+N/5gcW0jQ3N8Qec= google.golang.org/genproto/googleapis/api v0.0.0-20260414002931-afd174a4e478 h1:yQugLulqltosq0B/f8l4w9VryjV+N/5gcW0jQ3N8Qec=
google.golang.org/genproto/googleapis/api v0.0.0-20260414002931-afd174a4e478/go.mod h1:C6ADNqOxbgdUUeRTU+LCHDPB9ttAMCTff6auwCVa4uc= google.golang.org/genproto/googleapis/api v0.0.0-20260414002931-afd174a4e478/go.mod h1:C6ADNqOxbgdUUeRTU+LCHDPB9ttAMCTff6auwCVa4uc=
google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478 h1:RmoJA1ujG+/lRGNfUnOMfhCy5EipVMyvUE+KNbPbTlw= google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478 h1:RmoJA1ujG+/lRGNfUnOMfhCy5EipVMyvUE+KNbPbTlw=
google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8=
google.golang.org/grpc v1.80.0 h1:Xr6m2WmWZLETvUNvIUmeD5OAagMw3FiKmMlTdViWsHM= google.golang.org/grpc v1.82.1 h1:NnAxzGRA0677vCa4BUkOAnO5+FfQqVl9iUXeD0IqcGE=
google.golang.org/grpc v1.80.0/go.mod h1:ho/dLnxwi3EDJA4Zghp7k2Ec1+c2jqup0bFkw07bwF4= google.golang.org/grpc v1.82.1/go.mod h1:yzTZ1TB1Z3SG+LIYaI+WiE8D5+PZ3ArnrSp8zF3+/ZA=
google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=

View File

@ -1,6 +1,6 @@
{ {
"name": "e2e", "name": "e2e",
"engineVersion": "v0.20.6", "engineVersion": "v0.21.8",
"sdk": { "sdk": {
"source": "go" "source": "go"
}, },

View File

@ -1,37 +1,35 @@
module dagger/e-2-e module dagger/e-2-e
go 1.25.0 go 1.26.1
require ( require (
github.com/99designs/gqlgen v0.17.89
github.com/Khan/genqlient v0.8.1 github.com/Khan/genqlient v0.8.1
github.com/dagger/otel-go v1.43.0 github.com/dagger/otel-go v1.43.0
github.com/vektah/gqlparser/v2 v2.5.32 github.com/vektah/gqlparser/v2 v2.5.32
go.opentelemetry.io/otel v1.43.0 go.opentelemetry.io/otel v1.43.0
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.19.0
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.19.0
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.43.0
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.43.0
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.43.0
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.43.0
go.opentelemetry.io/otel/log v0.19.0
go.opentelemetry.io/otel/metric v1.43.0
go.opentelemetry.io/otel/sdk v1.43.0 go.opentelemetry.io/otel/sdk v1.43.0
go.opentelemetry.io/otel/sdk/log v0.19.0
go.opentelemetry.io/otel/sdk/metric v1.43.0
go.opentelemetry.io/otel/trace v1.43.0 go.opentelemetry.io/otel/trace v1.43.0
go.opentelemetry.io/proto/otlp v1.10.0
golang.org/x/sync v0.20.0
google.golang.org/grpc v1.82.1
) )
require ( require github.com/cenkalti/backoff/v5 v5.0.3 // indirect
github.com/99designs/gqlgen v0.17.89 // indirect
github.com/cenkalti/backoff/v5 v5.0.3 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.19.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.19.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.43.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.43.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.43.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.43.0 // indirect
go.opentelemetry.io/otel/log v0.19.0 // indirect
go.opentelemetry.io/otel/metric v1.43.0 // indirect
go.opentelemetry.io/otel/sdk/log v0.19.0 // indirect
go.opentelemetry.io/otel/sdk/metric v1.43.0 // indirect
go.opentelemetry.io/proto/otlp v1.10.0 // indirect
golang.org/x/sync v0.20.0 // indirect
google.golang.org/grpc v1.80.0 // indirect
)
require ( require (
dagger.io/dagger v0.20.6-0.20260415192040-7058e9313c72
github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/dagger/querybuilder v0.0.0-20260402040506-574a5e81cb59
github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/logr v1.4.3 // indirect
github.com/go-logr/stdr v1.2.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect
github.com/google/uuid v1.6.0 // indirect github.com/google/uuid v1.6.0 // indirect
@ -39,9 +37,9 @@ require (
github.com/sosodev/duration v1.4.0 // indirect github.com/sosodev/duration v1.4.0 // indirect
go.opentelemetry.io/auto/sdk v1.2.1 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.43.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.43.0 // indirect
golang.org/x/net v0.53.0 // indirect golang.org/x/net v0.55.0 // indirect
golang.org/x/sys v0.43.0 // indirect golang.org/x/sys v0.45.0 // indirect
golang.org/x/text v0.36.0 // indirect golang.org/x/text v0.37.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20260414002931-afd174a4e478 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20260414002931-afd174a4e478 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478 // indirect
google.golang.org/protobuf v1.36.11 // indirect google.golang.org/protobuf v1.36.11 // indirect

View File

@ -1,5 +1,3 @@
dagger.io/dagger v0.20.6-0.20260415192040-7058e9313c72 h1:s39e07WvaUU6tLhpojK8ZEIoIbOSn5hHOJra0waenxQ=
dagger.io/dagger v0.20.6-0.20260415192040-7058e9313c72/go.mod h1:ZXg8+pQZaZUC8rAw4V/gPP8aKvKARIJZ+pfcV+RC1es=
github.com/99designs/gqlgen v0.17.89 h1:KzEcxPiMgQoMw3m/E85atUEHyZyt0PbAflMia5Kw8z8= github.com/99designs/gqlgen v0.17.89 h1:KzEcxPiMgQoMw3m/E85atUEHyZyt0PbAflMia5Kw8z8=
github.com/99designs/gqlgen v0.17.89/go.mod h1:GFqruTVGB7ZTdrf1uzOagpXbY7DrEt1pIxnTdhIbWvQ= github.com/99designs/gqlgen v0.17.89/go.mod h1:GFqruTVGB7ZTdrf1uzOagpXbY7DrEt1pIxnTdhIbWvQ=
github.com/Khan/genqlient v0.8.1 h1:wtOCc8N9rNynRLXN3k3CnfzheCUNKBcvXmVv5zt6WCs= github.com/Khan/genqlient v0.8.1 h1:wtOCc8N9rNynRLXN3k3CnfzheCUNKBcvXmVv5zt6WCs=
@ -14,6 +12,8 @@ github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UF
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/dagger/otel-go v1.43.0 h1:AYCnAamWmxtSxigWPTgC+8EWqiWPcDZEegh8y05gdJ8= github.com/dagger/otel-go v1.43.0 h1:AYCnAamWmxtSxigWPTgC+8EWqiWPcDZEegh8y05gdJ8=
github.com/dagger/otel-go v1.43.0/go.mod h1:83CTuXi70zcx1kaym5buqmb7RNzg1E9dEiQSFyLbLdU= github.com/dagger/otel-go v1.43.0/go.mod h1:83CTuXi70zcx1kaym5buqmb7RNzg1E9dEiQSFyLbLdU=
github.com/dagger/querybuilder v0.0.0-20260402040506-574a5e81cb59 h1:g6vfdGRyz6fAjfHz5FyYPZgHy8qcQ31fHrBl1iCOzxw=
github.com/dagger/querybuilder v0.0.0-20260402040506-574a5e81cb59/go.mod h1:jsdUJeYzcbyK1j/EqMGPrQgNYxl/Zfg06vvM9C/xXxs=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
@ -75,22 +75,22 @@ go.opentelemetry.io/proto/otlp v1.10.0 h1:IQRWgT5srOCYfiWnpqUYz9CVmbO8bFmKcwYxpu
go.opentelemetry.io/proto/otlp v1.10.0/go.mod h1:/CV4QoCR/S9yaPj8utp3lvQPoqMtxXdzn7ozvvozVqk= go.opentelemetry.io/proto/otlp v1.10.0/go.mod h1:/CV4QoCR/S9yaPj8utp3lvQPoqMtxXdzn7ozvvozVqk=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
golang.org/x/net v0.53.0 h1:d+qAbo5L0orcWAr0a9JweQpjXF19LMXJE8Ey7hwOdUA= golang.org/x/net v0.55.0 h1:bcvxaJn3e1U6InsFWt1JUq1aSjnRxLzT2rtD2KfkDF8=
golang.org/x/net v0.53.0/go.mod h1:JvMuJH7rrdiCfbeHoo3fCQU24Lf5JJwT9W3sJFulfgs= golang.org/x/net v0.55.0/go.mod h1:L5U2KuzuOe1lY7Z+aWVIKK6qEeJXnXV9yzGA+WCHJww=
golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4= golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4=
golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
golang.org/x/sys v0.43.0 h1:Rlag2XtaFTxp19wS8MXlJwTvoh8ArU6ezoyFsMyCTNI= golang.org/x/sys v0.45.0 h1:dO4czNzziLiiXplLQgBCEpCvXQ3dnkn0SdaZSYdQ+FY=
golang.org/x/sys v0.43.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= golang.org/x/sys v0.45.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
golang.org/x/text v0.36.0 h1:JfKh3XmcRPqZPKevfXVpI1wXPTqbkE5f7JA92a55Yxg= golang.org/x/text v0.37.0 h1:Cqjiwd9eSg8e0QAkyCaQTNHFIIzWtidPahFWR83rTrc=
golang.org/x/text v0.36.0/go.mod h1:NIdBknypM8iqVmPiuco0Dh6P5Jcdk8lJL0CUebqK164= golang.org/x/text v0.37.0/go.mod h1:a5sjxXGs9hsn/AJVwuElvCAo9v8QYLzvavO5z2PiM38=
gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4= gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4=
gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E= gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E=
google.golang.org/genproto/googleapis/api v0.0.0-20260414002931-afd174a4e478 h1:yQugLulqltosq0B/f8l4w9VryjV+N/5gcW0jQ3N8Qec= google.golang.org/genproto/googleapis/api v0.0.0-20260414002931-afd174a4e478 h1:yQugLulqltosq0B/f8l4w9VryjV+N/5gcW0jQ3N8Qec=
google.golang.org/genproto/googleapis/api v0.0.0-20260414002931-afd174a4e478/go.mod h1:C6ADNqOxbgdUUeRTU+LCHDPB9ttAMCTff6auwCVa4uc= google.golang.org/genproto/googleapis/api v0.0.0-20260414002931-afd174a4e478/go.mod h1:C6ADNqOxbgdUUeRTU+LCHDPB9ttAMCTff6auwCVa4uc=
google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478 h1:RmoJA1ujG+/lRGNfUnOMfhCy5EipVMyvUE+KNbPbTlw= google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478 h1:RmoJA1ujG+/lRGNfUnOMfhCy5EipVMyvUE+KNbPbTlw=
google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8=
google.golang.org/grpc v1.80.0 h1:Xr6m2WmWZLETvUNvIUmeD5OAagMw3FiKmMlTdViWsHM= google.golang.org/grpc v1.82.1 h1:NnAxzGRA0677vCa4BUkOAnO5+FfQqVl9iUXeD0IqcGE=
google.golang.org/grpc v1.80.0/go.mod h1:ho/dLnxwi3EDJA4Zghp7k2Ec1+c2jqup0bFkw07bwF4= google.golang.org/grpc v1.82.1/go.mod h1:yzTZ1TB1Z3SG+LIYaI+WiE8D5+PZ3ArnrSp8zF3+/ZA=
google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=

View File

@ -1,6 +1,6 @@
{ {
"name": "gotest", "name": "gotest",
"engineVersion": "v0.20.6", "engineVersion": "v0.21.8",
"sdk": { "sdk": {
"source": "go" "source": "go"
}, },

View File

@ -1,6 +1,6 @@
module dagger/gotest module dagger/gotest
go 1.25.0 go 1.26.1
require ( require (
github.com/Khan/genqlient v0.8.1 github.com/Khan/genqlient v0.8.1
@ -22,12 +22,12 @@ require (
go.opentelemetry.io/otel/sdk/log v0.19.0 // indirect go.opentelemetry.io/otel/sdk/log v0.19.0 // indirect
go.opentelemetry.io/proto/otlp v1.10.0 // indirect go.opentelemetry.io/proto/otlp v1.10.0 // indirect
golang.org/x/sync v0.20.0 // indirect golang.org/x/sync v0.20.0 // indirect
google.golang.org/grpc v1.80.0 // indirect google.golang.org/grpc v1.82.1 // indirect
) )
require ( require (
dagger.io/dagger v0.20.6-0.20260415192040-7058e9313c72
github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/dagger/querybuilder v0.0.0-20260402040506-574a5e81cb59
github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/logr v1.4.3 // indirect
github.com/go-logr/stdr v1.2.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect
github.com/google/uuid v1.6.0 // indirect github.com/google/uuid v1.6.0 // indirect
@ -39,9 +39,9 @@ require (
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.43.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.43.0 // indirect
go.opentelemetry.io/otel/metric v1.43.0 // indirect go.opentelemetry.io/otel/metric v1.43.0 // indirect
go.opentelemetry.io/otel/sdk/metric v1.43.0 // indirect go.opentelemetry.io/otel/sdk/metric v1.43.0 // indirect
golang.org/x/net v0.53.0 // indirect golang.org/x/net v0.55.0 // indirect
golang.org/x/sys v0.43.0 // indirect golang.org/x/sys v0.45.0 // indirect
golang.org/x/text v0.36.0 // indirect golang.org/x/text v0.37.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20260414002931-afd174a4e478 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20260414002931-afd174a4e478 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478 // indirect
google.golang.org/protobuf v1.36.11 // indirect google.golang.org/protobuf v1.36.11 // indirect

View File

@ -1,5 +1,3 @@
dagger.io/dagger v0.20.6-0.20260415192040-7058e9313c72 h1:s39e07WvaUU6tLhpojK8ZEIoIbOSn5hHOJra0waenxQ=
dagger.io/dagger v0.20.6-0.20260415192040-7058e9313c72/go.mod h1:ZXg8+pQZaZUC8rAw4V/gPP8aKvKARIJZ+pfcV+RC1es=
github.com/99designs/gqlgen v0.17.89 h1:KzEcxPiMgQoMw3m/E85atUEHyZyt0PbAflMia5Kw8z8= github.com/99designs/gqlgen v0.17.89 h1:KzEcxPiMgQoMw3m/E85atUEHyZyt0PbAflMia5Kw8z8=
github.com/99designs/gqlgen v0.17.89/go.mod h1:GFqruTVGB7ZTdrf1uzOagpXbY7DrEt1pIxnTdhIbWvQ= github.com/99designs/gqlgen v0.17.89/go.mod h1:GFqruTVGB7ZTdrf1uzOagpXbY7DrEt1pIxnTdhIbWvQ=
github.com/Khan/genqlient v0.8.1 h1:wtOCc8N9rNynRLXN3k3CnfzheCUNKBcvXmVv5zt6WCs= github.com/Khan/genqlient v0.8.1 h1:wtOCc8N9rNynRLXN3k3CnfzheCUNKBcvXmVv5zt6WCs=
@ -14,6 +12,8 @@ github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UF
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/dagger/otel-go v1.43.0 h1:AYCnAamWmxtSxigWPTgC+8EWqiWPcDZEegh8y05gdJ8= github.com/dagger/otel-go v1.43.0 h1:AYCnAamWmxtSxigWPTgC+8EWqiWPcDZEegh8y05gdJ8=
github.com/dagger/otel-go v1.43.0/go.mod h1:83CTuXi70zcx1kaym5buqmb7RNzg1E9dEiQSFyLbLdU= github.com/dagger/otel-go v1.43.0/go.mod h1:83CTuXi70zcx1kaym5buqmb7RNzg1E9dEiQSFyLbLdU=
github.com/dagger/querybuilder v0.0.0-20260402040506-574a5e81cb59 h1:g6vfdGRyz6fAjfHz5FyYPZgHy8qcQ31fHrBl1iCOzxw=
github.com/dagger/querybuilder v0.0.0-20260402040506-574a5e81cb59/go.mod h1:jsdUJeYzcbyK1j/EqMGPrQgNYxl/Zfg06vvM9C/xXxs=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
@ -75,22 +75,22 @@ go.opentelemetry.io/proto/otlp v1.10.0 h1:IQRWgT5srOCYfiWnpqUYz9CVmbO8bFmKcwYxpu
go.opentelemetry.io/proto/otlp v1.10.0/go.mod h1:/CV4QoCR/S9yaPj8utp3lvQPoqMtxXdzn7ozvvozVqk= go.opentelemetry.io/proto/otlp v1.10.0/go.mod h1:/CV4QoCR/S9yaPj8utp3lvQPoqMtxXdzn7ozvvozVqk=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
golang.org/x/net v0.53.0 h1:d+qAbo5L0orcWAr0a9JweQpjXF19LMXJE8Ey7hwOdUA= golang.org/x/net v0.55.0 h1:bcvxaJn3e1U6InsFWt1JUq1aSjnRxLzT2rtD2KfkDF8=
golang.org/x/net v0.53.0/go.mod h1:JvMuJH7rrdiCfbeHoo3fCQU24Lf5JJwT9W3sJFulfgs= golang.org/x/net v0.55.0/go.mod h1:L5U2KuzuOe1lY7Z+aWVIKK6qEeJXnXV9yzGA+WCHJww=
golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4= golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4=
golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
golang.org/x/sys v0.43.0 h1:Rlag2XtaFTxp19wS8MXlJwTvoh8ArU6ezoyFsMyCTNI= golang.org/x/sys v0.45.0 h1:dO4czNzziLiiXplLQgBCEpCvXQ3dnkn0SdaZSYdQ+FY=
golang.org/x/sys v0.43.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= golang.org/x/sys v0.45.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
golang.org/x/text v0.36.0 h1:JfKh3XmcRPqZPKevfXVpI1wXPTqbkE5f7JA92a55Yxg= golang.org/x/text v0.37.0 h1:Cqjiwd9eSg8e0QAkyCaQTNHFIIzWtidPahFWR83rTrc=
golang.org/x/text v0.36.0/go.mod h1:NIdBknypM8iqVmPiuco0Dh6P5Jcdk8lJL0CUebqK164= golang.org/x/text v0.37.0/go.mod h1:a5sjxXGs9hsn/AJVwuElvCAo9v8QYLzvavO5z2PiM38=
gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4= gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4=
gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E= gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E=
google.golang.org/genproto/googleapis/api v0.0.0-20260414002931-afd174a4e478 h1:yQugLulqltosq0B/f8l4w9VryjV+N/5gcW0jQ3N8Qec= google.golang.org/genproto/googleapis/api v0.0.0-20260414002931-afd174a4e478 h1:yQugLulqltosq0B/f8l4w9VryjV+N/5gcW0jQ3N8Qec=
google.golang.org/genproto/googleapis/api v0.0.0-20260414002931-afd174a4e478/go.mod h1:C6ADNqOxbgdUUeRTU+LCHDPB9ttAMCTff6auwCVa4uc= google.golang.org/genproto/googleapis/api v0.0.0-20260414002931-afd174a4e478/go.mod h1:C6ADNqOxbgdUUeRTU+LCHDPB9ttAMCTff6auwCVa4uc=
google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478 h1:RmoJA1ujG+/lRGNfUnOMfhCy5EipVMyvUE+KNbPbTlw= google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478 h1:RmoJA1ujG+/lRGNfUnOMfhCy5EipVMyvUE+KNbPbTlw=
google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8=
google.golang.org/grpc v1.80.0 h1:Xr6m2WmWZLETvUNvIUmeD5OAagMw3FiKmMlTdViWsHM= google.golang.org/grpc v1.82.1 h1:NnAxzGRA0677vCa4BUkOAnO5+FfQqVl9iUXeD0IqcGE=
google.golang.org/grpc v1.80.0/go.mod h1:ho/dLnxwi3EDJA4Zghp7k2Ec1+c2jqup0bFkw07bwF4= google.golang.org/grpc v1.82.1/go.mod h1:yzTZ1TB1Z3SG+LIYaI+WiE8D5+PZ3ArnrSp8zF3+/ZA=
google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=

129
go.mod
View File

@ -1,33 +1,33 @@
module github.com/cloudnative-pg/plugin-barman-cloud module github.com/cloudnative-pg/plugin-barman-cloud
go 1.26.3 go 1.26.4
require ( require (
github.com/cert-manager/cert-manager v1.20.2 github.com/cert-manager/cert-manager v1.21.1
github.com/cloudnative-pg/api v1.29.1 github.com/cloudnative-pg/api v1.30.0
github.com/cloudnative-pg/barman-cloud v0.5.1 github.com/cloudnative-pg/barman-cloud v0.6.0
github.com/cloudnative-pg/cloudnative-pg v1.29.1 github.com/cloudnative-pg/cloudnative-pg v1.30.0
github.com/cloudnative-pg/cnpg-i v0.5.0 github.com/cloudnative-pg/cnpg-i v0.6.0
github.com/cloudnative-pg/cnpg-i-machinery v0.4.2 github.com/cloudnative-pg/cnpg-i-machinery v0.4.2
github.com/cloudnative-pg/machinery v0.4.0 github.com/cloudnative-pg/machinery v0.6.0
github.com/onsi/ginkgo/v2 v2.29.0 github.com/onsi/ginkgo/v2 v2.32.1
github.com/onsi/gomega v1.41.0 github.com/onsi/gomega v1.43.0
github.com/spf13/cobra v1.10.2 github.com/spf13/cobra v1.10.2
github.com/spf13/viper v1.21.0 github.com/spf13/viper v1.21.0
google.golang.org/grpc v1.81.1 google.golang.org/grpc v1.83.2
gopkg.in/yaml.v3 v3.0.1 gopkg.in/yaml.v3 v3.0.1
k8s.io/api v0.36.1 k8s.io/api v0.37.0
k8s.io/apiextensions-apiserver v0.36.1 k8s.io/apiextensions-apiserver v0.37.0
k8s.io/apimachinery v0.36.1 k8s.io/apimachinery v0.37.0
k8s.io/client-go v0.36.1 k8s.io/client-go v0.37.0
k8s.io/utils v0.0.0-20260507154919-ff6756f316d2 k8s.io/utils v0.0.0-20260707023825-cf1189d6abe3
sigs.k8s.io/controller-runtime v0.24.1 sigs.k8s.io/controller-runtime v0.24.1
sigs.k8s.io/kustomize/api v0.21.1 sigs.k8s.io/kustomize/api v0.21.1
sigs.k8s.io/kustomize/kyaml v0.21.1 sigs.k8s.io/kustomize/kyaml v0.21.1
) )
require ( require (
cel.dev/expr v0.25.1 // indirect cel.dev/expr v0.25.2 // indirect
github.com/Masterminds/semver/v3 v3.5.0 // indirect github.com/Masterminds/semver/v3 v3.5.0 // indirect
github.com/antlr4-go/antlr/v4 v4.13.1 // indirect github.com/antlr4-go/antlr/v4 v4.13.1 // indirect
github.com/avast/retry-go/v5 v5.0.0 // indirect github.com/avast/retry-go/v5 v5.0.0 // indirect
@ -40,38 +40,38 @@ require (
github.com/evanphx/json-patch/v5 v5.9.11 // indirect github.com/evanphx/json-patch/v5 v5.9.11 // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/fsnotify/fsnotify v1.9.0 // indirect github.com/fsnotify/fsnotify v1.9.0 // indirect
github.com/fxamacker/cbor/v2 v2.9.1 // indirect github.com/fxamacker/cbor/v2 v2.9.2 // indirect
github.com/go-errors/errors v1.5.1 // indirect github.com/go-errors/errors v1.5.1 // indirect
github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/logr v1.4.4 // indirect
github.com/go-logr/stdr v1.2.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-logr/zapr v1.3.0 // indirect github.com/go-logr/zapr v1.3.0 // indirect
github.com/go-openapi/jsonpointer v0.23.1 // indirect github.com/go-openapi/jsonpointer v1.0.0 // indirect
github.com/go-openapi/jsonreference v0.21.5 // indirect github.com/go-openapi/jsonreference v1.0.0 // indirect
github.com/go-openapi/swag v0.26.0 // indirect github.com/go-openapi/swag v0.27.1 // indirect
github.com/go-openapi/swag/cmdutils v0.26.0 // indirect github.com/go-openapi/swag/cmdutils v0.27.1 // indirect
github.com/go-openapi/swag/conv v0.26.0 // indirect github.com/go-openapi/swag/conv v0.27.1 // indirect
github.com/go-openapi/swag/fileutils v0.26.0 // indirect github.com/go-openapi/swag/fileutils v0.27.1 // indirect
github.com/go-openapi/swag/jsonname v0.26.0 // indirect github.com/go-openapi/swag/jsonutils v0.27.1 // indirect
github.com/go-openapi/swag/jsonutils v0.26.0 // indirect github.com/go-openapi/swag/loading v0.27.1 // indirect
github.com/go-openapi/swag/loading v0.26.0 // indirect github.com/go-openapi/swag/mangling v0.27.1 // indirect
github.com/go-openapi/swag/mangling v0.26.0 // indirect github.com/go-openapi/swag/netutils v0.27.1 // indirect
github.com/go-openapi/swag/netutils v0.26.0 // indirect github.com/go-openapi/swag/pools v0.27.1 // indirect
github.com/go-openapi/swag/stringutils v0.26.0 // indirect github.com/go-openapi/swag/stringutils v0.27.1 // indirect
github.com/go-openapi/swag/typeutils v0.26.0 // indirect github.com/go-openapi/swag/typeutils v0.27.1 // indirect
github.com/go-openapi/swag/yamlutils v0.26.0 // indirect github.com/go-openapi/swag/yamlutils v0.27.1 // indirect
github.com/go-task/slim-sprig/v3 v3.0.0 // indirect github.com/go-task/slim-sprig/v3 v3.0.0 // indirect
github.com/go-viper/mapstructure/v2 v2.4.0 // indirect github.com/go-viper/mapstructure/v2 v2.4.0 // indirect
github.com/google/cel-go v0.26.0 // indirect github.com/google/cel-go v0.29.2 // indirect
github.com/google/gnostic-models v0.7.1 // indirect github.com/google/gnostic-models v0.7.1 // indirect
github.com/google/go-cmp v0.7.0 // indirect github.com/google/go-cmp v0.7.0 // indirect
github.com/google/pprof v0.0.0-20260402051712-545e8a4df936 // indirect github.com/google/pprof v0.0.0-20260402051712-545e8a4df936 // indirect
github.com/google/uuid v1.6.0 // indirect github.com/google/uuid v1.6.0 // indirect
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 // indirect github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 // indirect
github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.3 // indirect github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.3 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.7 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.29.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect github.com/json-iterator/go v1.1.12 // indirect
github.com/kubernetes-csi/external-snapshotter/client/v8 v8.4.0 // indirect github.com/kubernetes-csi/external-snapshotter/client/v8 v8.6.0 // indirect
github.com/lib/pq v1.12.3 // indirect github.com/lib/pq v1.12.3 // indirect
github.com/moby/spdystream v0.5.1 // indirect github.com/moby/spdystream v0.5.1 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
@ -80,60 +80,59 @@ require (
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/pelletier/go-toml/v2 v2.2.4 // indirect github.com/pelletier/go-toml/v2 v2.2.4 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.87.1 // indirect github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.92.0 // indirect
github.com/prometheus/client_golang v1.23.2 // indirect github.com/prometheus/client_golang v1.24.0 // indirect
github.com/prometheus/client_model v0.6.2 // indirect github.com/prometheus/client_model v0.6.2 // indirect
github.com/prometheus/common v0.67.5 // indirect github.com/prometheus/common v0.70.0 // indirect
github.com/prometheus/procfs v0.19.2 // indirect github.com/prometheus/procfs v0.21.1 // indirect
github.com/sagikazarmark/locafero v0.11.0 // indirect github.com/sagikazarmark/locafero v0.11.0 // indirect
github.com/snorwin/jsonpatch v1.5.0 // indirect github.com/snorwin/jsonpatch v1.5.0 // indirect
github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 // indirect github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 // indirect
github.com/spf13/afero v1.15.0 // indirect github.com/spf13/afero v1.15.0 // indirect
github.com/spf13/cast v1.10.0 // indirect github.com/spf13/cast v1.10.0 // indirect
github.com/spf13/pflag v1.0.10 // indirect github.com/spf13/pflag v1.0.10 // indirect
github.com/stoewer/go-strcase v1.3.1 // indirect
github.com/subosito/gotenv v1.6.0 // indirect github.com/subosito/gotenv v1.6.0 // indirect
github.com/thoas/go-funk v0.9.3 // indirect github.com/thoas/go-funk v0.9.3 // indirect
github.com/x448/float16 v0.8.4 // indirect github.com/x448/float16 v0.8.4 // indirect
github.com/xlab/treeprint v1.2.0 // indirect github.com/xlab/treeprint v1.2.0 // indirect
go.opentelemetry.io/auto/sdk v1.2.1 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.65.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.69.0 // indirect
go.opentelemetry.io/otel v1.43.0 // indirect go.opentelemetry.io/otel v1.44.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.40.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.44.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.40.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.44.0 // indirect
go.opentelemetry.io/otel/metric v1.43.0 // indirect go.opentelemetry.io/otel/metric v1.44.0 // indirect
go.opentelemetry.io/otel/sdk v1.43.0 // indirect go.opentelemetry.io/otel/sdk v1.44.0 // indirect
go.opentelemetry.io/otel/trace v1.43.0 // indirect go.opentelemetry.io/otel/trace v1.44.0 // indirect
go.opentelemetry.io/proto/otlp v1.9.0 // indirect go.opentelemetry.io/proto/otlp v1.10.0 // indirect
go.uber.org/multierr v1.11.0 // indirect go.uber.org/multierr v1.11.0 // indirect
go.uber.org/zap v1.28.0 // indirect go.uber.org/zap v1.28.0 // indirect
go.yaml.in/yaml/v2 v2.4.4 // indirect go.yaml.in/yaml/v2 v2.4.4 // indirect
go.yaml.in/yaml/v3 v3.0.4 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect
golang.org/x/exp v0.0.0-20251219203646-944ab1f22d93 // indirect golang.org/x/exp v0.0.0-20260410095643-746e56fc9e2f // indirect
golang.org/x/mod v0.35.0 // indirect golang.org/x/mod v0.38.0 // indirect
golang.org/x/net v0.53.0 // indirect golang.org/x/net v0.58.0 // indirect
golang.org/x/oauth2 v0.36.0 // indirect golang.org/x/oauth2 v0.36.0 // indirect
golang.org/x/sync v0.20.0 // indirect golang.org/x/sync v0.22.0 // indirect
golang.org/x/sys v0.43.0 // indirect golang.org/x/sys v0.47.0 // indirect
golang.org/x/term v0.42.0 // indirect golang.org/x/term v0.45.0 // indirect
golang.org/x/text v0.36.0 // indirect golang.org/x/text v0.41.0 // indirect
golang.org/x/time v0.15.0 // indirect golang.org/x/time v0.15.0 // indirect
golang.org/x/tools v0.44.0 // indirect golang.org/x/tools v0.48.0 // indirect
gomodules.xyz/jsonpatch/v2 v2.5.0 // indirect gomodules.xyz/jsonpatch/v2 v2.5.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20260226221140-a57be14db171 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20260526163538-3dc84a4a5aaa // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20260319201613-d00831a3d3e7 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20260610212136-7ab31c22f7ad // indirect
google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af // indirect google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af // indirect
gopkg.in/evanphx/json-patch.v4 v4.13.0 // indirect gopkg.in/evanphx/json-patch.v4 v4.13.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/inf.v0 v0.9.1 // indirect
k8s.io/apiserver v0.36.1 // indirect k8s.io/apiserver v0.37.0 // indirect
k8s.io/component-base v0.36.1 // indirect k8s.io/component-base v0.37.0 // indirect
k8s.io/klog/v2 v2.140.0 // indirect k8s.io/klog/v2 v2.140.0 // indirect
k8s.io/kube-openapi v0.0.0-20260502001324-b7f5293f4787 // indirect k8s.io/kube-openapi v0.0.0-20260721132016-d427ff9ee9ad // indirect
k8s.io/streaming v0.36.1 // indirect k8s.io/streaming v0.37.0 // indirect
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.34.0 // indirect sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.36.0 // indirect
sigs.k8s.io/gateway-api v1.5.0 // indirect sigs.k8s.io/gateway-api v1.6.0 // indirect
sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect
sigs.k8s.io/randfill v1.0.0 // indirect sigs.k8s.io/randfill v1.0.0 // indirect
sigs.k8s.io/structured-merge-diff/v6 v6.4.0 // indirect sigs.k8s.io/structured-merge-diff/v6 v6.4.2 // indirect
sigs.k8s.io/yaml v1.6.0 // indirect sigs.k8s.io/yaml v1.6.0 // indirect
) )

283
go.sum
View File

@ -1,5 +1,5 @@
cel.dev/expr v0.25.1 h1:1KrZg61W6TWSxuNZ37Xy49ps13NUovb66QLprthtwi4= cel.dev/expr v0.25.2 h1:K6j46C81hXtZQfuX60cVWQFBJahKSE2gfRbNuvr5bFs=
cel.dev/expr v0.25.1/go.mod h1:hrXvqGP6G6gyx8UAHSHJ5RGk//1Oj5nXQ2NI02Nrsg4= cel.dev/expr v0.25.2/go.mod h1:hrXvqGP6G6gyx8UAHSHJ5RGk//1Oj5nXQ2NI02Nrsg4=
github.com/Masterminds/semver/v3 v3.5.0 h1:kQceYJfbupGfZOKZQg0kou0DgAKhzDg2NZPAwZ/2OOE= github.com/Masterminds/semver/v3 v3.5.0 h1:kQceYJfbupGfZOKZQg0kou0DgAKhzDg2NZPAwZ/2OOE=
github.com/Masterminds/semver/v3 v3.5.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= github.com/Masterminds/semver/v3 v3.5.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
github.com/antlr4-go/antlr/v4 v4.13.1 h1:SqQKkuVZ+zWkMMNkjy5FZe5mr5WURWnlpmOuzYWrPrQ= github.com/antlr4-go/antlr/v4 v4.13.1 h1:SqQKkuVZ+zWkMMNkjy5FZe5mr5WURWnlpmOuzYWrPrQ=
@ -14,22 +14,22 @@ github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM
github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ=
github.com/cenkalti/backoff/v5 v5.0.3 h1:ZN+IMa753KfX5hd8vVaMixjnqRZ3y8CuJKRKj1xcsSM= github.com/cenkalti/backoff/v5 v5.0.3 h1:ZN+IMa753KfX5hd8vVaMixjnqRZ3y8CuJKRKj1xcsSM=
github.com/cenkalti/backoff/v5 v5.0.3/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw= github.com/cenkalti/backoff/v5 v5.0.3/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw=
github.com/cert-manager/cert-manager v1.20.2 h1:CimnY00nLqB2lmxhoSuEC4GDMFDK7JCXqyjwMM9ndIQ= github.com/cert-manager/cert-manager v1.21.1 h1:0LttV37Q5c2CBNoHkjuI8sLKTXWZDC2SwQkxrBMKV9w=
github.com/cert-manager/cert-manager v1.20.2/go.mod h1:1g/+a/WK5zWH/dXPZa3dMD3aJQJNRXQu+PN17C6WrOw= github.com/cert-manager/cert-manager v1.21.1/go.mod h1:sVwmLBWoiB1BRd0rJElBGQuiu94z4k7p3Kd0FRQyfgw=
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cloudnative-pg/api v1.29.1 h1:FWr8S7EQeOfdhYXyr2cof8wUXLARZiiQt5Qa6ltED7w= github.com/cloudnative-pg/api v1.30.0 h1:L8hnvV/tPEQA1xYEi41FUBFA7FUNVGju8+SlgFlDDjI=
github.com/cloudnative-pg/api v1.29.1/go.mod h1:QtWF3yzSvIfORMHaSkPAk/o3bhCJwEHJgN3riyRiz3o= github.com/cloudnative-pg/api v1.30.0/go.mod h1:XrKBbOWObL33si0FNuwX4uHNf5JShiZyOUqd6LxbJQo=
github.com/cloudnative-pg/barman-cloud v0.5.1 h1:vjkXrrxo2DQXHT9u9usqhtaHiPZ/lTfDVs/pIWYTepQ= github.com/cloudnative-pg/barman-cloud v0.6.0 h1:OtBFmCDyVUAcgFa++FIoCCJwPfd5TtqK3PH6DGPcpkA=
github.com/cloudnative-pg/barman-cloud v0.5.1/go.mod h1:XPc5IUFP1y4cZX1sg+Pd8j9V4tmUEVnv3BGCpfQOOg8= github.com/cloudnative-pg/barman-cloud v0.6.0/go.mod h1:eqSPRGz/s8M0Mea8mkqiVQUTkoSquAhvJF49feh+Ks4=
github.com/cloudnative-pg/cloudnative-pg v1.29.1 h1:ZNEt1TMlnQKXI1kho2UqQuqdfvIvjGln4kN7C1lsmGA= github.com/cloudnative-pg/cloudnative-pg v1.30.0 h1:fnhVq44xXx97MNiuvJsPrX1vSjYbgdyBK5MSGfdHdp0=
github.com/cloudnative-pg/cloudnative-pg v1.29.1/go.mod h1:Sbgx9jVmkle4/gR2U5JHrzDd74sRPOBHDtPkvncg5v8= github.com/cloudnative-pg/cloudnative-pg v1.30.0/go.mod h1:QkolwBOWZ+GvAiJt6KpDSymwkpf0K19/p4Q6MQlTM8U=
github.com/cloudnative-pg/cnpg-i v0.5.0 h1:/TOzpNT6cwNgrpftTtrnLKdoHgMwd+88vZgXjlVgXeE= github.com/cloudnative-pg/cnpg-i v0.6.0 h1:LA//DLkFOLIjU0ASOpFkydZhGir9IAIDfgSsTTX9IpU=
github.com/cloudnative-pg/cnpg-i v0.5.0/go.mod h1:7Gh4+UzhBpGhr4DreB1GN9wGYfvxwXCXZUyVt3zE/3I= github.com/cloudnative-pg/cnpg-i v0.6.0/go.mod h1:4kcpLAj+feMTnh0TVadXRASdVnEhBytNSm/BvktLgmI=
github.com/cloudnative-pg/cnpg-i-machinery v0.4.2 h1:0reS9MtyLYINHXQ/MfxJ9jp39hhBf8e3Qdj+T5Nsq6I= github.com/cloudnative-pg/cnpg-i-machinery v0.4.2 h1:0reS9MtyLYINHXQ/MfxJ9jp39hhBf8e3Qdj+T5Nsq6I=
github.com/cloudnative-pg/cnpg-i-machinery v0.4.2/go.mod h1:gvrKabgxXq0zGthXGucemDdsxakLEQDMxn43M4HLW30= github.com/cloudnative-pg/cnpg-i-machinery v0.4.2/go.mod h1:gvrKabgxXq0zGthXGucemDdsxakLEQDMxn43M4HLW30=
github.com/cloudnative-pg/machinery v0.4.0 h1:3sfqrBptH4QQSVB4g10Z+7aiQRnh4g+6AsqsK0ibKaQ= github.com/cloudnative-pg/machinery v0.6.0 h1:faHxS1AK75XkzppOcAKdOexKmzX7iGK6jX2b9itssb4=
github.com/cloudnative-pg/machinery v0.4.0/go.mod h1:OIwaTYAnLv8PmBmBvEf0BvMK2JBX6J+naTMg9UgV1FQ= github.com/cloudnative-pg/machinery v0.6.0/go.mod h1:wyw9E/0uYGAixp9+0PLsJ6qHiEiFKDkeXb9O2dRi2w0=
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@ -47,8 +47,8 @@ github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHk
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k=
github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
github.com/fxamacker/cbor/v2 v2.9.1 h1:2rWm8B193Ll4VdjsJY28jxs70IdDsHRWgQYAI80+rMQ= github.com/fxamacker/cbor/v2 v2.9.2 h1:X4Ksno9+x3cz0TZv69ec1hxP/+tymuR8PXQJyDwfh78=
github.com/fxamacker/cbor/v2 v2.9.1/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ= github.com/fxamacker/cbor/v2 v2.9.2/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ=
github.com/gkampitakis/ciinfo v0.3.2 h1:JcuOPk8ZU7nZQjdUhctuhQofk7BGHuIy0c9Ez8BNhXs= github.com/gkampitakis/ciinfo v0.3.2 h1:JcuOPk8ZU7nZQjdUhctuhQofk7BGHuIy0c9Ez8BNhXs=
github.com/gkampitakis/ciinfo v0.3.2/go.mod h1:1NIwaOcFChN4fa/B0hEBdAb6npDlFL8Bwx4dfRLRqAo= github.com/gkampitakis/ciinfo v0.3.2/go.mod h1:1NIwaOcFChN4fa/B0hEBdAb6npDlFL8Bwx4dfRLRqAo=
github.com/gkampitakis/go-diff v1.3.2 h1:Qyn0J9XJSDTgnsgHRdz9Zp24RaJeKMUHg2+PDZZdC4M= github.com/gkampitakis/go-diff v1.3.2 h1:Qyn0J9XJSDTgnsgHRdz9Zp24RaJeKMUHg2+PDZZdC4M=
@ -60,46 +60,46 @@ github.com/go-errors/errors v1.5.1/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3Bop
github.com/go-faker/faker/v4 v4.4.1 h1:LY1jDgjVkBZWIhATCt+gkl0x9i/7wC61gZx73GTFb+Q= github.com/go-faker/faker/v4 v4.4.1 h1:LY1jDgjVkBZWIhATCt+gkl0x9i/7wC61gZx73GTFb+Q=
github.com/go-faker/faker/v4 v4.4.1/go.mod h1:HRLrjis+tYsbFtIHufEPTAIzcZiRu0rS9EYl2Ccwme4= github.com/go-faker/faker/v4 v4.4.1/go.mod h1:HRLrjis+tYsbFtIHufEPTAIzcZiRu0rS9EYl2Ccwme4=
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.4 h1:tG4xh9yMsRCAiodLVTxyrkzSZ9+o0L1Kg/+cPVcbP/8=
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/logr v1.4.4/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ= github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ=
github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg= github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg=
github.com/go-openapi/jsonpointer v0.23.1 h1:1HBACs7XIwR2RcmItfdSFlALhGbe6S92p0ry4d1GWg4= github.com/go-openapi/jsonpointer v1.0.0 h1:kR9tHqY0CtZaOPVFm622dPVNhrvYpwr4uCxgL3h1H8s=
github.com/go-openapi/jsonpointer v0.23.1/go.mod h1:iWRmZTrGn7XwYhtPt/fvdSFj1OfNBngqRT2UG3BxSqY= github.com/go-openapi/jsonpointer v1.0.0/go.mod h1:Z3rw7dWu1p9IgitXCFamSlA5lmDiklEB6vkaxcNZW5Y=
github.com/go-openapi/jsonreference v0.21.5 h1:6uCGVXU/aNF13AQNggxfysJ+5ZcU4nEAe+pJyVWRdiE= github.com/go-openapi/jsonreference v1.0.0 h1:jlmTr6torcd1YgDQvSfNmRtKzYDO4FGBkrAdlAVWnpY=
github.com/go-openapi/jsonreference v0.21.5/go.mod h1:u25Bw85sX4E2jzFodh1FOKMTZLcfifd1Q+iKKOUxExw= github.com/go-openapi/jsonreference v1.0.0/go.mod h1:jtwdyGbJk0Xhe5Y+rwtglQP6Sb1WZST4rT32LWB+sv0=
github.com/go-openapi/swag v0.26.0 h1:GVDXCmfvhfu1BxiHo8/FA+BbKmhecHnG3varjON5/RI= github.com/go-openapi/swag v0.27.1 h1:VotvOLWW8q/EAxB0YdsBBGC8XYyeL1YwBj2ungAGPNg=
github.com/go-openapi/swag v0.26.0/go.mod h1:82g3193sZJRbocs7bNCqGfIgq8pkuwVwCfhKIRlEQF0= github.com/go-openapi/swag v0.27.1/go.mod h1:GTkJPwHfhJp6MWr4/rCh64HVI3Ofu+tcsbfjfHmTxpE=
github.com/go-openapi/swag/cmdutils v0.26.0 h1:iowihOcvq7y4egO8cOq0dmfohz6wfeQ63U1EnuhO2TU= github.com/go-openapi/swag/cmdutils v0.27.1 h1:I7sYqaWVl5mq0NEmNQkAmFDyNin9ufvMX/p2zwtQaOE=
github.com/go-openapi/swag/cmdutils v0.26.0/go.mod h1:Sm1MVFMkF6guJJ+pQqHnQA3N0j9qALV3NxzDSv6bETM= github.com/go-openapi/swag/cmdutils v0.27.1/go.mod h1:Sm1MVFMkF6guJJ+pQqHnQA3N0j9qALV3NxzDSv6bETM=
github.com/go-openapi/swag/conv v0.26.0 h1:5yGGsPYI1ZCva93U0AoKi/iZrNhaJEjr324YVsiD89I= github.com/go-openapi/swag/conv v0.27.1 h1:8wi9ZG+olmY1wXphl93EWniPtbSPkXM/feH7FgjsvrU=
github.com/go-openapi/swag/conv v0.26.0/go.mod h1:tpAmIL7X58VPnHHiSO4uE3jBeRamGsFsfdDeDtb5ECE= github.com/go-openapi/swag/conv v0.27.1/go.mod h1:QbqMivkpKhC3g1B1GGGOJ6ANewI3S62dbzYu3Duowqs=
github.com/go-openapi/swag/fileutils v0.26.0 h1:WJoPRvsA7QRiiWluowkLJa9jaYR7FCuxmDvnCgaRRxU= github.com/go-openapi/swag/fileutils v0.27.1 h1:QQqBSoi5mW4XpU85nS0mLcA+zAE6vLzrb0QkmLKf9oM=
github.com/go-openapi/swag/fileutils v0.26.0/go.mod h1:0WDJ7lp67eNjPMO50wAWYlKvhOb6CQ37rzR7wrgI8Tc= github.com/go-openapi/swag/fileutils v0.27.1/go.mod h1:VvJFZLTZS0AI854gEQz5tk7dBESdLjiNUMSZ/th2ry8=
github.com/go-openapi/swag/jsonname v0.26.0 h1:gV1NFX9M8avo0YSpmWogqfQISigCmpaiNci8cGECU5w= github.com/go-openapi/swag/jsonutils v0.27.1 h1:SVgK3i4USzCU5mibOOS/l4ea2h9UQXy7J7RNLTjuXjU=
github.com/go-openapi/swag/jsonname v0.26.0/go.mod h1:urBBR8bZNoDYGr653ynhIx+gTeIz0ARZxHkAPktJK2M= github.com/go-openapi/swag/jsonutils v0.27.1/go.mod h1:tdlEpZqdcQ17uj6J4YdK9vd8It5qWMwjWXOs0tjpRlk=
github.com/go-openapi/swag/jsonutils v0.26.0 h1:FawFML2iAXsPqmERscuMPIHmFsoP1tOqWkxBaKNMsnA= github.com/go-openapi/swag/jsonutils/fixtures_test v0.27.1 h1:mJu3COL9WEaZVp/Kf2PRMi7tPszPEJfSr/OO75ynCs8=
github.com/go-openapi/swag/jsonutils v0.26.0/go.mod h1:2VmA0CJlyFqgawOaPI9psnjFDqzyivIqLYN34t9p91E= github.com/go-openapi/swag/jsonutils/fixtures_test v0.27.1/go.mod h1:mofwUWx70wvskwESqRJ//k/9kURmCgyJl5m5Ppoh5kY=
github.com/go-openapi/swag/jsonutils/fixtures_test v0.26.0 h1:apqeINu/ICHouqiRZbyFvuDge5jCmmLTqGQ9V95EaOM= github.com/go-openapi/swag/loading v0.27.1 h1:/DxUgDXKbBX4bcn7r9uEXfJyzN5XpiJmZplzQTjrRCY=
github.com/go-openapi/swag/jsonutils/fixtures_test v0.26.0/go.mod h1:AyM6QT8uz5IdKxk5akv0y6u4QvcL9GWERt0Jx/F/R8Y= github.com/go-openapi/swag/loading v0.27.1/go.mod h1:jvGh3iA2+zyUUycB5fgJWzeHnhrpvGnJJM0RVE9ZShE=
github.com/go-openapi/swag/loading v0.26.0 h1:Apg6zaKhCJurpJer0DCxq99qwmhFddBhaMX7kilDcko= github.com/go-openapi/swag/mangling v0.27.1 h1:yC9D0HyUE8gbP+BfmGx9+AA89ikwZTMjESK3OnnoaqA=
github.com/go-openapi/swag/loading v0.26.0/go.mod h1:dBxQ/6V2uBaAQdevN18VELE6xSpJWZxLX4txe12JwDg= github.com/go-openapi/swag/mangling v0.27.1/go.mod h1:jtBE2+V+3pILxOR7Vgce+Cwp6A2PgZbvVqfNntbVs0w=
github.com/go-openapi/swag/mangling v0.26.0 h1:Du2YC4YLA/Y5m/YKQd7AnY5qq0wRKSFZTTt8ktFaXcQ= github.com/go-openapi/swag/netutils v0.27.1 h1:mICMFoS82F5TZ4Zy3cqmcQk+BFeCp3Uyq3Np7GI0/qU=
github.com/go-openapi/swag/mangling v0.26.0/go.mod h1:jifS7W9vbg+pw63bT+GI53otluMQL3CeemuyCHKwVx0= github.com/go-openapi/swag/netutils v0.27.1/go.mod h1:J+WYyFMLtvtCGqa6jLv+YNUmIKI3ZRQRrvfNDMoQoEQ=
github.com/go-openapi/swag/netutils v0.26.0 h1:CmZp+ZT7HrmFwrC3GdGsXBq2+42T1bjKBapcqVpIs3c= github.com/go-openapi/swag/pools v0.27.1 h1:9LeadcMyb2GJCbXX5hVQDbZ2Lq9TL4dCs/nx1j5DO0E=
github.com/go-openapi/swag/netutils v0.26.0/go.mod h1:5iK+Ok3ZohWWex1C50BFTPexi03UaPwjW4Oj8kgrpwo= github.com/go-openapi/swag/pools v0.27.1/go.mod h1:kVQefhSK5RWuRe7BXsL8htgBPAMpN7HDGpGEknqugeE=
github.com/go-openapi/swag/stringutils v0.26.0 h1:qZQngLxs5s7SLijc3N2ZO+fUq2o8LjuWAASSrJuh+xg= github.com/go-openapi/swag/stringutils v0.27.1 h1:ZXePZ0r2p1qSjo8tD3Un4vFj8+FqlCkczxDrJIhYUp8=
github.com/go-openapi/swag/stringutils v0.26.0/go.mod h1:sWn5uY+QIIspwPhvgnqJsH8xqFT2ZbYcvbcFanRyhFE= github.com/go-openapi/swag/stringutils v0.27.1/go.mod h1:lzRN95CxXmA03XcDWHLOb6nOMcxCqR5rGY0lOgsfRoM=
github.com/go-openapi/swag/typeutils v0.26.0 h1:2kdEwdiNWy+JJdOvu5MA2IIg2SylWAFuuyQIKYybfq4= github.com/go-openapi/swag/typeutils v0.27.1 h1:KSTdFlfnse4r6dP9IrEnwMldjE+zs71UeEB3//PtVXc=
github.com/go-openapi/swag/typeutils v0.26.0/go.mod h1:oovDuIUvTrEHVMqWilQzKzV4YlSKgyZmFh7AlfABNVE= github.com/go-openapi/swag/typeutils v0.27.1/go.mod h1:Srm0xFNRZ1Y+vCxJclo5qzx8aj+1pAKda/YfFPrG0dQ=
github.com/go-openapi/swag/yamlutils v0.26.0 h1:H7O8l/8NJJQ/oiReEN+oMpnGMyt8G0hl460nRZxhLMQ= github.com/go-openapi/swag/yamlutils v0.27.1 h1:ftxv6xvXb1E3zohUc+okZ9nSqNb9StQX/FXnKZ98sQA=
github.com/go-openapi/swag/yamlutils v0.26.0/go.mod h1:1evKEGAtP37Pkwcc7EWMF0hedX0/x3Rkvei2wtG/TbU= github.com/go-openapi/swag/yamlutils v0.27.1/go.mod h1:bnxFIB1qewGRiZHypXGZ3fNgf13/0HfRgnS/iZBDrOo=
github.com/go-openapi/testify/enable/yaml/v2 v2.4.2 h1:5zRca5jw7lzVREKCZVNBpysDNBjj74rBh0N2BGQbSR0= github.com/go-openapi/testify/enable/yaml/v2 v2.6.0 h1:gGHwAJ0R/5jU8BEGDbfRNR3hL68dAVi84WuOApp29B0=
github.com/go-openapi/testify/enable/yaml/v2 v2.4.2/go.mod h1:XVevPw5hUXuV+5AkI1u1PeAm27EQVrhXTTCPAF85LmE= github.com/go-openapi/testify/enable/yaml/v2 v2.6.0/go.mod h1:tY+St1SGq4NFl0QIqdTY4aEdbChAHxhyB77XQi9iJCo=
github.com/go-openapi/testify/v2 v2.4.2 h1:tiByHpvE9uHrrKjOszax7ZvKB7QOgizBWGBLuq0ePx4= github.com/go-openapi/testify/v2 v2.6.0 h1:5PKH2HE7YJ/LuRPQGvSxBRlFXNQhSetBLlGAgUEu3ug=
github.com/go-openapi/testify/v2 v2.4.2/go.mod h1:SgsVHtfooshd0tublTtJ50FPKhujf47YRqauXXOUxfw= github.com/go-openapi/testify/v2 v2.6.0/go.mod h1:SgsVHtfooshd0tublTtJ50FPKhujf47YRqauXXOUxfw=
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs= github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs=
@ -108,8 +108,8 @@ github.com/goccy/go-yaml v1.18.0 h1:8W7wMFS12Pcas7KU+VVkaiCng+kG8QiFeFwzFb+rwuw=
github.com/goccy/go-yaml v1.18.0/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA= github.com/goccy/go-yaml v1.18.0/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA=
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
github.com/google/cel-go v0.26.0 h1:DPGjXackMpJWH680oGY4lZhYjIameYmR+/6RBdDGmaI= github.com/google/cel-go v0.29.2 h1:ZtDxkeiMmz0mxbKDYiNkE5Lk7V5edMRcaaDf2jX002k=
github.com/google/cel-go v0.26.0/go.mod h1:A9O8OU9rdvrK5MQyrqfIxo1a0u4g3sF8KB6PUIaryMM= github.com/google/cel-go v0.29.2/go.mod h1:X0bD6iVNR8pkROSOoHVdgTkzmRcosof7WQqCD6wcMc8=
github.com/google/gnostic-models v0.7.1 h1:SisTfuFKJSKM5CPZkffwi6coztzzeYUhc3v4yxLWH8c= github.com/google/gnostic-models v0.7.1 h1:SisTfuFKJSKM5CPZkffwi6coztzzeYUhc3v4yxLWH8c=
github.com/google/gnostic-models v0.7.1/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ= github.com/google/gnostic-models v0.7.1/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
@ -125,22 +125,22 @@ github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 h1:JeSE6pjso5T
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674/go.mod h1:r4w70xmWCQKmi1ONH4KIaBptdivuRPyosB9RmPlGEwA= github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674/go.mod h1:r4w70xmWCQKmi1ONH4KIaBptdivuRPyosB9RmPlGEwA=
github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.3 h1:B+8ClL/kCQkRiU82d9xajRPKYMrB7E0MbtzWVi1K4ns= github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.3 h1:B+8ClL/kCQkRiU82d9xajRPKYMrB7E0MbtzWVi1K4ns=
github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.3/go.mod h1:NbCUVmiS4foBGBHOYlCT25+YmGpJ32dZPi75pGEUpj4= github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.3/go.mod h1:NbCUVmiS4foBGBHOYlCT25+YmGpJ32dZPi75pGEUpj4=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.7 h1:X+2YciYSxvMQK0UZ7sg45ZVabVZBeBuvMkmuI2V3Fak= github.com/grpc-ecosystem/grpc-gateway/v2 v2.29.0 h1:5VipnvEpbqr2gA2VbM+nYVbkIF28c5ZQfqCBQ5g2xfk=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.7/go.mod h1:lW34nIZuQ8UDPdkon5fmfp2l3+ZkQ2me/+oecHYLOII= github.com/grpc-ecosystem/grpc-gateway/v2 v2.29.0/go.mod h1:Hyl3n6Twe1hvtd9XUXDec4pTvgMSEixRuQKPTMH2bNs=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/joshdk/go-junit v1.0.0 h1:S86cUKIdwBHWwA6xCmFlf3RTLfVXYQfvanM5Uh+K6GE= github.com/joshdk/go-junit v1.0.0 h1:S86cUKIdwBHWwA6xCmFlf3RTLfVXYQfvanM5Uh+K6GE=
github.com/joshdk/go-junit v1.0.0/go.mod h1:TiiV0PqkaNfFXjEiyjWM3XXrhVyCa1K4Zfga6W52ung= github.com/joshdk/go-junit v1.0.0/go.mod h1:TiiV0PqkaNfFXjEiyjWM3XXrhVyCa1K4Zfga6W52ung=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= github.com/klauspost/compress v1.19.0 h1:sXLILfc9jV2QYWkzFOPWStmcUVH2RHEB1JCdY2oVvCQ=
github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= github.com/klauspost/compress v1.19.0/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/kubernetes-csi/external-snapshotter/client/v8 v8.4.0 h1:bMqrb3UHgHbP+PW9VwiejfDJU1R0PpXVZNMdeH8WYKI= github.com/kubernetes-csi/external-snapshotter/client/v8 v8.6.0 h1:FtGewu2k6HWw6evLGXY8JqUZ9eHpti1kd3e4amj+ilA=
github.com/kubernetes-csi/external-snapshotter/client/v8 v8.4.0/go.mod h1:E3vdYxHj2C2q6qo8/Da4g7P+IcwqRZyy3gJBzYybV9Y= github.com/kubernetes-csi/external-snapshotter/client/v8 v8.6.0/go.mod h1:Vxl89NySJ45J+ah3NTMan/KJXW+NpcGHE2Tw0GSw53k=
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
github.com/lib/pq v1.12.3 h1:tTWxr2YLKwIvK90ZXEw8GP7UFHtcbTtty8zsI+YjrfQ= github.com/lib/pq v1.12.3 h1:tTWxr2YLKwIvK90ZXEw8GP7UFHtcbTtty8zsI+YjrfQ=
@ -161,10 +161,10 @@ github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 h1:n6/
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00/go.mod h1:Pm3mSP3c5uWn86xMLZ5Sa7JB9GsEZySvHYXCTK4E9q4= github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00/go.mod h1:Pm3mSP3c5uWn86xMLZ5Sa7JB9GsEZySvHYXCTK4E9q4=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/onsi/ginkgo/v2 v2.29.0 h1:rfh+ZFjgJhYWRoIqVf3Uwx/W20yLrcrE2h2GmYVRaag= github.com/onsi/ginkgo/v2 v2.32.1 h1:6tlvcDm/3sE8lGJbZ4+d4mO3RLy24/tQWOFzVSQNIfw=
github.com/onsi/ginkgo/v2 v2.29.0/go.mod h1:+aXOY+vzZ5mu2iI2HpTZUPmM//oQfsNFX6gU9kNcA44= github.com/onsi/ginkgo/v2 v2.32.1/go.mod h1:+aXOY+vzZ5mu2iI2HpTZUPmM//oQfsNFX6gU9kNcA44=
github.com/onsi/gomega v1.41.0 h1:OwKp4pXNgVxf6sCplzYo794OFNuoL2q2SBMU5NSWOjA= github.com/onsi/gomega v1.43.0 h1:VlG/1FxqNxhSO+lq/OHBNaaqwiBK/mO8JbVkX9Y+FeU=
github.com/onsi/gomega v1.41.0/go.mod h1:M/Uqpu/8qTjtzCLUA2zJHX9Iilrau25x1PdoSRbWh5A= github.com/onsi/gomega v1.43.0/go.mod h1:REff/hsDsodHoKlWsP2mAPhu1+5/6hVYNf9rIEBpeSg=
github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4= github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4=
github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY= github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
@ -172,16 +172,16 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.87.1 h1:wyKanf+IFdbIqbDNYGt+f1dabLErLWtBaxd0KaAx4aM= github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.92.0 h1:cgcHnhpMbk86QzIe23vwUiIUNBB0kftdOA9JJA83ASA=
github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.87.1/go.mod h1:WHiLZmOWVop/MoYvRD58LfnPeyE+dcITby/jQjg83Hw= github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.92.0/go.mod h1:eGo3VN8Kq5Fd0M7Cdx0oqbIxo753t99ojUZFVQkO1UM=
github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h0RJWRi/o0o= github.com/prometheus/client_golang v1.24.0 h1:5XStIklKuAtJSNpdD3s8XJj/Yv78IQmE1kbNk87JrAI=
github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg= github.com/prometheus/client_golang v1.24.0/go.mod h1:QcsNdotprC2nS4BTM2ucbcqxd2CeXTEa9jW7zHO9iDE=
github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk= github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk=
github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE=
github.com/prometheus/common v0.67.5 h1:pIgK94WWlQt1WLwAC5j2ynLaBRDiinoAb86HZHTUGI4= github.com/prometheus/common v0.70.0 h1:bcpru3tWPVnxGnETLgOV5jbp/JRXgYEyv65CuBLAMMI=
github.com/prometheus/common v0.67.5/go.mod h1:SjE/0MzDEEAyrdr5Gqc6G+sXI67maCxzaT3A2+HqjUw= github.com/prometheus/common v0.70.0/go.mod h1:S/SFasQmgGiYH6C81LKCtYa8QACgthGg5zxL2udV7SY=
github.com/prometheus/procfs v0.19.2 h1:zUMhqEW66Ex7OXIiDkll3tl9a1ZdilUOd/F6ZXw4Vws= github.com/prometheus/procfs v0.21.1 h1:GljZCt+zSTS+NZq88cyQ1LjZ+RCHp3uVuabBWA5+OJI=
github.com/prometheus/procfs v0.19.2/go.mod h1:M0aotyiemPhBCM0z5w87kL22CxfcH05ZpYlu+b4J7mw= github.com/prometheus/procfs v0.21.1/go.mod h1:aB55Cww9pdSJVHk0hUf0inxWyyjPogFIjmHKYgMKmtY=
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
@ -204,19 +204,12 @@ github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk=
github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/viper v1.21.0 h1:x5S+0EU27Lbphp4UKm1C+1oQO+rKx36vfCoaVebLFSU= github.com/spf13/viper v1.21.0 h1:x5S+0EU27Lbphp4UKm1C+1oQO+rKx36vfCoaVebLFSU=
github.com/spf13/viper v1.21.0/go.mod h1:P0lhsswPGWD/1lZJ9ny3fYnVqxiegrlNrEmgLjbTCAY= github.com/spf13/viper v1.21.0/go.mod h1:P0lhsswPGWD/1lZJ9ny3fYnVqxiegrlNrEmgLjbTCAY=
github.com/stoewer/go-strcase v1.3.1 h1:iS0MdW+kVTxgMoE1LAZyMiYJFKlOzLooE4MxjirtkAs=
github.com/stoewer/go-strcase v1.3.1/go.mod h1:fAH5hQ5pehh+j3nZfvwdk2RgEgQjAoM8wodgtPmh1xo=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.3 h1:jmXUvGomnU1o3W/V5h2VEradbpJDwGrzugQQvL0POH4=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/objx v0.5.3/go.mod h1:rDQraq+vQZU7Fde9LOZLr8Tax6zZvy4kuNKF+QYS+U0=
github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
@ -237,24 +230,24 @@ github.com/xlab/treeprint v1.2.0 h1:HzHnuAF1plUN2zGlAFHbSQP2qJ0ZAD3XF5XD7OesXRQ=
github.com/xlab/treeprint v1.2.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0= github.com/xlab/treeprint v1.2.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0=
go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=
go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.65.0 h1:7iP2uCb7sGddAr30RRS6xjKy7AZ2JtTOPA3oolgVSw8= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.69.0 h1:8tvICD4vSTOOsNrsI4Ljf6C+6UKvpTEH5XY3JMoyPoo=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.65.0/go.mod h1:c7hN3ddxs/z6q9xwvfLPk+UHlWRQyaeR1LdgfL/66l0= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.69.0/go.mod h1:z9+yiacE0IHRqM4qFfkbt/JYlmYXgss8GY/jXoNuPJI=
go.opentelemetry.io/otel v1.43.0 h1:mYIM03dnh5zfN7HautFE4ieIig9amkNANT+xcVxAj9I= go.opentelemetry.io/otel v1.44.0 h1:JjwHmHpA4iZ3wBxluu2fbbE7j4kqlE8jXyAyPXH7HqU=
go.opentelemetry.io/otel v1.43.0/go.mod h1:JuG+u74mvjvcm8vj8pI5XiHy1zDeoCS2LB1spIq7Ay0= go.opentelemetry.io/otel v1.44.0/go.mod h1:BMgjTHL9WPRlRjL2oZCBTL4whCGtXch2H4BhOPIAyYc=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.40.0 h1:QKdN8ly8zEMrByybbQgv8cWBcdAarwmIPZ6FThrWXJs= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.44.0 h1:4YsVu3B8+3qtWYYrsUYgn0OG78pN0rnNPRGX4SbokQI=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.40.0/go.mod h1:bTdK1nhqF76qiPoCCdyFIV+N/sRHYXYCTQc+3VCi3MI= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.44.0/go.mod h1:+wnlSn0mD1ADVMe3v9Z/WIaiz6q6gL2J/ejaAmdmv80=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.40.0 h1:DvJDOPmSWQHWywQS6lKL+pb8s3gBLOZUtw4N+mavW1I= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.44.0 h1:qazEJlUOQzhCpzQpFETGby7EdqjI1wsd0W+6Gg1SCTU=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.40.0/go.mod h1:EtekO9DEJb4/jRyN4v4Qjc2yA7AtfCBuz2FynRUWTXs= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.44.0/go.mod h1:fOD2Yefuxixkx3ahVNf0O/PERb6r4OlbxfATVnYvzCo=
go.opentelemetry.io/otel/metric v1.43.0 h1:d7638QeInOnuwOONPp4JAOGfbCEpYb+K6DVWvdxGzgM= go.opentelemetry.io/otel/metric v1.44.0 h1:1w0gILTcHdr3YI+ixLyjemwrVnsMURbTZFrSYCdDdmc=
go.opentelemetry.io/otel/metric v1.43.0/go.mod h1:RDnPtIxvqlgO8GRW18W6Z/4P462ldprJtfxHxyKd2PY= go.opentelemetry.io/otel/metric v1.44.0/go.mod h1:8O7hanEPBNgEMmybD3s2VBKcgWOCsA6tzHBPODAiquo=
go.opentelemetry.io/otel/sdk v1.43.0 h1:pi5mE86i5rTeLXqoF/hhiBtUNcrAGHLKQdhg4h4V9Dg= go.opentelemetry.io/otel/sdk v1.44.0 h1:nHYwb9lK+fJPU/dnT6s7W7Z8itMWyqrnVfbheVYrZ58=
go.opentelemetry.io/otel/sdk v1.43.0/go.mod h1:P+IkVU3iWukmiit/Yf9AWvpyRDlUeBaRg6Y+C58QHzg= go.opentelemetry.io/otel/sdk v1.44.0/go.mod h1:Osuydd3Se74nqjAKxid74N5eC+jfEqfTegHRnq58oK0=
go.opentelemetry.io/otel/sdk/metric v1.43.0 h1:S88dyqXjJkuBNLeMcVPRFXpRw2fuwdvfCGLEo89fDkw= go.opentelemetry.io/otel/sdk/metric v1.44.0 h1:3LlKgI+VjbVsjNRFZJZAJ30WjXC5VkNRks6si09iEfI=
go.opentelemetry.io/otel/sdk/metric v1.43.0/go.mod h1:C/RJtwSEJ5hzTiUz5pXF1kILHStzb9zFlIEe85bhj6A= go.opentelemetry.io/otel/sdk/metric v1.44.0/go.mod h1:5B5pMARnXxKhltooO4xUuCBorl65a4EpnTalObqOigA=
go.opentelemetry.io/otel/trace v1.43.0 h1:BkNrHpup+4k4w+ZZ86CZoHHEkohws8AY+WTX09nk+3A= go.opentelemetry.io/otel/trace v1.44.0 h1:jxF5CsGYCe74MCRx2X4g7WsY/VBKRqqpNvXlX/6gtIk=
go.opentelemetry.io/otel/trace v1.43.0/go.mod h1:/QJhyVBUUswCphDVxq+8mld+AvhXZLhe+8WVFxiFff0= go.opentelemetry.io/otel/trace v1.44.0/go.mod h1:oLl1jrMQAVo6v3GAggN+1VH9VIz9iUSvW53sW1Q8PIE=
go.opentelemetry.io/proto/otlp v1.9.0 h1:l706jCMITVouPOqEnii2fIAuO3IVGBRPV5ICjceRb/A= go.opentelemetry.io/proto/otlp v1.10.0 h1:IQRWgT5srOCYfiWnpqUYz9CVmbO8bFmKcwYxpuCSL2g=
go.opentelemetry.io/proto/otlp v1.9.0/go.mod h1:xE+Cx5E/eEHw+ISFkwPLwCZefwVjY+pqKg1qcK03+/4= go.opentelemetry.io/proto/otlp v1.10.0/go.mod h1:/CV4QoCR/S9yaPj8utp3lvQPoqMtxXdzn7ozvvozVqk=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
@ -265,36 +258,36 @@ go.yaml.in/yaml/v2 v2.4.4 h1:tuyd0P+2Ont/d6e2rl3be67goVK4R6deVxCUX5vyPaQ=
go.yaml.in/yaml/v2 v2.4.4/go.mod h1:gMZqIpDtDqOfM0uNfy0SkpRhvUryYH0Z6wdMYcacYXQ= go.yaml.in/yaml/v2 v2.4.4/go.mod h1:gMZqIpDtDqOfM0uNfy0SkpRhvUryYH0Z6wdMYcacYXQ=
go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
golang.org/x/exp v0.0.0-20251219203646-944ab1f22d93 h1:fQsdNF2N+/YewlRZiricy4P1iimyPKZ/xwniHj8Q2a0= golang.org/x/exp v0.0.0-20260410095643-746e56fc9e2f h1:W3F4c+6OLc6H2lb//N1q4WpJkhzJCK5J6kUi1NTVXfM=
golang.org/x/exp v0.0.0-20251219203646-944ab1f22d93/go.mod h1:EPRbTFwzwjXj9NpYyyrvenVh9Y+GFeEvMNh7Xuz7xgU= golang.org/x/exp v0.0.0-20260410095643-746e56fc9e2f/go.mod h1:J1xhfL/vlindoeF/aINzNzt2Bket5bjo9sdOYzOsU80=
golang.org/x/mod v0.35.0 h1:Ww1D637e6Pg+Zb2KrWfHQUnH2dQRLBQyAtpr/haaJeM= golang.org/x/mod v0.38.0 h1:MECBjubtXD7yj4HrhIUcywNaGeNVUdfVnxmPajOk4yk=
golang.org/x/mod v0.35.0/go.mod h1:+GwiRhIInF8wPm+4AoT6L0FA1QWAad3OMdTRx4tFYlU= golang.org/x/mod v0.38.0/go.mod h1:V6Xz0pq8TQ3dGqVQ1FVHuelZpAL0uNhSkk9ogYP3c40=
golang.org/x/net v0.53.0 h1:d+qAbo5L0orcWAr0a9JweQpjXF19LMXJE8Ey7hwOdUA= golang.org/x/net v0.58.0 h1:ynWG7rqYi4ccpTEuPZ2QGWHktVEM9DMCj9yzDE0Q7To=
golang.org/x/net v0.53.0/go.mod h1:JvMuJH7rrdiCfbeHoo3fCQU24Lf5JJwT9W3sJFulfgs= golang.org/x/net v0.58.0/go.mod h1:YwCddHnFlT7eLQqVprV19OnhLGtc5xOKgE0RyqgfWAU=
golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs= golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs=
golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q= golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q=
golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4= golang.org/x/sync v0.22.0 h1:SZjpbeLmrCk4xhRSZFNZW5gFUeCeFgjekvI/+gfScek=
golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= golang.org/x/sync v0.22.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
golang.org/x/sys v0.43.0 h1:Rlag2XtaFTxp19wS8MXlJwTvoh8ArU6ezoyFsMyCTNI= golang.org/x/sys v0.47.0 h1:o7XGOvZQCADBQQ4Y7VNq2dRWQR7JmOUW8Kxx4ZsNgWs=
golang.org/x/sys v0.43.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= golang.org/x/sys v0.47.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
golang.org/x/term v0.42.0 h1:UiKe+zDFmJobeJ5ggPwOshJIVt6/Ft0rcfrXZDLWAWY= golang.org/x/term v0.45.0 h1:NwWyBmoJCbfTHpxrWoZ9C6/VxOf7ic219I8xZZFdrf0=
golang.org/x/term v0.42.0/go.mod h1:Dq/D+snpsbazcBG5+F9Q1n2rXV8Ma+71xEjTRufARgY= golang.org/x/term v0.45.0/go.mod h1:9aqxs0blBcrm/n0L9QW0aRVD+ktan8ssZromtqJC43w=
golang.org/x/text v0.36.0 h1:JfKh3XmcRPqZPKevfXVpI1wXPTqbkE5f7JA92a55Yxg= golang.org/x/text v0.41.0 h1:vz/seA0lnX87Othu2f/0L24RcgrXD9/YFTSuGjj3rH8=
golang.org/x/text v0.36.0/go.mod h1:NIdBknypM8iqVmPiuco0Dh6P5Jcdk8lJL0CUebqK164= golang.org/x/text v0.41.0/go.mod h1:jvf1O8ajNzZqhSrQBPbutR/EB83Cc0CFrezNQIwbb5M=
golang.org/x/time v0.15.0 h1:bbrp8t3bGUeFOx08pvsMYRTCVSMk89u4tKbNOZbp88U= golang.org/x/time v0.15.0 h1:bbrp8t3bGUeFOx08pvsMYRTCVSMk89u4tKbNOZbp88U=
golang.org/x/time v0.15.0/go.mod h1:Y4YMaQmXwGQZoFaVFk4YpCt4FLQMYKZe9oeV/f4MSno= golang.org/x/time v0.15.0/go.mod h1:Y4YMaQmXwGQZoFaVFk4YpCt4FLQMYKZe9oeV/f4MSno=
golang.org/x/tools v0.44.0 h1:UP4ajHPIcuMjT1GqzDWRlalUEoY+uzoZKnhOjbIPD2c= golang.org/x/tools v0.48.0 h1:3+hClM1aLL5mjMKm5ovokw9epgRXPuu2tILgismM6RE=
golang.org/x/tools v0.44.0/go.mod h1:KA0AfVErSdxRZIsOVipbv3rQhVXTnlU6UhKxHd1seDI= golang.org/x/tools v0.48.0/go.mod h1:08xX0orndb/F7jJxGDicx061tyd5pcMto75YMAXr6lk=
gomodules.xyz/jsonpatch/v2 v2.5.0 h1:JELs8RLM12qJGXU4u/TO3V25KW8GreMKl9pdkk14RM0= gomodules.xyz/jsonpatch/v2 v2.5.0 h1:JELs8RLM12qJGXU4u/TO3V25KW8GreMKl9pdkk14RM0=
gomodules.xyz/jsonpatch/v2 v2.5.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY= gomodules.xyz/jsonpatch/v2 v2.5.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY=
gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4= gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4=
gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E= gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E=
google.golang.org/genproto/googleapis/api v0.0.0-20260226221140-a57be14db171 h1:tu/dtnW1o3wfaxCOjSLn5IRX4YDcJrtlpzYkhHhGaC4= google.golang.org/genproto/googleapis/api v0.0.0-20260526163538-3dc84a4a5aaa h1:Kjn0N0tCrDgiAFW+lGO4JZ3ck44CehvJQMAwj9QF0G8=
google.golang.org/genproto/googleapis/api v0.0.0-20260226221140-a57be14db171/go.mod h1:M5krXqk4GhBKvB596udGL3UyjL4I1+cTbK0orROM9ng= google.golang.org/genproto/googleapis/api v0.0.0-20260526163538-3dc84a4a5aaa/go.mod h1:q4lMZS6kskjT5HvCPrnnypcDPVJqT/f4nfxmkE7gryY=
google.golang.org/genproto/googleapis/rpc v0.0.0-20260319201613-d00831a3d3e7 h1:ndE4FoJqsIceKP2oYSnUZqhTdYufCYYkqwtFzfrhI7w= google.golang.org/genproto/googleapis/rpc v0.0.0-20260610212136-7ab31c22f7ad h1:45WmJvIV6C2+O/jjLkPUH+F3aOj/1miDoU2DD0+NWbg=
google.golang.org/genproto/googleapis/rpc v0.0.0-20260319201613-d00831a3d3e7/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= google.golang.org/genproto/googleapis/rpc v0.0.0-20260610212136-7ab31c22f7ad/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8=
google.golang.org/grpc v1.81.1 h1:VnnIIZ88UzOOKLukQi+ImGz8O1Wdp8nAGGnvOfEIWQQ= google.golang.org/grpc v1.83.2 h1:EManeRomTObA0BU7I8vXgg/78uE5MJ9M8B39EX2WscU=
google.golang.org/grpc v1.81.1/go.mod h1:xGH9GfzOyMTGIOXBJmXt+BX/V0kcdQbdcuwQ/zNw42I= google.golang.org/grpc v1.83.2/go.mod h1:YPI1hK3kDked6iHvgX3tR0y+nX/qpMFKhPgFsokw1S8=
google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af h1:+5/Sw3GsDNlEmu7TfklWKPdQ0Ykja5VEmq2i817+jbI= google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af h1:+5/Sw3GsDNlEmu7TfklWKPdQ0Ykja5VEmq2i817+jbI=
google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
@ -308,32 +301,32 @@ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
k8s.io/api v0.36.1 h1:XbL/EMj8K2aJpJtePmqUyQMsM0D4QI2pvl7YKJ20FTY= k8s.io/api v0.37.0 h1:Z//Vj9N7RA/yS2sDmxyeo7h+RR4zbUrd2vrd3Z0TbB4=
k8s.io/api v0.36.1/go.mod h1:KOWo4ey3TINlXjeHVuwB3i+tXXnu+UcwFBHlI/9dvEo= k8s.io/api v0.37.0/go.mod h1:LKXgcJWMc+f4OLbP5SFR8rulEg07zZhpi/zMULiBImk=
k8s.io/apiextensions-apiserver v0.36.1 h1:6JfYmPUsuUIHuN+3QxutXYWj492RqF5fBSx67GYK5Ks= k8s.io/apiextensions-apiserver v0.37.0 h1:zRMQ3+/LIE5oZ0tVvXwYHC+dIkSP5cjNWju7AZU1LOI=
k8s.io/apiextensions-apiserver v0.36.1/go.mod h1:pLzZin90riwisdzKwv/GoTwENooytoIx5zWJb4Hkby8= k8s.io/apiextensions-apiserver v0.37.0/go.mod h1:HU0PfSBwchHL5iDau6jjt9zU6ryWkDDlaVUiq91NK80=
k8s.io/apimachinery v0.36.1 h1:G63Gjx2W+q0YD+72Vo8oY0nDnePVwnuzTmmy5ENrVSA= k8s.io/apimachinery v0.37.0 h1:Np2AbDtf8x6RDHiD8T9LbKJ9gaegeVNa8yNm5FuGKm0=
k8s.io/apimachinery v0.36.1/go.mod h1:ibYOR00vW/I1kzvi5SF0dRuJ52BvKtfvRdOn35GPQ+8= k8s.io/apimachinery v0.37.0/go.mod h1:RN3nhprFSCxOi5Selxd7oMTXOe/c+ZbcE7Im+TS2zkE=
k8s.io/apiserver v0.36.1 h1:iMS5V+rPUertv5P9RaqJgmHHTuh4quWpoxchvMUY+JY= k8s.io/apiserver v0.37.0 h1:TXg7OxsOWrAH8J4Zi/gBAZuMw1Dfdd+6cca2h4qjRqo=
k8s.io/apiserver v0.36.1/go.mod h1:Cby1PbLWztu0GDOxoO6iFOyyqIsziHNEW+w9zVQ22Kw= k8s.io/apiserver v0.37.0/go.mod h1:OddHDF4gy9qyIb8o/3+qaeP6S0vEObWLgOygVqXksv0=
k8s.io/client-go v0.36.1 h1:FN/K8QIT2CEDt+2WB2HnWrUANZ50AP5GII43/SP2JR0= k8s.io/client-go v0.37.0 h1:nsN31fy8wBySuZ+QRnKmrjRSQLOG2rvoGN0tKd12zhQ=
k8s.io/client-go v0.36.1/go.mod h1:s6rAnCtTGYDQnpNjEhSaISV+2O8jwruZ6m3QOYBFbtU= k8s.io/client-go v0.37.0/go.mod h1:FcGqw+Ll/gNQiq+nPGY1Oyt9y7SgDh1d3MW3RFDEbn0=
k8s.io/component-base v0.36.1 h1:iG6GsELftXqTNG9HG6kiVjatSgAw1sf5pJ6R5a6N0kA= k8s.io/component-base v0.37.0 h1:3SdSa4+itMdFTDFTeR8CxKGmSTSMXFlKL4ky8OqjguM=
k8s.io/component-base v0.36.1/go.mod h1:nf9XPlntRdqO6WMeEWAA5F93Y4ICZQdeT9GeqLDB3JI= k8s.io/component-base v0.37.0/go.mod h1:LjOebp4R9y6LODWZQv102ZQxGheLcDO2ZJLAw6bbh4I=
k8s.io/klog/v2 v2.140.0 h1:Tf+J3AH7xnUzZyVVXhTgGhEKnFqye14aadWv7bzXdzc= k8s.io/klog/v2 v2.140.0 h1:Tf+J3AH7xnUzZyVVXhTgGhEKnFqye14aadWv7bzXdzc=
k8s.io/klog/v2 v2.140.0/go.mod h1:o+/RWfJ6PwpnFn7OyAG3QnO47BFsymfEfrz6XyYSSp0= k8s.io/klog/v2 v2.140.0/go.mod h1:o+/RWfJ6PwpnFn7OyAG3QnO47BFsymfEfrz6XyYSSp0=
k8s.io/kube-openapi v0.0.0-20260502001324-b7f5293f4787 h1:kHv8PETbPIVHfqKBYwTNNSjqChf/7xn3JOS3re+NWs8= k8s.io/kube-openapi v0.0.0-20260721132016-d427ff9ee9ad h1:oXImqH8mQNk7PmvzKhmN3ddJoY6OnyM225MXwGHPm0A=
k8s.io/kube-openapi v0.0.0-20260502001324-b7f5293f4787/go.mod h1:Cyq7UE0QtGe+Zo+/6XFrxiS4Mq0tLyQEONkFzSkfp9o= k8s.io/kube-openapi v0.0.0-20260721132016-d427ff9ee9ad/go.mod h1:0/mqHCVhlumdJ3BhCfnjSZQE037nAhNodh1/hK0T8/I=
k8s.io/streaming v0.36.1 h1:L+K68n4Gg940BGNNYtUBvL1WTLL0YnKT3s+P1MNAmR4= k8s.io/streaming v0.37.0 h1:iPBUZLZiKt5bV+lxJurASMOV07VuBhNpiwJt2//AWrM=
k8s.io/streaming v0.36.1/go.mod h1:z6fV3D+NVkoeqRMtWwlUZK6U17SY/LqNzOxWL6GyR/s= k8s.io/streaming v0.37.0/go.mod h1:APlJR26ZWRcVy5bIEj0QRrKUXROtBHPcxl2NT7EAzPU=
k8s.io/utils v0.0.0-20260507154919-ff6756f316d2 h1:wU4tMEhLGgIbLvXQb1cfN+EcM0wf7zC6CPF+C79jroc= k8s.io/utils v0.0.0-20260707023825-cf1189d6abe3 h1:jVkFFVfXdXP74B/zbO3hM3hpSFD0xvhQ5U686DPurkE=
k8s.io/utils v0.0.0-20260507154919-ff6756f316d2/go.mod h1:xDxuJ0whA3d0I4mf/C4ppKHxXynQ+fxnkmQH0vTHnuk= k8s.io/utils v0.0.0-20260707023825-cf1189d6abe3/go.mod h1:M2s5JB1lIYP3jzZdorPLHXIPJzt9vv2muW5a6L9DtNM=
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.34.0 h1:hSfpvjjTQXQY2Fol2CS0QHMNs/WI1MOSGzCm1KhM5ec= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.36.0 h1:/YpDJ4vReG7ZmzSpBGxduXgywWkJU9zHubgJG03MT+Y=
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.34.0/go.mod h1:Ve9uj1L+deCXFrPOk1LpFXqTg7LCFzFso6PA48q/XZw= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.36.0/go.mod h1:tJo1aepTXyR+8Xs3sUsGBDk4Ub2AM5dPAPKJx0mpm5c=
sigs.k8s.io/controller-runtime v0.24.1 h1:miPEwrmirImAvgME1L9qebGHrOnGJoVmVdtOU9fRfo4= sigs.k8s.io/controller-runtime v0.24.1 h1:miPEwrmirImAvgME1L9qebGHrOnGJoVmVdtOU9fRfo4=
sigs.k8s.io/controller-runtime v0.24.1/go.mod h1:vFkfY5fGt5xAC/sKb8IBFKgWPNKG9OUG29dR8Y2wImw= sigs.k8s.io/controller-runtime v0.24.1/go.mod h1:vFkfY5fGt5xAC/sKb8IBFKgWPNKG9OUG29dR8Y2wImw=
sigs.k8s.io/gateway-api v1.5.0 h1:duoo14Ky/fJXpjpmyMISE2RTBGnfCg8zICfTYLTnBJA= sigs.k8s.io/gateway-api v1.6.0 h1:735YBRj5NXFrOGX0GoSjwzUIzbz8kiEOfADsqHFmHgE=
sigs.k8s.io/gateway-api v1.5.0/go.mod h1:GvCETiaMAlLym5CovLxGjS0NysqFk3+Yuq3/rh6QL2o= sigs.k8s.io/gateway-api v1.6.0/go.mod h1:FVfx3t389ybeXOqvDghLbdvJdSCfI/PReqCUI3lu3mY=
sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg= sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg=
sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg=
sigs.k8s.io/kustomize/api v0.21.1 h1:lzqbzvz2CSvsjIUZUBNFKtIMsEw7hVLJp0JeSIVmuJs= sigs.k8s.io/kustomize/api v0.21.1 h1:lzqbzvz2CSvsjIUZUBNFKtIMsEw7hVLJp0JeSIVmuJs=
@ -342,7 +335,7 @@ sigs.k8s.io/kustomize/kyaml v0.21.1 h1:IVlbmhC076nf6foyL6Taw4BkrLuEsXUXNpsE+ScX7
sigs.k8s.io/kustomize/kyaml v0.21.1/go.mod h1:hmxADesM3yUN2vbA5z1/YTBnzLJ1dajdqpQonwBL1FQ= sigs.k8s.io/kustomize/kyaml v0.21.1/go.mod h1:hmxADesM3yUN2vbA5z1/YTBnzLJ1dajdqpQonwBL1FQ=
sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU= sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU=
sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY=
sigs.k8s.io/structured-merge-diff/v6 v6.4.0 h1:qmp2e3ZfFi1/jJbDGpD4mt3wyp6PE1NfKHCYLqgNQJo= sigs.k8s.io/structured-merge-diff/v6 v6.4.2 h1:qdOxHwrl2Kaag1aQEarlYcOA9vSyGCp3CIki3aW8c4Q=
sigs.k8s.io/structured-merge-diff/v6 v6.4.0/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE= sigs.k8s.io/structured-merge-diff/v6 v6.4.2/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE=
sigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs= sigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs=
sigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4= sigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4=

View File

@ -0,0 +1,36 @@
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
name: cluster-replica
spec:
instances: 3
bootstrap:
pg_basebackup:
source: source
replica:
enabled: true
source: source
externalClusters:
- name: source
connectionParameters:
host: cluster-example-rw.default.svc
user: streaming_replica
sslmode: verify-full
dbname: postgres
sslKey:
name: cluster-example-replication
key: tls.key
sslCert:
name: cluster-example-replication
key: tls.crt
sslRootCert:
name: cluster-example-ca
key: ca.crt
plugin:
name: barman-cloud.cloudnative-pg.io
parameters:
barmanObjectName: minio-store
serverName: cluster-example
storage:
size: 1Gi

View File

@ -52,6 +52,11 @@ const (
// BarmanEndpointCACertificateFileName is the name of the file in which the barman endpoint // BarmanEndpointCACertificateFileName is the name of the file in which the barman endpoint
// CA certificate is stored. // CA certificate is stored.
BarmanEndpointCACertificateFileName = "barman-ca.crt" BarmanEndpointCACertificateFileName = "barman-ca.crt"
// PgWalVolumePgWalPath is the path of the pg_wal directory inside the WAL volume,
// used when a separate WAL storage is configured. During a restore the pg_wal
// directory is moved here and symlinked back into PGDATA.
PgWalVolumePgWalPath = "/var/lib/postgresql/wal/pg_wal"
) )
// GetRestoreCABundleEnv gets the enveronment variables to be used when custom // GetRestoreCABundleEnv gets the enveronment variables to be used when custom

View File

@ -20,10 +20,38 @@ SPDX-License-Identifier: Apache-2.0
package common package common
import ( import (
"errors"
barmanRestorer "github.com/cloudnative-pg/barman-cloud/pkg/restorer"
"google.golang.org/grpc/codes" "google.golang.org/grpc/codes"
"google.golang.org/grpc/status" "google.golang.org/grpc/status"
) )
// classifyWALRestoreError maps an error returned by the WAL
// restorer to a gRPC-coded error so the caller can tell terminal
// failures apart from transient ones via the status code.
func classifyWALRestoreError(walName string, walErr error) error {
switch {
case errors.Is(walErr, barmanRestorer.ErrWALNotFound):
return newWALNotFoundError(walName)
case errors.Is(walErr, barmanRestorer.ErrInvalidWALName):
// A malformed WAL name will never become valid on retry.
return newInvalidWALNameError(walName, walErr)
case errors.Is(walErr, barmanRestorer.ErrConnectivity),
errors.Is(walErr, barmanRestorer.ErrGeneric):
// barman-cloud exit codes 2 (connectivity) and 4
// (generic) both surface conditions that are retryable
// in practice — barman uses the "generic" bucket for
// some connection-class failures too, not just exit 2.
return newUnavailableError(walName, walErr)
default:
// Unrecognized exit codes and unexpected failures (e.g.
// the barman-cloud command could not be executed). No
// positive signal that retry would help.
return newInternalWALRestoreError(walName, walErr)
}
}
// ErrEndOfWALStreamReached is returned when end of WAL is detected in the cloud archive. // ErrEndOfWALStreamReached is returned when end of WAL is detected in the cloud archive.
var ErrEndOfWALStreamReached = status.Errorf(codes.OutOfRange, "end of WAL reached") var ErrEndOfWALStreamReached = status.Errorf(codes.OutOfRange, "end of WAL reached")
@ -35,10 +63,48 @@ var ErrEndOfWALStreamReached = status.Errorf(codes.OutOfRange, "end of WAL reach
var ErrMissingPermissions = status.Errorf(codes.FailedPrecondition, var ErrMissingPermissions = status.Errorf(codes.FailedPrecondition,
"no permission to download the backup credentials, retrying") "no permission to download the backup credentials, retrying")
// newWALNotFoundError returns a error that states that a // newWALNotFoundError reports that the requested WAL file is not
// certain WAL file has not been found. This error is // present in the object store. Emits codes.NotFound: this is a
// compatible with GRPC status codes, resulting in a 404 // terminal condition (the file won't appear on retry).
// being used as a response code.
func newWALNotFoundError(walName string) error { func newWALNotFoundError(walName string) error {
return status.Errorf(codes.NotFound, "wal %q not found", walName) return status.Errorf(codes.NotFound, "wal %q not found", walName)
} }
// newUnavailableError reports that downloading the WAL file failed
// for a reason expected to be transient (a barman-cloud connectivity
// blip, or a generic exit code that in practice covers retryable
// conditions too). Emits codes.Unavailable: per gRPC conventions,
// the canonical signal for "retry may succeed".
func newUnavailableError(walName string, err error) error {
return status.Errorf(
codes.Unavailable,
"transient error while downloading %q: %s",
walName,
err.Error(),
)
}
// newInvalidWALNameError reports that the requested WAL name is
// not a valid name. Emits codes.InvalidArgument: this is a
// terminal condition (the same name won't become valid on retry).
func newInvalidWALNameError(walName string, err error) error {
return status.Errorf(
codes.InvalidArgument,
"invalid WAL name %q: %s",
walName,
err.Error(),
)
}
// newInternalWALRestoreError reports that downloading the WAL
// file failed for an unclassified reason. Emits codes.Internal:
// we have no positive signal that retry would help, so by gRPC
// convention this is treated as terminal.
func newInternalWALRestoreError(walName string, err error) error {
return status.Errorf(
codes.Internal,
"internal error while downloading %q: %s",
walName,
err.Error(),
)
}

View File

@ -0,0 +1,86 @@
/*
Copyright © contributors to CloudNativePG, established as
CloudNativePG a Series of LF Projects, LLC.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
SPDX-License-Identifier: Apache-2.0
*/
package common
import (
"errors"
"fmt"
barmanRestorer "github.com/cloudnative-pg/barman-cloud/pkg/restorer"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
)
var _ = Describe("classifyWALRestoreError", func() {
const walName = "000000010000000000000001"
DescribeTable(
"maps barman restorer sentinels to gRPC status codes",
func(walErr error, expectedCode codes.Code) {
got := classifyWALRestoreError(walName, walErr)
Expect(got).To(HaveOccurred())
st, ok := status.FromError(got)
Expect(ok).To(BeTrue(), "returned error must carry a gRPC status")
Expect(st.Code()).To(Equal(expectedCode))
Expect(st.Message()).To(ContainSubstring(walName))
},
Entry("ErrWALNotFound -> NotFound",
fmt.Errorf("object storage or file not found: %w", barmanRestorer.ErrWALNotFound),
codes.NotFound),
Entry("ErrInvalidWALName -> InvalidArgument",
fmt.Errorf("invalid name for a WAL file: %w", barmanRestorer.ErrInvalidWALName),
codes.InvalidArgument),
Entry("ErrConnectivity -> Unavailable",
fmt.Errorf("connectivity failure, retrying: %w", barmanRestorer.ErrConnectivity),
codes.Unavailable),
Entry("ErrGeneric -> Unavailable (barman uses exit 4 for some retryable cases too)",
fmt.Errorf("generic error: %w", barmanRestorer.ErrGeneric),
codes.Unavailable),
Entry("unknown error -> Internal",
errors.New("something we did not classify"),
codes.Internal),
)
It("matches the sentinel even through several wrapping layers", func() {
// The plugin wraps barman errors via fmt.Errorf("...: %w", ...);
// classification must keep working if more wraps appear above.
inner := fmt.Errorf("connectivity failure, retrying: %w", barmanRestorer.ErrConnectivity)
wrapped := fmt.Errorf("while restoring WAL %s: %w", walName, inner)
got := classifyWALRestoreError(walName, wrapped)
st, ok := status.FromError(got)
Expect(ok).To(BeTrue())
Expect(st.Code()).To(Equal(codes.Unavailable))
})
It("treats ErrWALNotFound as terminal even when the error chain mentions other sentinels in its message", func() {
// Defensive: if the underlying error stringifies to something
// resembling another sentinel's message, the switch must still
// match by identity (errors.Is), not by substring.
walErr := fmt.Errorf("not found, looks like a connectivity failure: %w", barmanRestorer.ErrWALNotFound)
got := classifyWALRestoreError(walName, walErr)
st, _ := status.FromError(got)
Expect(st.Code()).To(Equal(codes.NotFound))
})
})

View File

@ -25,6 +25,7 @@ import (
cnpgv1 "github.com/cloudnative-pg/cloudnative-pg/api/v1" cnpgv1 "github.com/cloudnative-pg/cloudnative-pg/api/v1"
"github.com/cloudnative-pg/machinery/pkg/log" "github.com/cloudnative-pg/machinery/pkg/log"
"github.com/spf13/viper" "github.com/spf13/viper"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/runtime/schema"
utilruntime "k8s.io/apimachinery/pkg/util/runtime" utilruntime "k8s.io/apimachinery/pkg/util/runtime"
@ -58,6 +59,7 @@ func GenerateScheme(ctx context.Context) *runtime.Scheme {
&cnpgv1.Backup{}, &cnpgv1.BackupList{}, &cnpgv1.Backup{}, &cnpgv1.BackupList{},
&cnpgv1.ScheduledBackup{}, &cnpgv1.ScheduledBackupList{}, &cnpgv1.ScheduledBackup{}, &cnpgv1.ScheduledBackupList{},
) )
metav1.AddToGroupVersion(result, schemeGroupVersion)
schemeLog := log.FromContext(ctx) schemeLog := log.FromContext(ctx)
schemeLog.Info("CNPG types registration", "schemeGroupVersion", schemeGroupVersion) schemeLog.Info("CNPG types registration", "schemeGroupVersion", schemeGroupVersion)

View File

@ -0,0 +1,32 @@
/*
Copyright © contributors to CloudNativePG, established as
CloudNativePG a Series of LF Projects, LLC.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
SPDX-License-Identifier: Apache-2.0
*/
package common
import (
"testing"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)
func TestCommon(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "Common Suite")
}

View File

@ -27,6 +27,7 @@ import (
"path" "path"
"time" "time"
barmanapi "github.com/cloudnative-pg/barman-cloud/pkg/api"
"github.com/cloudnative-pg/barman-cloud/pkg/archiver" "github.com/cloudnative-pg/barman-cloud/pkg/archiver"
barmanCommand "github.com/cloudnative-pg/barman-cloud/pkg/command" barmanCommand "github.com/cloudnative-pg/barman-cloud/pkg/command"
barmanCredentials "github.com/cloudnative-pg/barman-cloud/pkg/credentials" barmanCredentials "github.com/cloudnative-pg/barman-cloud/pkg/credentials"
@ -155,13 +156,17 @@ func (w WALServiceImplementation) Archive(
return nil, err return nil, err
} }
// Step 2: Check if the archive location is safe to perform archiving // Step 2: Check if the archive location is safe to perform archiving.
checkFileExisting, err := fileutils.FileExists(emptyWalArchiveFile) checkEmptyWalArchive, err := resolveArchiveEmptyWalArchiveCheck(
request.CheckEmptyWalArchive,
configuration.Cluster,
emptyWalArchiveFile,
)
if err != nil { if err != nil {
return nil, fmt.Errorf("while checking for empty wal archive check file %q: %w", emptyWalArchiveFile, err) return nil, err
} }
if utils.IsEmptyWalArchiveCheckEnabled(&configuration.Cluster.ObjectMeta) && checkFileExisting { if checkEmptyWalArchive {
if err := CheckBackupDestination( if err := CheckBackupDestination(
ctx, ctx,
&objectStore.Spec.Configuration, &objectStore.Spec.Configuration,
@ -223,8 +228,32 @@ func (w WALServiceImplementation) Archive(
return &wal.WALArchiveResult{}, nil return &wal.WALArchiveResult{}, nil
} }
// resolveArchiveEmptyWalArchiveCheck reports whether the WAL archive
// destination must be verified before archiving this segment.
//
// The operator owns the marker file's lifecycle, so when it sets the decision
// (non-nil) that value already accounts for the marker and is obeyed as-is. A
// nil value comes from an operator that predates this field, so we fall back to
// the previous logic: the Cluster annotation combined with the on-disk marker
// file.
func resolveArchiveEmptyWalArchiveCheck(
operatorDecision *bool,
cluster *cnpgv1.Cluster,
markerFilePath string,
) (bool, error) {
if operatorDecision != nil {
return *operatorDecision, nil
}
markerFilePresent, err := fileutils.FileExists(markerFilePath)
if err != nil {
return false, fmt.Errorf("while checking for empty wal archive check file %q: %w", markerFilePath, err)
}
return utils.IsEmptyWalArchiveCheckEnabled(&cluster.ObjectMeta) && markerFilePresent, nil
}
// Restore implements the WALService interface // Restore implements the WALService interface
// nolint: gocognit
func (w WALServiceImplementation) Restore( func (w WALServiceImplementation) Restore(
ctx context.Context, ctx context.Context,
request *wal.WALRestoreRequest, request *wal.WALRestoreRequest,
@ -239,36 +268,7 @@ func (w WALServiceImplementation) Restore(
return nil, err return nil, err
} }
var serverName string serverName, objectStoreKey := resolveRestoreObjectStore(configuration, w.InstanceName)
var objectStoreKey types.NamespacedName
var promotionToken string
if configuration.Cluster.Spec.ReplicaCluster != nil {
promotionToken = configuration.Cluster.Spec.ReplicaCluster.PromotionToken
}
switch {
case promotionToken != "" && configuration.Cluster.Status.LastPromotionToken != promotionToken:
// This is a replica cluster that is being promoted to a primary cluster
// Recover from the replica source object store
serverName = configuration.ReplicaSourceServerName
objectStoreKey = configuration.GetReplicaSourceBarmanObjectKey()
case configuration.Cluster.IsReplica() && configuration.Cluster.Status.CurrentPrimary == w.InstanceName:
// Designated primary on replica cluster, using replica source object store
serverName = configuration.ReplicaSourceServerName
objectStoreKey = configuration.GetReplicaSourceBarmanObjectKey()
case configuration.Cluster.Status.CurrentPrimary == "":
// Recovery from object store, using recovery object store
serverName = configuration.RecoveryServerName
objectStoreKey = configuration.GetRecoveryBarmanObjectKey()
default:
// Using cluster object store
serverName = configuration.ServerName
objectStoreKey = configuration.GetBarmanObjectKey()
}
var objectStore barmancloudv1.ObjectStore var objectStore barmancloudv1.ObjectStore
if err := w.Client.Get(ctx, objectStoreKey, &objectStore); err != nil { if err := w.Client.Get(ctx, objectStoreKey, &objectStore); err != nil {
@ -279,9 +279,38 @@ func (w WALServiceImplementation) Restore(
"Restoring WAL file", "Restoring WAL file",
"objectStore", objectStore.Name, "objectStore", objectStore.Name,
"serverName", serverName, "serverName", serverName,
"walName", walName) "walName", walName,
"mode", request.GetMode())
return &wal.WALRestoreResult{}, w.restoreFromBarmanObjectStore( return &wal.WALRestoreResult{}, w.restoreFromBarmanObjectStore(
ctx, configuration.Cluster, &objectStore, serverName, walName, destinationPath) ctx, configuration.Cluster, &objectStore, serverName, walName, destinationPath,
request.GetMode() == wal.WALRestoreRequest_MODE_REWIND)
}
// resolveRestoreObjectStore selects the object store and server name to use when
// restoring a WAL file, based on the role this instance plays in the cluster.
func resolveRestoreObjectStore(
configuration *config.PluginConfiguration,
instanceName string,
) (serverName string, objectStoreKey types.NamespacedName) {
switch {
case configuration.Cluster.Status.CurrentPrimary == instanceName &&
len(configuration.ReplicaSourceBarmanObjectName) > 0:
// PostgreSQL never runs restore_command on a live primary; it runs only while
// the instance is in recovery (a genuine standby, restoring from a backup, or
// being rewound by pg_rewind). So a current primary that still has a replica
// source configured can only be a designated primary that has not finished
// promoting, and it must keep fetching WAL from the replica source.
// Token-agnostic: covers both switchover and failover.
return configuration.ReplicaSourceServerName, configuration.GetReplicaSourceBarmanObjectKey()
case configuration.Cluster.Status.CurrentPrimary == "":
// Recovery from object store, using recovery object store
return configuration.RecoveryServerName, configuration.GetRecoveryBarmanObjectKey()
default:
// Using cluster object store
return configuration.ServerName, configuration.GetBarmanObjectKey()
}
} }
func (w WALServiceImplementation) restoreFromBarmanObjectStore( func (w WALServiceImplementation) restoreFromBarmanObjectStore(
@ -291,6 +320,7 @@ func (w WALServiceImplementation) restoreFromBarmanObjectStore(
serverName string, serverName string,
walName string, walName string,
destinationPath string, destinationPath string,
rewindMode bool,
) error { ) error {
contextLogger := log.FromContext(ctx) contextLogger := log.FromContext(ctx)
startTime := time.Now() startTime := time.Now()
@ -322,6 +352,20 @@ func (w WALServiceImplementation) restoreFromBarmanObjectStore(
return fmt.Errorf("while creating the restorer: %w", err) return fmt.Errorf("while creating the restorer: %w", err)
} }
// A flag left over from a normal-recovery invocation that ran before this pod
// was demoted must not survive into a pg_rewind restore: the flag machinery
// does not apply while restoring on behalf of pg_rewind (see
// shouldUseEndOfWALStreamFlag below), so it is never checked here, but left
// untouched it would resurface and wrongly abort the first normal-recovery
// invocation that runs once the rewind is done. This runs unconditionally,
// before the spool short-circuit in Step 1, so a request for a WAL file that
// happens to already be staged in the spool cannot skip the clear.
if rewindMode {
if err := clearEndOfWALStreamFlag(walRestorer); err != nil {
return err
}
}
// Step 1: check if this WAL file is not already in the spool // Step 1: check if this WAL file is not already in the spool
var wasInSpool bool var wasInSpool bool
if wasInSpool, err = walRestorer.RestoreFromSpool(walName, destinationPath); err != nil { if wasInSpool, err = walRestorer.RestoreFromSpool(walName, destinationPath); err != nil {
@ -334,8 +378,10 @@ func (w WALServiceImplementation) restoreFromBarmanObjectStore(
return nil return nil
} }
// We skip this step if streaming connection is not available // Step 2: return error if the end-of-wal-stream flag is set.
if isStreamingAvailable(cluster, w.InstanceName) { // We skip this step if the flag machinery does not apply to this invocation
useEndOfWALStreamFlag := shouldUseEndOfWALStreamFlag(cluster, w.InstanceName, rewindMode)
if useEndOfWALStreamFlag {
if err := checkEndOfWALStreamFlag(walRestorer); err != nil { if err := checkEndOfWALStreamFlag(walRestorer); err != nil {
return err return err
} }
@ -343,10 +389,7 @@ func (w WALServiceImplementation) restoreFromBarmanObjectStore(
// Step 3: gather the WAL files names to restore. If the required file isn't a regular WAL, we download it directly. // Step 3: gather the WAL files names to restore. If the required file isn't a regular WAL, we download it directly.
var walFilesList []string var walFilesList []string
maxParallel := 1 maxParallel := maxWALFilesPerInvocation(barmanConfiguration, rewindMode)
if barmanConfiguration.Wal != nil && barmanConfiguration.Wal.MaxParallel > 1 {
maxParallel = barmanConfiguration.Wal.MaxParallel
}
if IsWALFile(walName) { if IsWALFile(walName) {
// If this is a regular WAL file, we try to prefetch // If this is a regular WAL file, we try to prefetch
if walFilesList, err = gatherWALFilesToRestore(walName, maxParallel); err != nil { if walFilesList, err = gatherWALFilesToRestore(walName, maxParallel); err != nil {
@ -365,16 +408,12 @@ func (w WALServiceImplementation) restoreFromBarmanObjectStore(
// is the one that PostgreSQL has requested to restore. // is the one that PostgreSQL has requested to restore.
// The failure has already been logged in walRestorer.RestoreList method // The failure has already been logged in walRestorer.RestoreList method
if walStatus[0].Err != nil { if walStatus[0].Err != nil {
if errors.Is(walStatus[0].Err, barmanRestorer.ErrWALNotFound) { return classifyWALRestoreError(walStatus[0].WalName, walStatus[0].Err)
return newWALNotFoundError(walStatus[0].WalName)
} }
return walStatus[0].Err // We skip this step if the flag machinery does not apply to this invocation
}
// We skip this step if streaming connection is not available
endOfWALStream := isEndOfWALStream(walStatus) endOfWALStream := isEndOfWALStream(walStatus)
if isStreamingAvailable(cluster, w.InstanceName) && endOfWALStream { if useEndOfWALStreamFlag && endOfWALStream {
contextLogger.Info( contextLogger.Info(
"Set end-of-wal-stream flag as one of the WAL files to be prefetched was not found") "Set end-of-wal-stream flag as one of the WAL files to be prefetched was not found")
@ -422,6 +461,38 @@ func (w WALServiceImplementation) SetFirstRequired(
panic("implement me") panic("implement me")
} }
// maxWALFilesPerInvocation returns how many WAL files a single restore
// invocation is allowed to fetch, the requested one included. Prefetching is
// disabled when restoring on behalf of pg_rewind, which walks the WAL
// backward: the following segments would never be requested, and past the end
// of the timeline they do not even exist
func maxWALFilesPerInvocation(barmanConfiguration *barmanapi.BarmanObjectStoreConfiguration, rewindMode bool) int {
if rewindMode {
return 1
}
if barmanConfiguration.Wal != nil && barmanConfiguration.Wal.MaxParallel > 1 {
return barmanConfiguration.Wal.MaxParallel
}
return 1
}
// shouldUseEndOfWALStreamFlag returns true when the end-of-wal-stream flag
// machinery applies to the current invocation. The flag makes the following
// invocation fail, so that PostgreSQL stops polling the WAL archive and
// switches to streaming replication. It does not apply when no streaming
// connection is available, nor when restoring on behalf of pg_rewind:
// pg_rewind cannot fall back to streaming replication, and a stale flag would
// make it abort on a segment that is available in the archive
func shouldUseEndOfWALStreamFlag(cluster *cnpgv1.Cluster, podName string, rewindMode bool) bool {
if rewindMode {
return false
}
return isStreamingAvailable(cluster, podName)
}
// isStreamingAvailable checks if this pod can replicate via streaming connection. // isStreamingAvailable checks if this pod can replicate via streaming connection.
func isStreamingAvailable(cluster *cnpgv1.Cluster, podName string) bool { func isStreamingAvailable(cluster *cnpgv1.Cluster, podName string) bool {
if cluster == nil { if cluster == nil {
@ -498,6 +569,22 @@ func checkEndOfWALStreamFlag(walRestorer *barmanRestorer.WALRestorer) error {
return nil return nil
} }
// clearEndOfWALStreamFlag removes the end-of-wal-stream flag, if present, without
// treating it as an error. It is used instead of checkEndOfWALStreamFlag when
// restoring on behalf of pg_rewind, which must not abort on a flag it did not
// set itself.
func clearEndOfWALStreamFlag(walRestorer *barmanRestorer.WALRestorer) error {
contain, err := walRestorer.IsEndOfWALStream()
if err != nil {
return err
}
if contain {
return walRestorer.ResetEndOfWalStream()
}
return nil
}
// isEndOfWALStream returns true if one of the downloads has returned // isEndOfWALStream returns true if one of the downloads has returned
// a file-not-found error. // a file-not-found error.
func isEndOfWALStream(results []barmanRestorer.Result) bool { func isEndOfWALStream(results []barmanRestorer.Result) bool {

View File

@ -0,0 +1,246 @@
/*
Copyright © contributors to CloudNativePG, established as
CloudNativePG a Series of LF Projects, LLC.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
SPDX-License-Identifier: Apache-2.0
*/
package common
import (
"context"
"os"
"path/filepath"
barmanapi "github.com/cloudnative-pg/barman-cloud/pkg/api"
barmanRestorer "github.com/cloudnative-pg/barman-cloud/pkg/restorer"
cnpgv1 "github.com/cloudnative-pg/cloudnative-pg/api/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/utils/ptr"
"github.com/cloudnative-pg/plugin-barman-cloud/internal/cnpgi/metadata"
"github.com/cloudnative-pg/plugin-barman-cloud/internal/cnpgi/operator/config"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)
var _ = Describe("resolveRestoreObjectStore", func() {
const (
namespace = "test-ns"
instance = "cluster-1"
)
// newConfig builds a PluginConfiguration with distinct, recognizable names
// for every candidate object store, so each test can assert exactly which
// one the routing selected.
newConfig := func(currentPrimary, replicaSourceObject string) *config.PluginConfiguration {
return &config.PluginConfiguration{
Cluster: &cnpgv1.Cluster{
ObjectMeta: metav1.ObjectMeta{Namespace: namespace},
Status: cnpgv1.ClusterStatus{CurrentPrimary: currentPrimary},
},
BarmanObjectName: "cluster-store",
ServerName: "cluster-server",
RecoveryBarmanObjectName: "recovery-store",
RecoveryServerName: "recovery-server",
ReplicaSourceBarmanObjectName: replicaSourceObject,
ReplicaSourceServerName: "replica-server",
}
}
DescribeTable(
"selects the correct object store for restoring WAL files",
func(cfg *config.PluginConfiguration, wantServer, wantObject string) {
gotServer, gotKey := resolveRestoreObjectStore(cfg, instance)
Expect(gotServer).To(Equal(wantServer))
Expect(gotKey.Name).To(Equal(wantObject))
Expect(gotKey.Namespace).To(Equal(namespace))
},
// The regression this guards: during a designated-primary promotion the
// instance is already the current primary while still in recovery, and it
// must pull remaining WALs from the replica source. The routing decision does
// not depend on the promotion token, so this single case covers both
// switchover and failover.
Entry("designated primary in promotion -> replica source",
newConfig(instance, "replica-store"),
"replica-server", "replica-store"),
// Guards the len(ReplicaSourceBarmanObjectName) > 0 gate: a current primary
// without a barman-backed replica source (plain HA primary, or a replica
// cluster whose source is streaming-only) must use the cluster store, not
// an empty-named replica source key.
Entry("current primary without a replica source -> cluster store",
newConfig(instance, ""),
"cluster-server", "cluster-store"),
// Bootstrap / PITR: no current primary yet. Recovery wins even if a replica
// source happens to be configured.
Entry("no current primary -> recovery store",
newConfig("", "replica-store"),
"recovery-server", "recovery-store"),
Entry("ordinary standby -> cluster store",
newConfig("cluster-2", ""),
"cluster-server", "cluster-store"),
// A non-primary instance must never route to the replica source, even when
// one is configured: only the designated primary catches up from the source.
Entry("standby in a replica cluster -> cluster store",
newConfig("cluster-2", "replica-store"),
"cluster-server", "cluster-store"),
)
})
var _ = Describe("maxWALFilesPerInvocation", func() {
configWithMaxParallel := func(maxParallel int) *barmanapi.BarmanObjectStoreConfiguration {
return &barmanapi.BarmanObjectStoreConfiguration{
Wal: &barmanapi.WalBackupConfiguration{MaxParallel: maxParallel},
}
}
DescribeTable(
"computes how many WAL files a single invocation may fetch",
func(cfg *barmanapi.BarmanObjectStoreConfiguration, rewindMode bool, want int) {
Expect(maxWALFilesPerInvocation(cfg, rewindMode)).To(Equal(want))
},
Entry("no WAL configuration", &barmanapi.BarmanObjectStoreConfiguration{}, false, 1),
Entry("parallel restore configured", configWithMaxParallel(8), false, 8),
// pg_rewind walks the timeline backwards: prefetching must stay off no
// matter what the object store configuration asks for
Entry("rewind mode overrides the configured parallelism", configWithMaxParallel(8), true, 1),
)
})
var _ = Describe("shouldUseEndOfWALStreamFlag", func() {
clusterWithPrimary := func(currentPrimary string) *cnpgv1.Cluster {
return &cnpgv1.Cluster{
Status: cnpgv1.ClusterStatus{CurrentPrimary: currentPrimary},
}
}
DescribeTable(
"decides whether the end-of-wal-stream flag machinery applies",
func(cluster *cnpgv1.Cluster, podName string, rewindMode bool, want bool) {
Expect(shouldUseEndOfWALStreamFlag(cluster, podName, rewindMode)).To(Equal(want))
},
Entry("replica with streaming available", clusterWithPrimary("cluster-1"), "cluster-2", false, true),
Entry("primary cannot stream from anyone", clusterWithPrimary("cluster-1"), "cluster-1", false, false),
// pg_rewind cannot fall back to streaming replication: the flag machinery
// must stay off even where a standby would use it
Entry("rewind mode wins over streaming availability", clusterWithPrimary("cluster-1"), "cluster-2", true, false),
)
})
var _ = Describe("clearEndOfWALStreamFlag", func() {
newRestorer := func() *barmanRestorer.WALRestorer {
restorer, err := barmanRestorer.New(context.Background(), nil, GinkgoT().TempDir())
Expect(err).ToNot(HaveOccurred())
return restorer
}
It("is a no-op when the flag is not set", func() {
restorer := newRestorer()
Expect(clearEndOfWALStreamFlag(restorer)).To(Succeed())
isEOS, err := restorer.IsEndOfWALStream()
Expect(err).ToNot(HaveOccurred())
Expect(isEOS).To(BeFalse())
})
// Regression guard: a flag left over from a normal-recovery invocation that
// ran before this pod was demoted must not survive a pg_rewind restore, or
// it would resurface and wrongly abort the first normal-recovery invocation
// that runs once the rewind is done.
It("removes a pre-existing flag without returning an error", func() {
restorer := newRestorer()
Expect(restorer.SetEndOfWALStream()).To(Succeed())
Expect(clearEndOfWALStreamFlag(restorer)).To(Succeed())
isEOS, err := restorer.IsEndOfWALStream()
Expect(err).ToNot(HaveOccurred())
Expect(isEOS).To(BeFalse())
})
})
var _ = Describe("resolveArchiveEmptyWalArchiveCheck", func() {
// skipAnnotation mirrors the unexported constant in cloudnative-pg's
// pkg/utils; hard-coding the literal makes a divergence surface as a
// failing test rather than silently disabling the check.
const skipAnnotation = "cnpg.io/skipEmptyWalArchiveCheck"
clusterWith := func(annotationValue *string) *cnpgv1.Cluster {
cluster := &cnpgv1.Cluster{}
if annotationValue != nil {
cluster.Annotations = map[string]string{skipAnnotation: *annotationValue}
}
return cluster
}
// markerPath returns the marker file path inside a fresh temp dir,
// creating the file there when present is true.
markerPath := func(present bool) string {
filePath := filepath.Join(GinkgoT().TempDir(), metadata.CheckEmptyWalArchiveFile)
if present {
Expect(os.WriteFile(filePath, []byte{}, 0o600)).To(Succeed())
}
return filePath
}
When("the operator sets the decision", func() {
It("obeys true, ignoring the annotation and the marker file", func() {
// annotation would skip the check and the marker is absent, yet the
// operator's explicit true must still win.
got, err := resolveArchiveEmptyWalArchiveCheck(
ptr.To(true), clusterWith(ptr.To("enabled")), markerPath(false))
Expect(err).NotTo(HaveOccurred())
Expect(got).To(BeTrue())
})
It("obeys false, ignoring the annotation and the marker file", func() {
// annotation would keep the check on and the marker is present, yet the
// operator's explicit false must still win.
got, err := resolveArchiveEmptyWalArchiveCheck(
ptr.To(false), clusterWith(nil), markerPath(true))
Expect(err).NotTo(HaveOccurred())
Expect(got).To(BeFalse())
})
})
When("the operator predates the field (nil decision)", func() {
DescribeTable(
"falls back to the annotation combined with the marker file",
func(annotationValue *string, markerPresent bool, expected bool) {
got, err := resolveArchiveEmptyWalArchiveCheck(
nil, clusterWith(annotationValue), markerPath(markerPresent))
Expect(err).NotTo(HaveOccurred())
Expect(got).To(Equal(expected))
},
Entry("no annotation and marker present: check runs", nil, true, true),
Entry("no annotation and marker absent: check skipped", nil, false, false),
Entry("opt-out annotation and marker present: check skipped", ptr.To("enabled"), true, false),
Entry("unrelated annotation value and marker present: check runs", ptr.To("something-else"), true, true),
Entry("empty annotation value and marker present: check runs", ptr.To(""), true, true),
)
})
})

View File

@ -70,6 +70,13 @@ func (i IdentityImplementation) GetPluginCapabilities(
}, },
}, },
}, },
{
Type: &identity.PluginCapability_Service_{
Service: &identity.PluginCapability_Service{
Type: identity.PluginCapability_Service_TYPE_RESTORE_JOB,
},
},
},
}, },
}, nil }, nil
} }

View File

@ -0,0 +1,51 @@
/*
Copyright © contributors to CloudNativePG, established as
CloudNativePG a Series of LF Projects, LLC.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
SPDX-License-Identifier: Apache-2.0
*/
package instance
import (
"github.com/cloudnative-pg/cnpg-i/pkg/identity"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)
var _ = Describe("IdentityImplementation", func() {
Describe("GetPluginCapabilities", func() {
It("declares the WAL, backup, metrics and restore-job services", func(ctx SpecContext) {
impl := IdentityImplementation{}
response, err := impl.GetPluginCapabilities(ctx, &identity.GetPluginCapabilitiesRequest{})
Expect(err).NotTo(HaveOccurred())
Expect(response).NotTo(BeNil())
var serviceTypes []identity.PluginCapability_Service_Type
for _, capability := range response.GetCapabilities() {
serviceTypes = append(serviceTypes, capability.GetService().GetType())
}
// Runs the phase-0 restore in-process now, hence TYPE_RESTORE_JOB below.
Expect(serviceTypes).To(ConsistOf(
identity.PluginCapability_Service_TYPE_WAL_SERVICE,
identity.PluginCapability_Service_TYPE_BACKUP_SERVICE,
identity.PluginCapability_Service_TYPE_METRICS,
identity.PluginCapability_Service_TYPE_RESTORE_JOB,
))
})
})
})

View File

@ -25,11 +25,13 @@ import (
"github.com/cloudnative-pg/cnpg-i-machinery/pkg/pluginhelper/http" "github.com/cloudnative-pg/cnpg-i-machinery/pkg/pluginhelper/http"
"github.com/cloudnative-pg/cnpg-i/pkg/backup" "github.com/cloudnative-pg/cnpg-i/pkg/backup"
"github.com/cloudnative-pg/cnpg-i/pkg/metrics" "github.com/cloudnative-pg/cnpg-i/pkg/metrics"
restore "github.com/cloudnative-pg/cnpg-i/pkg/restore/job"
"github.com/cloudnative-pg/cnpg-i/pkg/wal" "github.com/cloudnative-pg/cnpg-i/pkg/wal"
"google.golang.org/grpc" "google.golang.org/grpc"
"sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/client"
"github.com/cloudnative-pg/plugin-barman-cloud/internal/cnpgi/common" "github.com/cloudnative-pg/plugin-barman-cloud/internal/cnpgi/common"
barmanrestore "github.com/cloudnative-pg/plugin-barman-cloud/internal/cnpgi/restore"
) )
// CNPGI is the implementation of the PostgreSQL sidecar // CNPGI is the implementation of the PostgreSQL sidecar
@ -60,6 +62,15 @@ func (c *CNPGI) Start(ctx context.Context) error {
metrics.RegisterMetricsServer(server, &metricsImpl{ metrics.RegisterMetricsServer(server, &metricsImpl{
Client: c.Client, Client: c.Client,
}) })
// The instance pod runs the phase-0 bootstrap in-process (no separate
// recovery Job), so the same sidecar must answer the Restore RPC that
// initializes PGDATA from the object store before PostgreSQL starts.
restore.RegisterRestoreJobHooksServer(server, &barmanrestore.JobHookImpl{
Client: c.Client,
SpoolDirectory: c.SpoolDirectory,
PgDataPath: c.PGDataPath,
PgWalFolderToSymlink: common.PgWalVolumePgWalPath,
})
common.AddHealthCheck(server) common.AddHealthCheck(server)
return nil return nil
} }

View File

@ -63,7 +63,7 @@ const (
// Data is the metadata of this plugin. // Data is the metadata of this plugin.
var Data = identity.GetPluginMetadataResponse{ var Data = identity.GetPluginMetadataResponse{
Name: PluginName, Name: PluginName,
Version: "0.12.0", // x-release-please-version Version: "0.15.0", // x-release-please-version
DisplayName: "BarmanCloudInstance", DisplayName: "BarmanCloudInstance",
ProjectUrl: "https://github.com/cloudnative-pg/plugin-barman-cloud", ProjectUrl: "https://github.com/cloudnative-pg/plugin-barman-cloud",
RepositoryUrl: "https://github.com/cloudnative-pg/plugin-barman-cloud", RepositoryUrl: "https://github.com/cloudnative-pg/plugin-barman-cloud",

View File

@ -102,6 +102,13 @@ func (config *PluginConfiguration) GetReplicaSourceBarmanObjectKey() types.Names
} }
} }
// HasAnyBarmanObjectStore reports whether any barman object store is configured.
func (config *PluginConfiguration) HasAnyBarmanObjectStore() bool {
return len(config.BarmanObjectName) > 0 ||
len(config.RecoveryBarmanObjectName) > 0 ||
len(config.ReplicaSourceBarmanObjectName) > 0
}
// GetReferredBarmanObjectsKey gets the list of barman objects referred by this // GetReferredBarmanObjectsKey gets the list of barman objects referred by this
// plugin configuration // plugin configuration
func (config *PluginConfiguration) GetReferredBarmanObjectsKey() []types.NamespacedName { func (config *PluginConfiguration) GetReferredBarmanObjectsKey() []types.NamespacedName {
@ -263,7 +270,7 @@ func getReplicaSourcePlugin(cluster *cnpgv1.Cluster) *cnpgv1.PluginConfiguration
func (config *PluginConfiguration) Validate() error { func (config *PluginConfiguration) Validate() error {
err := NewConfigurationError() err := NewConfigurationError()
if len(config.BarmanObjectName) == 0 && len(config.RecoveryBarmanObjectName) == 0 { if !config.HasAnyBarmanObjectStore() {
return err.WithMessage("no reference to barmanObjectName have been included") return err.WithMessage("no reference to barmanObjectName have been included")
} }

View File

@ -0,0 +1,126 @@
/*
Copyright © contributors to CloudNativePG, established as
CloudNativePG a Series of LF Projects, LLC.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
SPDX-License-Identifier: Apache-2.0
*/
package config
import (
cnpgv1 "github.com/cloudnative-pg/cloudnative-pg/api/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
"github.com/cloudnative-pg/plugin-barman-cloud/internal/cnpgi/metadata"
)
var _ = Describe("PluginConfiguration.Validate", func() {
It("fails when no barman object name is set", func() {
cfg := &PluginConfiguration{}
Expect(cfg.Validate()).To(HaveOccurred())
})
It("passes when only BarmanObjectName is set (backup/archive)", func() {
cfg := &PluginConfiguration{BarmanObjectName: "my-store"}
Expect(cfg.Validate()).To(Succeed())
})
It("passes when only RecoveryBarmanObjectName is set (recovery bootstrap)", func() {
cfg := &PluginConfiguration{RecoveryBarmanObjectName: "my-store"}
Expect(cfg.Validate()).To(Succeed())
})
It("passes when only ReplicaSourceBarmanObjectName is set (pg_basebackup replica cluster)", func() {
cfg := &PluginConfiguration{ReplicaSourceBarmanObjectName: "my-store"}
Expect(cfg.Validate()).To(Succeed())
})
})
var _ = Describe("NewFromCluster", func() {
enabled := true
It("derives the replica source object store for a pg_basebackup replica cluster", func() {
cluster := &cnpgv1.Cluster{
ObjectMeta: metav1.ObjectMeta{Name: "cluster-replica", Namespace: "test-ns"},
Spec: cnpgv1.ClusterSpec{
Bootstrap: &cnpgv1.BootstrapConfiguration{
PgBaseBackup: &cnpgv1.BootstrapPgBaseBackup{Source: "source"},
},
ReplicaCluster: &cnpgv1.ReplicaClusterConfiguration{
Enabled: &enabled,
Source: "source",
},
ExternalClusters: []cnpgv1.ExternalCluster{
{
Name: "source",
PluginConfiguration: &cnpgv1.PluginConfiguration{
Name: metadata.PluginName,
Parameters: map[string]string{
"barmanObjectName": "minio-store",
"serverName": "cluster-example",
},
},
},
},
},
}
cfg := NewFromCluster(cluster)
// The replica source object store is derived from the external cluster plugin,
// while the backup/archive and recovery object stores remain empty: this is the
// distinguishing trait of a pg_basebackup replica cluster (a recovery-bootstrapped
// replica would also populate RecoveryBarmanObjectName).
Expect(cfg.ReplicaSourceBarmanObjectName).To(Equal("minio-store"))
Expect(cfg.ReplicaSourceServerName).To(Equal("cluster-example"))
Expect(cfg.BarmanObjectName).To(BeEmpty())
Expect(cfg.RecoveryBarmanObjectName).To(BeEmpty())
// Validate must accept it, otherwise the lifecycle hook skips sidecar injection.
Expect(cfg.Validate()).To(Succeed())
})
It("ignores a replica source backed by a different plugin", func() {
cluster := &cnpgv1.Cluster{
ObjectMeta: metav1.ObjectMeta{Name: "cluster-replica", Namespace: "test-ns"},
Spec: cnpgv1.ClusterSpec{
Bootstrap: &cnpgv1.BootstrapConfiguration{
PgBaseBackup: &cnpgv1.BootstrapPgBaseBackup{Source: "source"},
},
ReplicaCluster: &cnpgv1.ReplicaClusterConfiguration{
Enabled: &enabled,
Source: "source",
},
ExternalClusters: []cnpgv1.ExternalCluster{
{
Name: "source",
PluginConfiguration: &cnpgv1.PluginConfiguration{
Name: "some-other-plugin.cloudnative-pg.io",
Parameters: map[string]string{"barmanObjectName": "minio-store"},
},
},
},
},
}
cfg := NewFromCluster(cluster)
Expect(cfg.ReplicaSourceBarmanObjectName).To(BeEmpty())
Expect(cfg.Validate()).NotTo(Succeed())
})
})

View File

@ -0,0 +1,32 @@
/*
Copyright © contributors to CloudNativePG, established as
CloudNativePG a Series of LF Projects, LLC.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
SPDX-License-Identifier: Apache-2.0
*/
package config
import (
"testing"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)
func TestConfig(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "Config Suite")
}

View File

@ -273,8 +273,10 @@ func (impl LifecycleImplementation) collectAdditionalInstanceArgs(
return args return args
} }
// Prefer the cluster object store (backup/archive). If not set, fallback to the recovery object store. // Only one object store provides the sidecar arguments, with precedence:
// If neither is configured, no additional args are provided. // BarmanObjectName (backup/archive) > RecoveryBarmanObjectName (recovery
// bootstrap) > ReplicaSourceBarmanObjectName (pg_basebackup replica).
// If none is configured, no additional args are provided.
if len(pluginConfiguration.BarmanObjectName) > 0 { if len(pluginConfiguration.BarmanObjectName) > 0 {
var barmanObjectStore barmancloudv1.ObjectStore var barmanObjectStore barmancloudv1.ObjectStore
if err := impl.Client.Get(ctx, pluginConfiguration.GetBarmanObjectKey(), &barmanObjectStore); err != nil { if err := impl.Client.Get(ctx, pluginConfiguration.GetBarmanObjectKey(), &barmanObjectStore); err != nil {
@ -303,9 +305,59 @@ func (impl LifecycleImplementation) collectAdditionalInstanceArgs(
return args, nil return args, nil
} }
if len(pluginConfiguration.ReplicaSourceBarmanObjectName) > 0 {
key := pluginConfiguration.GetReplicaSourceBarmanObjectKey()
var barmanObjectStore barmancloudv1.ObjectStore
if err := impl.Client.Get(ctx, key, &barmanObjectStore); err != nil {
return nil, fmt.Errorf("while getting replica source barman object store %s: %w", key.String(), err)
}
args := barmanObjectStore.Spec.InstanceSidecarConfiguration.AdditionalContainerArgs
args = append(
args,
collectTypedAdditionalArgs(&barmanObjectStore)...,
)
return args, nil
}
return nil, nil return nil, nil
} }
// shouldInjectBarmanSidecar decides whether an instance pod needs the
// plugin-barman-cloud sidecar.
//
// Backup/archiving and replica-source configs need it for as long as the
// cluster exists, so those always inject it. A recovery-only cluster (only
// RecoveryBarmanObjectName set, mirroring pluginConfiguration.Validate())
// only needs it for the one-time bootstrap restore, so it's gated on
// cluster.Status.CurrentPrimary instead.
//
// CurrentPrimary is set by the instance manager itself, from inside the pod,
// only once bootstrap completes (see instance_startup.go in cloudnative-pg).
// cluster.Status.Instances / IsInitialized() looks equivalent but flips as
// soon as the instance's PVC exists, before the pod is even created - using
// it here would mean the sidecar never reaches the pod that needs it.
//
// Once CurrentPrimary is set, the operator's drift-check
// (checkPodSpecIsOutdated) sees the running pod's spec as outdated and rolls
// it out to drop the sidecar. Accepted deliberately: one deterministic
// rollout via the same machinery used for any other pod-spec change
// (switchover if a replica exists, in-place restart otherwise), not a new
// risk.
func shouldInjectBarmanSidecar(
cluster *cnpgv1.Cluster,
pluginConfiguration *config.PluginConfiguration,
) bool {
if len(pluginConfiguration.BarmanObjectName) != 0 || len(pluginConfiguration.ReplicaSourceBarmanObjectName) != 0 {
return true
}
if len(pluginConfiguration.RecoveryBarmanObjectName) == 0 {
return false
}
return cluster.Status.CurrentPrimary == ""
}
func reconcileInstancePod( func reconcileInstancePod(
ctx context.Context, ctx context.Context,
cluster *cnpgv1.Cluster, cluster *cnpgv1.Cluster,
@ -323,8 +375,7 @@ func reconcileInstancePod(
mutatedPod := pod.DeepCopy() mutatedPod := pod.DeepCopy()
if len(pluginConfiguration.BarmanObjectName) != 0 || if shouldInjectBarmanSidecar(cluster, pluginConfiguration) {
len(pluginConfiguration.ReplicaSourceBarmanObjectName) != 0 {
if err := reconcilePodSpec( if err := reconcilePodSpec(
cluster, cluster,
&mutatedPod.Spec, &mutatedPod.Spec,
@ -337,7 +388,7 @@ func reconcileInstancePod(
return nil, fmt.Errorf("while reconciling pod spec for pod: %w", err) return nil, fmt.Errorf("while reconciling pod spec for pod: %w", err)
} }
} else { } else {
contextLogger.Debug("No need to mutate instance with no backup & archiving configuration") contextLogger.Debug("No need to mutate instance, sidecar not required for this configuration and pod")
} }
patch, err := object.CreatePatch(mutatedPod, pod) patch, err := object.CreatePatch(mutatedPod, pod)
@ -387,8 +438,9 @@ func reconcilePodSpec(
envs = append(envs, config.env...) envs = append(envs, config.env...)
baseProbe := &corev1.Probe{ baseProbe := &corev1.Probe{
FailureThreshold: 10, PeriodSeconds: 1,
TimeoutSeconds: 10, FailureThreshold: 30,
TimeoutSeconds: 5,
ProbeHandler: corev1.ProbeHandler{ ProbeHandler: corev1.ProbeHandler{
Exec: &corev1.ExecAction{ Exec: &corev1.ExecAction{
Command: []string{"/manager", "healthcheck", "unix"}, Command: []string{"/manager", "healthcheck", "unix"},

View File

@ -48,6 +48,9 @@ func (impl LifecycleImplementation) collectSidecarResourcesForPod(
ctx context.Context, ctx context.Context,
configuration *config.PluginConfiguration, configuration *config.PluginConfiguration,
) (corev1.ResourceRequirements, error) { ) (corev1.ResourceRequirements, error) {
// Only one object store provides the sidecar resources, with precedence:
// BarmanObjectName (backup/archive) > RecoveryBarmanObjectName (recovery
// bootstrap) > ReplicaSourceBarmanObjectName (pg_basebackup replica).
if len(configuration.BarmanObjectName) > 0 { if len(configuration.BarmanObjectName) > 0 {
// On a replica cluster that also archives, the designated primary // On a replica cluster that also archives, the designated primary
// will use both the replica source object store and the object store // will use both the replica source object store and the object store
@ -64,10 +67,10 @@ func (impl LifecycleImplementation) collectSidecarResourcesForPod(
} }
if len(configuration.RecoveryBarmanObjectName) > 0 { if len(configuration.RecoveryBarmanObjectName) > 0 {
// On a replica cluster that doesn't archive, the designated primary // On a cluster recovering from an object store (including log-shipping
// uses only the replica source object store. // replica clusters, where the recovery and replica source object stores
// In this case, we use the replica source object store for configuring // coincide), we use the recovery object store for configuring the
// the resources of the sidecar container. // resources of the sidecar container.
var barmanObjectStore barmancloudv1.ObjectStore var barmanObjectStore barmancloudv1.ObjectStore
if err := impl.Client.Get(ctx, configuration.GetRecoveryBarmanObjectKey(), &barmanObjectStore); err != nil { if err := impl.Client.Get(ctx, configuration.GetRecoveryBarmanObjectKey(), &barmanObjectStore); err != nil {
return corev1.ResourceRequirements{}, err return corev1.ResourceRequirements{}, err
@ -76,5 +79,18 @@ func (impl LifecycleImplementation) collectSidecarResourcesForPod(
return barmanObjectStore.Spec.InstanceSidecarConfiguration.Resources, nil return barmanObjectStore.Spec.InstanceSidecarConfiguration.Resources, nil
} }
if len(configuration.ReplicaSourceBarmanObjectName) > 0 {
// On a replica cluster bootstrapped via pg_basebackup, the designated
// primary uses only the replica source object store.
// In this case, we use the replica source object store for configuring
// the resources of the sidecar container.
var barmanObjectStore barmancloudv1.ObjectStore
if err := impl.Client.Get(ctx, configuration.GetReplicaSourceBarmanObjectKey(), &barmanObjectStore); err != nil {
return corev1.ResourceRequirements{}, err
}
return barmanObjectStore.Spec.InstanceSidecarConfiguration.Resources, nil
}
return corev1.ResourceRequirements{}, nil return corev1.ResourceRequirements{}, nil
} }

View File

@ -28,6 +28,7 @@ import (
barmancloudv1 "github.com/cloudnative-pg/plugin-barman-cloud/api/v1" barmancloudv1 "github.com/cloudnative-pg/plugin-barman-cloud/api/v1"
batchv1 "k8s.io/api/batch/v1" batchv1 "k8s.io/api/batch/v1"
corev1 "k8s.io/api/core/v1" corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
"sigs.k8s.io/controller-runtime/pkg/client/fake" "sigs.k8s.io/controller-runtime/pkg/client/fake"
@ -241,6 +242,69 @@ var _ = Describe("LifecycleImplementation", func() {
HaveKey("value"))) HaveKey("value")))
}) })
It("injects the sidecar for a recovery-only cluster", func(ctx SpecContext) {
recoveryOnlyConfig := &config.PluginConfiguration{
RecoveryBarmanObjectName: "minio-store-recovery",
}
pod := &corev1.Pod{
TypeMeta: podTypeMeta,
ObjectMeta: metav1.ObjectMeta{Name: "test-pod"},
Spec: corev1.PodSpec{Containers: []corev1.Container{{Name: "postgres"}}},
}
podJSON, _ := json.Marshal(pod)
request := &lifecycle.OperatorLifecycleRequest{
ObjectDefinition: podJSON,
}
response, err := reconcileInstancePod(ctx, cluster, request, recoveryOnlyConfig, sidecarConfiguration{})
Expect(err).NotTo(HaveOccurred())
Expect(response).NotTo(BeNil())
Expect(response.JsonPatch).NotTo(BeEmpty())
var patch []map[string]interface{}
Expect(json.Unmarshal(response.JsonPatch, &patch)).To(Succeed())
Expect(patch).To(ContainElement(HaveKeyWithValue("path", "/spec/initContainers")))
})
It("does not inject the sidecar for a recovery-only cluster that has "+
"already completed its initial bootstrap", func(ctx SpecContext) {
recoveryOnlyConfig := &config.PluginConfiguration{
RecoveryBarmanObjectName: "minio-store-recovery",
}
cluster.Status.CurrentPrimary = "test-pod"
pod := &corev1.Pod{
TypeMeta: podTypeMeta,
ObjectMeta: metav1.ObjectMeta{Name: "test-pod"},
Spec: corev1.PodSpec{Containers: []corev1.Container{{Name: "postgres"}}},
}
podJSON, _ := json.Marshal(pod)
request := &lifecycle.OperatorLifecycleRequest{
ObjectDefinition: podJSON,
}
response, err := reconcileInstancePod(ctx, cluster, request, recoveryOnlyConfig, sidecarConfiguration{})
Expect(err).NotTo(HaveOccurred())
Expect(response).NotTo(BeNil())
Expect(response.JsonPatch).To(BeEmpty())
})
It("does not mutate the pod when no object store is configured", func(ctx SpecContext) {
emptyConfig := &config.PluginConfiguration{}
pod := &corev1.Pod{
TypeMeta: podTypeMeta,
ObjectMeta: metav1.ObjectMeta{Name: "test-pod"},
Spec: corev1.PodSpec{Containers: []corev1.Container{{Name: "postgres"}}},
}
podJSON, _ := json.Marshal(pod)
request := &lifecycle.OperatorLifecycleRequest{
ObjectDefinition: podJSON,
}
response, err := reconcileInstancePod(ctx, cluster, request, emptyConfig, sidecarConfiguration{})
Expect(err).NotTo(HaveOccurred())
Expect(response).NotTo(BeNil())
Expect(response.JsonPatch).To(BeEmpty())
})
It("returns an error for invalid pod definition", func(ctx SpecContext) { It("returns an error for invalid pod definition", func(ctx SpecContext) {
request := &lifecycle.OperatorLifecycleRequest{ request := &lifecycle.OperatorLifecycleRequest{
ObjectDefinition: []byte("invalid-json"), ObjectDefinition: []byte("invalid-json"),
@ -293,6 +357,24 @@ var _ = Describe("LifecycleImplementation", func() {
Expect(args).To(Equal(recoveryArgs)) Expect(args).To(Equal(recoveryArgs))
}) })
It("falls back to replica source object store when primary and recovery not set", func(ctx SpecContext) {
ns := "test-ns"
cluster := &cnpgv1.Cluster{ObjectMeta: metav1.ObjectMeta{Name: "c", Namespace: ns}}
pc := &config.PluginConfiguration{
Cluster: cluster,
ReplicaSourceBarmanObjectName: "replica-source-store",
}
replicaArgs := []string{"--replica-a", "--replica-b"}
cli := buildClientFunc(
makeStoreFunc(ns, pc.ReplicaSourceBarmanObjectName, replicaArgs),
).Build()
impl := LifecycleImplementation{Client: cli}
args, err := impl.collectAdditionalInstanceArgs(ctx, pc)
Expect(err).NotTo(HaveOccurred())
Expect(args).To(Equal(replicaArgs))
})
It("returns nil when neither object name is configured", func(ctx SpecContext) { It("returns nil when neither object name is configured", func(ctx SpecContext) {
ns := "test-ns" ns := "test-ns"
cluster := &cnpgv1.Cluster{ObjectMeta: metav1.ObjectMeta{Name: "c", Namespace: ns}} cluster := &cnpgv1.Cluster{ObjectMeta: metav1.ObjectMeta{Name: "c", Namespace: ns}}
@ -386,6 +468,117 @@ var _ = Describe("LifecycleImplementation", func() {
Expect(err).NotTo(HaveOccurred()) Expect(err).NotTo(HaveOccurred())
Expect(args).To(Equal([]string{"--log-level=info"})) Expect(args).To(Equal([]string{"--log-level=info"}))
}) })
It("includes --log-level from replica source object store when only replica source set", func(ctx SpecContext) {
ns := "test-ns"
cluster := &cnpgv1.Cluster{ObjectMeta: metav1.ObjectMeta{Name: "c", Namespace: ns}}
pc := &config.PluginConfiguration{
Cluster: cluster,
ReplicaSourceBarmanObjectName: "replica-source-store",
}
store := &barmancloudv1.ObjectStore{
TypeMeta: metav1.TypeMeta{Kind: "ObjectStore", APIVersion: barmancloudv1.GroupVersion.String()},
ObjectMeta: metav1.ObjectMeta{Name: pc.ReplicaSourceBarmanObjectName, Namespace: ns},
Spec: barmancloudv1.ObjectStoreSpec{
InstanceSidecarConfiguration: barmancloudv1.InstanceSidecarConfiguration{
LogLevel: "warning",
},
},
}
s := runtime.NewScheme()
barmancloudv1.AddKnownTypes(s)
cli := fake.NewClientBuilder().WithScheme(s).WithRuntimeObjects(store).Build()
impl := LifecycleImplementation{Client: cli}
args, err := impl.collectAdditionalInstanceArgs(ctx, pc)
Expect(err).NotTo(HaveOccurred())
Expect(args).To(Equal([]string{"--log-level=warning"}))
})
})
Describe("collectSidecarResourcesForPod", func() {
makeStoreWithResourcesFunc := func(ns, name string, res corev1.ResourceRequirements) *barmancloudv1.ObjectStore {
return &barmancloudv1.ObjectStore{
TypeMeta: metav1.TypeMeta{Kind: "ObjectStore", APIVersion: barmancloudv1.GroupVersion.String()},
ObjectMeta: metav1.ObjectMeta{Name: name, Namespace: ns},
Spec: barmancloudv1.ObjectStoreSpec{
InstanceSidecarConfiguration: barmancloudv1.InstanceSidecarConfiguration{
Resources: res,
},
},
}
}
It("uses the cluster object store resources when set", func(ctx SpecContext) {
ns := "test-ns"
cluster := &cnpgv1.Cluster{ObjectMeta: metav1.ObjectMeta{Name: "c", Namespace: ns}}
pc := &config.PluginConfiguration{Cluster: cluster, BarmanObjectName: "primary-store"}
res := corev1.ResourceRequirements{
Requests: corev1.ResourceList{corev1.ResourceMemory: resource.MustParse("64Mi")},
}
cli := buildClientFunc(makeStoreWithResourcesFunc(ns, pc.BarmanObjectName, res)).Build()
impl := LifecycleImplementation{Client: cli}
got, err := impl.collectSidecarResourcesForPod(ctx, pc)
Expect(err).NotTo(HaveOccurred())
gotMem := got.Requests[corev1.ResourceMemory]
Expect(gotMem.String()).To(Equal("64Mi"))
})
It("uses the recovery object store resources when only recovery is set", func(ctx SpecContext) {
ns := "test-ns"
cluster := &cnpgv1.Cluster{ObjectMeta: metav1.ObjectMeta{Name: "c", Namespace: ns}}
pc := &config.PluginConfiguration{Cluster: cluster, RecoveryBarmanObjectName: "recovery-store"}
res := corev1.ResourceRequirements{
Requests: corev1.ResourceList{corev1.ResourceMemory: resource.MustParse("128Mi")},
}
cli := buildClientFunc(makeStoreWithResourcesFunc(ns, pc.RecoveryBarmanObjectName, res)).Build()
impl := LifecycleImplementation{Client: cli}
got, err := impl.collectSidecarResourcesForPod(ctx, pc)
Expect(err).NotTo(HaveOccurred())
gotMem := got.Requests[corev1.ResourceMemory]
Expect(gotMem.String()).To(Equal("128Mi"))
})
It("uses the replica source object store resources when only replica source is set", func(ctx SpecContext) {
ns := "test-ns"
cluster := &cnpgv1.Cluster{ObjectMeta: metav1.ObjectMeta{Name: "c", Namespace: ns}}
pc := &config.PluginConfiguration{Cluster: cluster, ReplicaSourceBarmanObjectName: "replica-source-store"}
res := corev1.ResourceRequirements{
Requests: corev1.ResourceList{corev1.ResourceMemory: resource.MustParse("256Mi")},
}
cli := buildClientFunc(makeStoreWithResourcesFunc(ns, pc.ReplicaSourceBarmanObjectName, res)).Build()
impl := LifecycleImplementation{Client: cli}
got, err := impl.collectSidecarResourcesForPod(ctx, pc)
Expect(err).NotTo(HaveOccurred())
gotMem := got.Requests[corev1.ResourceMemory]
Expect(gotMem.String()).To(Equal("256Mi"))
})
It("returns empty resources when no object store is configured", func(ctx SpecContext) {
ns := "test-ns"
cluster := &cnpgv1.Cluster{ObjectMeta: metav1.ObjectMeta{Name: "c", Namespace: ns}}
pc := &config.PluginConfiguration{Cluster: cluster}
cli := buildClientFunc().Build()
impl := LifecycleImplementation{Client: cli}
got, err := impl.collectSidecarResourcesForPod(ctx, pc)
Expect(err).NotTo(HaveOccurred())
Expect(got).To(Equal(corev1.ResourceRequirements{}))
})
It("returns an error if the replica source object store cannot be retrieved", func(ctx SpecContext) {
ns := "test-ns"
cluster := &cnpgv1.Cluster{ObjectMeta: metav1.ObjectMeta{Name: "c", Namespace: ns}}
pc := &config.PluginConfiguration{Cluster: cluster, ReplicaSourceBarmanObjectName: "missing-store"}
cli := buildClientFunc().Build()
impl := LifecycleImplementation{Client: cli}
_, err := impl.collectSidecarResourcesForPod(ctx, pc)
Expect(err).To(HaveOccurred())
})
}) })
}) })

View File

@ -113,6 +113,7 @@ func (impl JobHookImpl) Restore(
configuration.Cluster, configuration.Cluster,
&targetObjectStore.Spec.Configuration, &targetObjectStore.Spec.Configuration,
targetObjectStore.Name, targetObjectStore.Name,
req.CheckEmptyWalArchive,
); err != nil { ); err != nil {
return nil, err return nil, err
} }
@ -181,6 +182,9 @@ func (impl JobHookImpl) restoreDataDir(
if backup.Status.EndpointURL != "" { if backup.Status.EndpointURL != "" {
options = append(options, "--endpoint-url", backup.Status.EndpointURL) options = append(options, "--endpoint-url", backup.Status.EndpointURL)
} }
options = barmanConfiguration.Data.AppendRestoreAdditionalCommandArgs(options)
options = append(options, backup.Status.DestinationPath) options = append(options, backup.Status.DestinationPath)
options = append(options, backup.Status.ServerName) options = append(options, backup.Status.ServerName)
options = append(options, backup.Status.BackupID) options = append(options, backup.Status.BackupID)
@ -247,6 +251,7 @@ func (impl *JobHookImpl) checkBackupDestination(
cluster *cnpgv1.Cluster, cluster *cnpgv1.Cluster,
barmanConfiguration *cnpgv1.BarmanObjectStoreConfiguration, barmanConfiguration *cnpgv1.BarmanObjectStoreConfiguration,
objectStoreName string, objectStoreName string,
operatorCheckEmptyWalArchive *bool,
) error { ) error {
// Get environment from cache // Get environment from cache
env, err := barmanCredentials.EnvSetCloudCredentialsAndCertificates(ctx, env, err := barmanCredentials.EnvSetCloudCredentialsAndCertificates(ctx,
@ -285,14 +290,26 @@ func (impl *JobHookImpl) checkBackupDestination(
} }
} }
// Check if we're ok to archive in the desired destination if resolveRestoreEmptyWalArchiveCheck(operatorCheckEmptyWalArchive, cluster) {
if utils.IsEmptyWalArchiveCheckEnabled(&cluster.ObjectMeta) {
return common.CheckBackupDestination(ctx, barmanConfiguration, walArchiver, serverName) return common.CheckBackupDestination(ctx, barmanConfiguration, walArchiver, serverName)
} }
return nil return nil
} }
// resolveRestoreEmptyWalArchiveCheck reports whether the destination must be
// verified before restoring. When the operator sets the decision (non-nil) it
// is obeyed as-is; a nil value comes from an operator that predates this field,
// so we fall back to the Cluster annotation. Unlike archiving, restore is a
// one-shot operation that has never been gated on the first-archive marker
// file, so the annotation is the only fallback needed.
func resolveRestoreEmptyWalArchiveCheck(operatorDecision *bool, cluster *cnpgv1.Cluster) bool {
if operatorDecision != nil {
return *operatorDecision
}
return utils.IsEmptyWalArchiveCheckEnabled(&cluster.ObjectMeta)
}
// restoreCustomWalDir moves the current pg_wal data to the specified custom wal dir and applies the symlink // restoreCustomWalDir moves the current pg_wal data to the specified custom wal dir and applies the symlink
// returns indicating if any changes were made and any error encountered in the process // returns indicating if any changes were made and any error encountered in the process
func (impl JobHookImpl) restoreCustomWalDir(ctx context.Context) (bool, error) { func (impl JobHookImpl) restoreCustomWalDir(ctx context.Context) (bool, error) {

View File

@ -0,0 +1,66 @@
/*
Copyright © contributors to CloudNativePG, established as
CloudNativePG a Series of LF Projects, LLC.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
SPDX-License-Identifier: Apache-2.0
*/
package restore
import (
cnpgv1 "github.com/cloudnative-pg/cloudnative-pg/api/v1"
"k8s.io/utils/ptr"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)
var _ = Describe("resolveRestoreEmptyWalArchiveCheck", func() {
// skipAnnotation mirrors the unexported constant in cloudnative-pg's
// pkg/utils; hard-coding the literal makes a divergence surface as a
// failing test rather than silently disabling the check.
const skipAnnotation = "cnpg.io/skipEmptyWalArchiveCheck"
clusterWith := func(annotationValue *string) *cnpgv1.Cluster {
cluster := &cnpgv1.Cluster{}
if annotationValue != nil {
cluster.Annotations = map[string]string{skipAnnotation: *annotationValue}
}
return cluster
}
When("the operator sets the decision", func() {
It("obeys true even when the annotation would skip the check", func() {
Expect(resolveRestoreEmptyWalArchiveCheck(ptr.To(true), clusterWith(ptr.To("enabled")))).To(BeTrue())
})
It("obeys false even when the annotation would keep the check on", func() {
Expect(resolveRestoreEmptyWalArchiveCheck(ptr.To(false), clusterWith(nil))).To(BeFalse())
})
})
When("the operator predates the field (nil decision)", func() {
DescribeTable(
"falls back to the Cluster annotation, never to a marker file",
func(annotationValue *string, expected bool) {
Expect(resolveRestoreEmptyWalArchiveCheck(nil, clusterWith(annotationValue))).To(Equal(expected))
},
Entry("no annotation: check runs", nil, true),
Entry("opt-out annotation: check skipped", ptr.To("enabled"), false),
Entry("unrelated annotation value: check runs", ptr.To("something-else"), true),
Entry("empty annotation value: check runs", ptr.To(""), true),
)
})
})

View File

@ -44,9 +44,6 @@ type CNPGI struct {
// Start starts the GRPC service // Start starts the GRPC service
func (c *CNPGI) Start(ctx context.Context) error { func (c *CNPGI) Start(ctx context.Context) error {
// PgWalVolumePgWalPath is the path of pg_wal directory inside the WAL volume when present
const PgWalVolumePgWalPath = "/var/lib/postgresql/wal/pg_wal"
enrich := func(server *grpc.Server) error { enrich := func(server *grpc.Server) error {
wal.RegisterWALServer(server, common.WALServiceImplementation{ wal.RegisterWALServer(server, common.WALServiceImplementation{
InstanceName: c.InstanceName, InstanceName: c.InstanceName,
@ -60,7 +57,7 @@ func (c *CNPGI) Start(ctx context.Context) error {
Client: c.Client, Client: c.Client,
SpoolDirectory: c.SpoolDirectory, SpoolDirectory: c.SpoolDirectory,
PgDataPath: c.PGDataPath, PgDataPath: c.PGDataPath,
PgWalFolderToSymlink: PgWalVolumePgWalPath, PgWalFolderToSymlink: common.PgWalVolumePgWalPath,
}) })
common.AddHealthCheck(server) common.AddHealthCheck(server)

View File

@ -0,0 +1,32 @@
/*
Copyright © contributors to CloudNativePG, established as
CloudNativePG a Series of LF Projects, LLC.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
SPDX-License-Identifier: Apache-2.0
*/
package restore
import (
"testing"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)
func TestRestore(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "Restore job hook test suite")
}

View File

@ -25,6 +25,7 @@ import (
cnpgv1 "github.com/cloudnative-pg/cloudnative-pg/api/v1" cnpgv1 "github.com/cloudnative-pg/cloudnative-pg/api/v1"
"github.com/cloudnative-pg/machinery/pkg/log" "github.com/cloudnative-pg/machinery/pkg/log"
"github.com/spf13/viper" "github.com/spf13/viper"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/runtime/schema"
) )
@ -49,6 +50,7 @@ func AddCNPGToScheme(ctx context.Context, s *runtime.Scheme) {
&cnpgv1.Backup{}, &cnpgv1.BackupList{}, &cnpgv1.Backup{}, &cnpgv1.BackupList{},
&cnpgv1.ScheduledBackup{}, &cnpgv1.ScheduledBackupList{}, &cnpgv1.ScheduledBackup{}, &cnpgv1.ScheduledBackupList{},
) )
metav1.AddToGroupVersion(s, schemeGroupVersion)
log.FromContext(ctx).Info("CNPG types registration", "schemeGroupVersion", schemeGroupVersion) log.FromContext(ctx).Info("CNPG types registration", "schemeGroupVersion", schemeGroupVersion)
} }

View File

@ -175,6 +175,25 @@ spec:
format: int32 format: int32
minimum: 1 minimum: 1
type: integer type: integer
restoreAdditionalCommandArgs:
description: |-
Additional arguments that can be appended to the 'barman-cloud-restore'
command-line invocation. These arguments provide flexibility to customize
the data restore process further, according to specific requirements or
configurations.
Example:
In a scenario where specialized restore options are required, such as setting
a specific read timeout or defining custom behavior, users can use this field
to specify additional command arguments.
Note:
It's essential to ensure that the provided arguments are valid and supported
by the 'barman-cloud-restore' command, to avoid potential errors or unintended
behavior during execution.
items:
type: string
type: array
type: object type: object
destinationPath: destinationPath:
description: |- description: |-
@ -440,7 +459,9 @@ spec:
description: Selects a key of a ConfigMap. description: Selects a key of a ConfigMap.
properties: properties:
key: key:
description: The key to select. description: |-
The key to select from the ConfigMap's Data field.
Keys in the BinaryData field are not currently propagated to container env vars.
type: string type: string
name: name:
default: "" default: ""

View File

@ -12,14 +12,14 @@
rebaseWhen: 'never', rebaseWhen: 'never',
prConcurrentLimit: 5, prConcurrentLimit: 5,
// Override default ignorePaths to scan test/e2e for emulator image dependencies // Override default ignorePaths to scan test/e2e for emulator image dependencies
// Removed: '**/test/**' // Removed: '**/test/**', '**/tests/**' (this repo's e2e Ginkgo packages live
// under test/e2e/internal/tests/**, which the plural pattern was excluding)
ignorePaths: [ ignorePaths: [
'**/node_modules/**', '**/node_modules/**',
'**/bower_components/**', '**/bower_components/**',
'**/vendor/**', '**/vendor/**',
'**/examples/**', '**/examples/**',
'**/__tests__/**', '**/__tests__/**',
'**/tests/**',
'**/__fixtures__/**', '**/__fixtures__/**',
], ],
lockFileMaintenance: { lockFileMaintenance: {
@ -53,6 +53,7 @@
], ],
matchStrings: [ matchStrings: [
'//\\s*renovate:\\s*datasource=(?<datasource>[a-z-.]+?)\\s+depName=(?<depName>[^\\s]+?)(?:\\s+versioning=(?<versioning>[^\\s]+?))?\\s*\\n\\s*//\\s*Version:\\s*(?<currentValue>[^\\s]+?)\\s*\\n\\s*Image:\\s*"[^@]+@(?<currentDigest>sha256:[a-f0-9]+)"', '//\\s*renovate:\\s*datasource=(?<datasource>[a-z-.]+?)\\s+depName=(?<depName>[^\\s]+?)(?:\\s+versioning=(?<versioning>[^\\s]+?))?\\s*\\n\\s*//\\s*Version:\\s*(?<currentValue>[^\\s]+?)\\s*\\n\\s*Image:\\s*"[^@]+@(?<currentDigest>sha256:[a-f0-9]+)"',
'//\\s*renovate:\\s*datasource=(?<datasource>[a-z-.]+?)\\s+depName=(?<depName>[^\\s]+?)(?:\\s+versioning=(?<versioning>[^\\s]+?))?\\s*\\n\\s*const\\s+\\w+\\s*=\\s*"(?<currentValue>[^"]+?)"',
], ],
}, },
{ {

View File

@ -39,6 +39,7 @@ import (
_ "github.com/cloudnative-pg/plugin-barman-cloud/test/e2e/internal/tests/backup" _ "github.com/cloudnative-pg/plugin-barman-cloud/test/e2e/internal/tests/backup"
_ "github.com/cloudnative-pg/plugin-barman-cloud/test/e2e/internal/tests/credentialrotation" _ "github.com/cloudnative-pg/plugin-barman-cloud/test/e2e/internal/tests/credentialrotation"
_ "github.com/cloudnative-pg/plugin-barman-cloud/test/e2e/internal/tests/replicacluster" _ "github.com/cloudnative-pg/plugin-barman-cloud/test/e2e/internal/tests/replicacluster"
_ "github.com/cloudnative-pg/plugin-barman-cloud/test/e2e/internal/tests/walrestore"
. "github.com/onsi/ginkgo/v2" . "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega" . "github.com/onsi/gomega"

View File

@ -55,10 +55,10 @@ func WithIgnoreExistingResources(ignore bool) InstallOption {
} }
} }
// TODO: renovate
// DefaultVersion is the default version of cert-manager to install. // DefaultVersion is the default version of cert-manager to install.
const DefaultVersion = "v1.15.1" //
// renovate: datasource=github-releases depName=cert-manager/cert-manager
const DefaultVersion = "v1.21.1"
// Install installs cert-manager using kubectl. // Install installs cert-manager using kubectl.
func Install(ctx context.Context, cl client.Client, opts ...InstallOption) error { func Install(ctx context.Context, cl client.Client, opts ...InstallOption) error {

View File

@ -97,9 +97,8 @@ func WithIgnoreExistingResources(ignore bool) SetupOption {
} }
func defaultSetupOptions() SetupOptions { func defaultSetupOptions() SetupOptions {
// TODO: renovate
return SetupOptions{ return SetupOptions{
CertManagerVersion: "v1.15.1", CertManagerVersion: certmanager.DefaultVersion,
} }
} }

View File

@ -72,8 +72,8 @@ func newAzuriteDeployment(namespace, name string) *appsv1.Deployment {
{ {
Name: name, Name: name,
// renovate: datasource=docker depName=mcr.microsoft.com/azure-storage/azurite versioning=docker // renovate: datasource=docker depName=mcr.microsoft.com/azure-storage/azurite versioning=docker
// Version: 3.35.0 // Version: 3.37.0
Image: "mcr.microsoft.com/azure-storage/azurite@sha256:647c63a91102a9d8e8000aab803436e1fc85fbb285e7ce830a82ee5d6661cf37", Image: "mcr.microsoft.com/azure-storage/azurite@sha256:830430c1da1a2d537e08f3e6764dd1f5ae00cf0346bcaf625b968ec3f0971fd5",
Args: []string{ Args: []string{
"azurite-blob", "azurite-blob",
"--blobHost", "--blobHost",

View File

@ -72,8 +72,8 @@ func newGCSDeployment(namespace, name string) *appsv1.Deployment {
{ {
Name: name, Name: name,
// renovate: datasource=docker depName=fsouza/fake-gcs-server versioning=docker // renovate: datasource=docker depName=fsouza/fake-gcs-server versioning=docker
// Version: 1.54.0 // Version: 1.56.1
Image: "fsouza/fake-gcs-server@sha256:3730da0e31f7e5186a90ec4899dc2c336104e7599df400411392ef17e684c31f", Image: "fsouza/fake-gcs-server@sha256:797ce226d62f947c009dc40246b30cfb456b8473d8241407f9d6f2c04e4d69ef",
Ports: []corev1.ContainerPort{ Ports: []corev1.ContainerPort{
{ {
ContainerPort: 4443, ContainerPort: 4443,

View File

@ -56,6 +56,12 @@ var _ = Describe("Backup and restore", func() {
ctx SpecContext, ctx SpecContext,
factory testCaseFactory, factory testCaseFactory,
) { ) {
switch factory.(type) {
case *gcsBackupPluginBackupPluginRestore, *gcsBackupPluginBackupInTreeRestore,
*gcsBackupPluginInTreeBackupPluginRestore:
Skip("GCS e2e tests are disabled until https://github.com/EnterpriseDB/barman/issues/1218 is fixed")
}
testResources := factory.createBackupRestoreTestResources(namespace.Name) testResources := factory.createBackupRestoreTestResources(namespace.Name)
By("starting the ObjectStore deployment") By("starting the ObjectStore deployment")

View File

@ -57,6 +57,11 @@ var _ = Describe("Replica cluster", func() {
ctx SpecContext, ctx SpecContext,
factory testCaseFactory, factory testCaseFactory,
) { ) {
switch factory.(type) {
case gcsReplicaClusterFactory:
Skip("GCS e2e tests are disabled until https://github.com/EnterpriseDB/barman/issues/1218 is fixed")
}
testResources := factory.createReplicaClusterTestResources(namespace.Name) testResources := factory.createReplicaClusterTestResources(namespace.Name)
By("starting the ObjectStore deployments") By("starting the ObjectStore deployments")

View File

@ -0,0 +1,24 @@
/*
Copyright © contributors to CloudNativePG, established as
CloudNativePG a Series of LF Projects, LLC.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
SPDX-License-Identifier: Apache-2.0
*/
// Package walrestore contains the end-to-end test for the parallel WAL restore
// behaviour of the Barman Cloud Plugin: prefetching upcoming segments into the
// spool directory, serving later requests from the spool, and tracking the
// end-of-wal-stream sentinel.
package walrestore

View File

@ -0,0 +1,178 @@
/*
Copyright © contributors to CloudNativePG, established as
CloudNativePG a Series of LF Projects, LLC.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
SPDX-License-Identifier: Apache-2.0
*/
package walrestore
import (
cloudnativepgv1 "github.com/cloudnative-pg/api/pkg/api/v1"
barmanapi "github.com/cloudnative-pg/barman-cloud/pkg/api"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/utils/ptr"
pluginBarmanCloudV1 "github.com/cloudnative-pg/plugin-barman-cloud/api/v1"
"github.com/cloudnative-pg/plugin-barman-cloud/test/e2e/internal/objectstore"
)
const (
minioName = "minio"
objectStoreName = "source"
clusterName = "source"
s3ClientName = "s3-client"
storageSize = "1Gi"
// walMaxParallel is the prefetch parallelism under test: for a regular WAL
// request the plugin restores the requested segment and prefetches the next
// ones, up to this many segments in total.
walMaxParallel = 3
)
// newObjectStoreResources returns the minio server Deployment/Service/Secret/PVC.
func newObjectStoreResources(namespace string) *objectstore.Resources {
return objectstore.NewMinioObjectStoreResources(namespace, minioName)
}
// newObjectStore returns a minio-backed ObjectStore configured with the WAL
// prefetch parallelism (maxParallel) under test. Archiving with gzip makes the
// archived segments carry the ".gz" suffix that forged segments are copied from.
func newObjectStore(namespace string) *pluginBarmanCloudV1.ObjectStore {
store := objectstore.NewMinioObjectStore(namespace, objectStoreName, minioName)
store.Spec.Configuration.Wal = &barmanapi.WalBackupConfiguration{
MaxParallel: walMaxParallel,
Compression: barmanapi.CompressionTypeGzip,
}
return store
}
// newCluster returns a 2-instance cluster that uses the plugin as its WAL
// archiver, so the standby drives WAL restore (and its prefetch/spool/
// end-of-wal-stream state machine) through the plugin.
func newCluster(namespace string) *cloudnativepgv1.Cluster {
return &cloudnativepgv1.Cluster{
TypeMeta: metav1.TypeMeta{
Kind: "Cluster",
APIVersion: "postgresql.cnpg.io/v1",
},
ObjectMeta: metav1.ObjectMeta{
Name: clusterName,
Namespace: namespace,
},
Spec: cloudnativepgv1.ClusterSpec{
Instances: 2,
ImagePullPolicy: corev1.PullAlways,
Plugins: []cloudnativepgv1.PluginConfiguration{
{
Name: "barman-cloud.cloudnative-pg.io",
Parameters: map[string]string{
"barmanObjectName": objectStoreName,
},
IsWALArchiver: ptr.To(true),
},
},
PostgresConfiguration: cloudnativepgv1.PostgresConfiguration{
Parameters: map[string]string{
"log_min_messages": "DEBUG4",
},
},
StorageConfiguration: cloudnativepgv1.StorageConfiguration{
Size: storageSize,
},
},
}
}
// newS3ClientDeployment returns a deployment running the AWS CLI configured to
// talk to the in-namespace minio service. The test execs `aws s3` commands in
// it to forge WAL segments on the object store and to check their presence.
func newS3ClientDeployment(namespace string) *appsv1.Deployment {
labels := map[string]string{"app": s3ClientName}
return &appsv1.Deployment{
TypeMeta: metav1.TypeMeta{
Kind: "Deployment",
APIVersion: "apps/v1",
},
ObjectMeta: metav1.ObjectMeta{
Name: s3ClientName,
Namespace: namespace,
},
Spec: appsv1.DeploymentSpec{
Replicas: ptr.To(int32(1)),
Selector: &metav1.LabelSelector{MatchLabels: labels},
Template: corev1.PodTemplateSpec{
ObjectMeta: metav1.ObjectMeta{Labels: labels},
Spec: corev1.PodSpec{
Containers: []corev1.Container{
{
Name: s3ClientName,
// renovate: datasource=docker depName=amazon/aws-cli versioning=docker
// Version: 2.36.32
Image: "docker.io/amazon/aws-cli@sha256:f630107e3eadb6479fa441631bbf50d15cf354a6ace85b6028bf6b3e5c69c605",
Command: []string{"sleep", "infinity"},
Env: []corev1.EnvVar{
{
Name: "AWS_ENDPOINT_URL",
Value: "http://" + minioName + ":9000",
},
{
Name: "AWS_ACCESS_KEY_ID",
ValueFrom: &corev1.EnvVarSource{
SecretKeyRef: &corev1.SecretKeySelector{
LocalObjectReference: corev1.LocalObjectReference{Name: minioName},
Key: "ACCESS_KEY_ID",
},
},
},
{
Name: "AWS_SECRET_ACCESS_KEY",
ValueFrom: &corev1.EnvVarSource{
SecretKeyRef: &corev1.SecretKeySelector{
LocalObjectReference: corev1.LocalObjectReference{Name: minioName},
Key: "ACCESS_SECRET_KEY",
},
},
},
{
Name: "AWS_DEFAULT_REGION",
Value: "us-east-1",
},
// The CRC-based default checksums introduced in AWS
// CLI 2.23 are not supported by every S3-compatible
// object store, minio included.
{
Name: "AWS_REQUEST_CHECKSUM_CALCULATION",
Value: "when_required",
},
{
Name: "AWS_RESPONSE_CHECKSUM_VALIDATION",
Value: "when_required",
},
},
SecurityContext: &corev1.SecurityContext{
AllowPrivilegeEscalation: ptr.To(false),
SeccompProfile: &corev1.SeccompProfile{
Type: corev1.SeccompProfileTypeRuntimeDefault,
},
},
},
},
},
},
},
}
}

View File

@ -0,0 +1,312 @@
/*
Copyright © contributors to CloudNativePG, established as
CloudNativePG a Series of LF Projects, LLC.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
SPDX-License-Identifier: Apache-2.0
*/
package walrestore
import (
"context"
"errors"
"fmt"
"strconv"
"strings"
"time"
corev1 "k8s.io/api/core/v1"
apitypes "k8s.io/apimachinery/pkg/types"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
executil "k8s.io/client-go/util/exec"
"sigs.k8s.io/controller-runtime/pkg/client"
internalClient "github.com/cloudnative-pg/plugin-barman-cloud/test/e2e/internal/client"
internalCluster "github.com/cloudnative-pg/plugin-barman-cloud/test/e2e/internal/cluster"
"github.com/cloudnative-pg/plugin-barman-cloud/test/e2e/internal/command"
"github.com/cloudnative-pg/plugin-barman-cloud/test/e2e/internal/deployment"
nmsp "github.com/cloudnative-pg/plugin-barman-cloud/test/e2e/internal/namespace"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)
const (
// spoolDirectory is where the plugin sidecar prefetches WAL segments and
// records the end-of-wal-stream sentinel. It must match the SPOOL_DIRECTORY
// the operator injects on the sidecar (internal/cnpgi/operator/lifecycle.go),
// which lives on the CloudNativePG scratch-data volume shared with the
// postgres container, so the path is visible from the postgres container too.
spoolDirectory = "/controller/wal-restore-spool"
// pgWalPath is PgDataPath + "/pg_wal" in the CloudNativePG operand image.
pgWalPath = "/var/lib/postgresql/data/pgdata/pg_wal"
// endOfWALStreamFlag is the sentinel file the barman-cloud restorer writes in
// the spool to record that the archive ran out of segments.
endOfWALStreamFlag = "end-of-wal-stream"
// managerExecutable is the CloudNativePG instance manager. Its wal-restore
// subcommand delegates to the plugin when the cluster uses it as WAL archiver.
managerExecutable = "/controller/manager"
// postgresContainer is the container we exec into on instance pods.
postgresContainer = "postgres"
// walLogDir is the WALs subdirectory (timeline + log id) the forged segments
// live under; a freshly bootstrapped, idle cluster stays within it.
walLogDir = "0000000100000000"
// bucket is the destination bucket of the minio ObjectStore.
bucket = "backups"
)
// walFile returns the name of the n-th forged WAL segment (segment 0xF0+n on
// timeline 1, log 0, for n <= 15). The high segment number keeps it out of the
// range an idle PostgreSQL would archive on its own.
func walFile(n int) string {
return fmt.Sprintf("0000000100000000%08X", 0xF0+n)
}
// walObjectURI returns the s3 URI of a wals object (by file name) in the store.
func walObjectURI(name string) string {
return fmt.Sprintf("s3://%s/%s/wals/%s/%s", bucket, clusterName, walLogDir, name)
}
// execInPod runs a command in the given container and returns stdout, stderr
// and the error (non-nil for a non-zero exit code).
func execInPod(
ctx context.Context,
clientSet *kubernetes.Clientset,
cfg *rest.Config,
namespace, pod, container string,
args ...string,
) (string, string, error) {
return command.ExecuteInContainer(
ctx,
*clientSet,
cfg,
command.ContainerLocator{
NamespaceName: namespace,
PodName: pod,
ContainerName: container,
},
nil,
args,
)
}
// This test drives the plugin's parallel WAL restore directly: it invokes the
// instance-manager wal-restore command on the standby (which delegates to the
// plugin) and asserts the prefetch/spool/end-of-wal-stream state machine with
// maxParallel = 3. To control the archive deterministically, it forges WAL
// segments on the object store by copying a real archived segment under new
// names.
var _ = Describe("Parallel WAL restore", func() {
var (
namespace *corev1.Namespace
cl client.Client
clientSet *kubernetes.Clientset
cfg *rest.Config
)
BeforeEach(func(ctx SpecContext) {
var err error
cl, _, err = internalClient.NewClient()
Expect(err).NotTo(HaveOccurred())
clientSet, cfg, err = internalClient.NewClientSet()
Expect(err).NotTo(HaveOccurred())
namespace, err = nmsp.CreateUniqueNamespace(ctx, cl, "wal-restore-parallel")
Expect(err).NotTo(HaveOccurred())
})
AfterEach(func(ctx SpecContext) {
Expect(cl.Delete(ctx, namespace)).To(Succeed())
})
It("prefetches segments, serves them from the spool and tracks end-of-wal-stream",
func(ctx SpecContext) {
ns := namespace.Name
By("creating the object store backing resources")
Expect(newObjectStoreResources(ns).Create(ctx, cl)).To(Succeed())
By("creating the ObjectStore with WAL maxParallel")
Expect(cl.Create(ctx, newObjectStore(ns))).To(Succeed())
By("deploying the S3 client used to forge and inspect WAL segments")
Expect(cl.Create(ctx, newS3ClientDeployment(ns))).To(Succeed())
By("creating the cluster using the plugin as WAL archiver")
cluster := newCluster(ns)
Expect(cl.Create(ctx, cluster)).To(Succeed())
By("waiting for the cluster to become ready")
Eventually(func(g Gomega) {
g.Expect(cl.Get(ctx,
apitypes.NamespacedName{Name: clusterName, Namespace: ns},
cluster)).To(Succeed())
g.Expect(internalCluster.IsReady(*cluster)).To(BeTrue())
}).WithTimeout(10 * time.Minute).WithPolling(10 * time.Second).Should(Succeed())
By("waiting for the S3 client to become ready")
Eventually(func(g Gomega) {
ready, err := deployment.IsReady(ctx, cl,
apitypes.NamespacedName{Name: s3ClientName, Namespace: ns})
g.Expect(err).NotTo(HaveOccurred())
g.Expect(ready).To(BeTrue())
}).WithTimeout(2 * time.Minute).WithPolling(5 * time.Second).Should(Succeed())
primary := cluster.Status.CurrentPrimary
Expect(primary).NotTo(BeEmpty())
standby := clusterName + "-2"
var s3ClientPods corev1.PodList
Expect(cl.List(ctx, &s3ClientPods,
client.InNamespace(ns),
client.MatchingLabels{"app": s3ClientName})).To(Succeed())
Expect(s3ClientPods.Items).NotTo(BeEmpty())
s3Client := s3ClientPods.Items[0].Name
// Operations scoped to the fixed pods/clients, kept as closures so the
// step assertions below read like the original state-machine table.
restore := func(name string) error {
_, _, err := execInPod(ctx, clientSet, cfg, ns, standby, postgresContainer,
managerExecutable, "wal-restore", name, pgWalPath+"/"+name)
return err
}
existsIn := func(dir, name string) bool {
_, _, err := execInPod(ctx, clientSet, cfg, ns, standby, postgresContainer,
"test", "-f", dir+"/"+name)
return err == nil
}
flagSet := func() bool { return existsIn(spoolDirectory, endOfWALStreamFlag) }
spoolSegments := func() int {
out, _, _ := execInPod(ctx, clientSet, cfg, ns, standby, postgresContainer,
"sh", "-c",
"ls -1 "+spoolDirectory+" 2>/dev/null | grep -Ec '^[0-9A-F]{24}$' || true")
n, _ := strconv.Atoi(strings.TrimSpace(out))
return n
}
purgeSpool := func() {
_, _, _ = execInPod(ctx, clientSet, cfg, ns, standby, postgresContainer,
"sh", "-c", "rm -f "+spoolDirectory+"/* 2>/dev/null; true")
}
forge := func(src, dst string) {
// ExecuteInContainer drops stdout/stderr on a non-zero exit, so on
// failure this only reports the exit code, not the aws CLI's error text.
_, _, err := execInPod(ctx, clientSet, cfg, ns, s3Client, s3ClientName,
"aws", "s3", "cp", walObjectURI(src), walObjectURI(dst))
Expect(err).NotTo(HaveOccurred(), "forging %s -> %s", src, dst)
}
objectExists := func(name string) bool {
out, _, err := execInPod(ctx, clientSet, cfg, ns, s3Client, s3ClientName,
"aws", "s3", "ls", walObjectURI(name))
return err == nil && strings.TrimSpace(out) != ""
}
By("archiving a real WAL on the primary and learning its name")
_, _, err := execInPod(ctx, clientSet, cfg, ns, primary, postgresContainer,
"psql", "-tAc", "CHECKPOINT")
Expect(err).NotTo(HaveOccurred(), "CHECKPOINT on the primary failed")
out, _, err := execInPod(ctx, clientSet, cfg, ns, primary, postgresContainer,
"psql", "-tAc", "SELECT pg_walfile_name(pg_switch_wal())")
Expect(err).NotTo(HaveOccurred(), "switching WAL on the primary failed")
latestWAL := strings.TrimSpace(out)
Expect(latestWAL).To(HavePrefix(walLogDir),
"the freshly bootstrapped cluster should still be on the first WAL log")
By("waiting for the archived WAL to land on the object store")
Eventually(func() bool {
return objectExists(latestWAL + ".gz")
}).WithTimeout(2 * time.Minute).WithPolling(5 * time.Second).Should(BeTrue())
By("forging WAL segments #1 to #5 from the archived WAL")
for n := 1; n <= 5; n++ {
forge(latestWAL+".gz", walFile(n))
}
By("ensuring the spool directory is empty on the standby")
purgeSpool()
// #1: served fresh; #2 and #3 prefetched into the spool; flag unset.
By("requesting WAL #1: #1 restored, #2 and #3 prefetched")
Expect(restore(walFile(1))).To(Succeed())
Eventually(func(g Gomega) {
g.Expect(existsIn(pgWalPath, walFile(1))).To(BeTrue(), "#1 in pg_wal")
g.Expect(existsIn(spoolDirectory, walFile(2))).To(BeTrue(), "#2 in spool")
g.Expect(existsIn(spoolDirectory, walFile(3))).To(BeTrue(), "#3 in spool")
g.Expect(flagSet()).To(BeFalse(), "end-of-wal-stream unset")
}).WithTimeout(time.Minute).WithPolling(2 * time.Second).Should(Succeed())
// #2: served from the spool; #3 stays prefetched; no new prefetch; flag unset.
By("requesting WAL #2: served from the spool, #3 still prefetched")
Expect(restore(walFile(2))).To(Succeed())
Eventually(func(g Gomega) {
g.Expect(existsIn(pgWalPath, walFile(2))).To(BeTrue(), "#2 in pg_wal")
g.Expect(existsIn(spoolDirectory, walFile(3))).To(BeTrue(), "#3 in spool")
g.Expect(flagSet()).To(BeFalse(), "end-of-wal-stream unset")
}).WithTimeout(time.Minute).WithPolling(2 * time.Second).Should(Succeed())
// #3: served from the spool; spool now empty; flag unset.
By("requesting WAL #3: served from the spool, spool now empty")
Expect(restore(walFile(3))).To(Succeed())
Eventually(func(g Gomega) {
g.Expect(existsIn(pgWalPath, walFile(3))).To(BeTrue(), "#3 in pg_wal")
g.Expect(spoolSegments()).To(Equal(0), "no WAL segments in spool")
g.Expect(flagSet()).To(BeFalse(), "end-of-wal-stream unset")
}).WithTimeout(time.Minute).WithPolling(2 * time.Second).Should(Succeed())
// #4: served fresh; #5 prefetched; #6 absent so end-of-wal-stream is set.
By("requesting WAL #4: #4 restored, #5 prefetched, end-of-wal-stream set")
Expect(restore(walFile(4))).To(Succeed())
Eventually(func(g Gomega) {
g.Expect(existsIn(pgWalPath, walFile(4))).To(BeTrue(), "#4 in pg_wal")
g.Expect(existsIn(spoolDirectory, walFile(5))).To(BeTrue(), "#5 in spool")
g.Expect(flagSet()).To(BeTrue(), "end-of-wal-stream set (#6 absent)")
}).WithTimeout(time.Minute).WithPolling(2 * time.Second).Should(Succeed())
By("forging WAL segment #6 on the object store")
forge(latestWAL+".gz", walFile(6))
// #5: served from the spool; flag untouched (served before it is checked).
By("requesting WAL #5: served from the spool, end-of-wal-stream still set")
Expect(restore(walFile(5))).To(Succeed())
Eventually(func(g Gomega) {
g.Expect(existsIn(pgWalPath, walFile(5))).To(BeTrue(), "#5 in pg_wal")
g.Expect(spoolSegments()).To(Equal(0), "no WAL segments in spool")
g.Expect(flagSet()).To(BeTrue(), "end-of-wal-stream still set")
}).WithTimeout(time.Minute).WithPolling(2 * time.Second).Should(Succeed())
// #6 (first): flag is set, so the request fails fast (exit 1) and the
// flag is consumed, leaving an empty spool.
By("requesting WAL #6: fails fast on the end-of-wal-stream flag, spool cleared")
restoreErr := restore(walFile(6))
var exitErr executil.CodeExitError
Expect(errors.As(restoreErr, &exitErr)).To(BeTrue(),
"expected a CodeExitError, got %T: %v", restoreErr, restoreErr)
Expect(exitErr.ExitStatus()).To(Equal(1), "exit code should be 1")
Eventually(func(g Gomega) {
g.Expect(existsIn(pgWalPath, walFile(6))).To(BeFalse(), "#6 not restored")
g.Expect(spoolSegments()).To(Equal(0), "no WAL segments in spool")
g.Expect(flagSet()).To(BeFalse(), "end-of-wal-stream consumed")
}).WithTimeout(time.Minute).WithPolling(2 * time.Second).Should(Succeed())
// #6 (second): now present, restored; #7 and #8 absent so the flag is
// set again.
By("requesting WAL #6 again: #6 restored, end-of-wal-stream set again")
Expect(restore(walFile(6))).To(Succeed())
Eventually(func(g Gomega) {
g.Expect(existsIn(pgWalPath, walFile(6))).To(BeTrue(), "#6 in pg_wal")
g.Expect(spoolSegments()).To(Equal(0), "no WAL segments in spool")
g.Expect(flagSet()).To(BeTrue(), "end-of-wal-stream set (#7/#8 absent)")
}).WithTimeout(time.Minute).WithPolling(2 * time.Second).Should(Succeed())
})
})

View File

@ -35,7 +35,7 @@ object storage system. It allows you to configure:
- **Base backup options**—with similar settings for compression, concurrency, - **Base backup options**—with similar settings for compression, concurrency,
and encryption—under `.spec.configuration.data` and encryption—under `.spec.configuration.data`
- **Retention policies** to manage the life-cycle of archived WALs and backups - **Retention policies** to manage the life-cycle of archived WALs and backups
via `.spec.configuration.retentionPolicy` via `.spec.retentionPolicy`
WAL files are archived in the `wals` directory, while base backups are stored WAL files are archived in the `wals` directory, while base backups are stored
as **tarballs** in the `base` directory, following the as **tarballs** in the `base` directory, following the
@ -43,7 +43,7 @@ as **tarballs** in the `base` directory, following the
The plugin also offers advanced capabilities, including The plugin also offers advanced capabilities, including
[backup tagging](misc.md#backup-object-tagging) and [backup tagging](misc.md#backup-object-tagging) and
[extra options for backups and WAL archiving](misc.md#extra-options-for-backup-and-wal-archiving). [extra options for backups and WAL archiving](misc.md#extra-options-for-backup-wal-archiving-and-restore).
:::tip :::tip
For details, refer to the For details, refer to the

View File

@ -54,10 +54,49 @@ Both checks are required before proceeding with the installation.
## Installing the Barman Cloud Plugin ## Installing the Barman Cloud Plugin
import { InstallationSnippet } from '@site/src/components/Installation'; import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
import { InstallationSnippet, ManifestVersion } from '@site/src/components/Installation';
import { HelmInstallationSnippet } from '@site/src/components/HelmInstallation';
Install the plugin using `kubectl` by applying the manifest for the latest <Tabs groupId="install-method" queryString>
release: <TabItem value="helm" label="Helm Chart" default>
The plugin can be installed using the provided [Helm chart](https://github.com/cloudnative-pg/charts/tree/main/charts/plugin-barman-cloud).
This installs the latest published chart release; to test an unreleased
development snapshot instead, switch to the [**Manifest (kubectl)**](./?install-method=kubectl#installing-the-barman-cloud-plugin) tab.
<HelmInstallationSnippet />
Example output:
```output
Release "plugin-barman-cloud" does not exist. Installing it now.
NAME: plugin-barman-cloud
LAST DEPLOYED: Wed Jul 1 09:05:16 2026
NAMESPACE: cnpg-system
STATUS: deployed
REVISION: 1
DESCRIPTION: Install complete
TEST SUITE: None
```
Finally, check that the deployment is up and running:
```sh
kubectl -n cnpg-system rollout status deploy/plugin-barman-cloud
```
Example output:
```output
deployment "plugin-barman-cloud" successfully rolled out
```
</TabItem>
<TabItem value="kubectl" label="Manifest (kubectl)">
Install the plugin using `kubectl` by applying the manifest for <ManifestVersion />:
<InstallationSnippet /> <InstallationSnippet />
@ -86,8 +125,7 @@ issuer.cert-manager.io/selfsigned-issuer created
Finally, check that the deployment is up and running: Finally, check that the deployment is up and running:
```sh ```sh
kubectl rollout status deployment \ kubectl -n cnpg-system rollout status deploy/barman-cloud
-n cnpg-system barman-cloud
``` ```
Example output: Example output:
@ -96,14 +134,15 @@ Example output:
deployment "barman-cloud" successfully rolled out deployment "barman-cloud" successfully rolled out
``` ```
</TabItem>
</Tabs>
---
This confirms that the plugin is deployed and ready to use. This confirms that the plugin is deployed and ready to use.
## Testing the latest development snapshot ## Testing the latest development snapshot
You can also test the latest development snapshot of the plugin with the import { DevSnapshotSection } from '@site/src/components/Installation';
following command:
```sh <DevSnapshotSection />
kubectl apply -f \
https://raw.githubusercontent.com/cloudnative-pg/plugin-barman-cloud/refs/heads/main/manifest.yaml
```

View File

@ -32,17 +32,20 @@ spec:
[...] [...]
``` ```
## Extra Options for Backup and WAL Archiving ## Extra Options for Backup, WAL Archiving, and Restore
You can pass additional command-line arguments to `barman-cloud-backup` and You can pass additional command-line arguments to the underlying
`barman-cloud-wal-archive` using the `additionalCommandArgs` field in the `barman-cloud-*` commands using the corresponding fields in the `ObjectStore`
`ObjectStore` configuration. configuration.
- `.spec.configuration.data.additionalCommandArgs`: for `barman-cloud-backup` - `.spec.configuration.data.additionalCommandArgs`: for `barman-cloud-backup`
- `.spec.configuration.data.restoreAdditionalCommandArgs`: for `barman-cloud-restore`
- `.spec.configuration.wal.archiveAdditionalCommandArgs`: for `barman-cloud-wal-archive` - `.spec.configuration.wal.archiveAdditionalCommandArgs`: for `barman-cloud-wal-archive`
- `.spec.configuration.wal.restoreAdditionalCommandArgs`: for `barman-cloud-wal-restore`
Each field accepts a list of string arguments. If an argument is already Each field accepts a list of string arguments. If an argument conflicts with
configured elsewhere in the plugin, the duplicate will be ignored. one already set by the plugin, the user-provided value will be ignored. These
fields are intended to pass options the plugin does not configure automatically.
### Example: Extra Backup Options ### Example: Extra Backup Options
@ -58,6 +61,19 @@ spec:
- "--read-timeout=60" - "--read-timeout=60"
``` ```
### Example: Extra Restore Options
```yaml
kind: ObjectStore
metadata:
name: my-store
spec:
configuration:
data:
restoreAdditionalCommandArgs:
- "--read-timeout=900"
```
### Example: Extra WAL Archive Options ### Example: Extra WAL Archive Options
```yaml ```yaml
@ -72,6 +88,19 @@ spec:
- "--read-timeout=60" - "--read-timeout=60"
``` ```
### Example: Extra WAL Restore Options
```yaml
kind: ObjectStore
metadata:
name: my-store
spec:
configuration:
wal:
restoreAdditionalCommandArgs:
- "--read-timeout=60"
```
For a complete list of supported options, refer to the For a complete list of supported options, refer to the
[official Barman Cloud documentation](https://docs.pgbarman.org/release/latest/). [official Barman Cloud documentation](https://docs.pgbarman.org/release/latest/).

View File

@ -485,14 +485,10 @@ If problems persist:
### Plugin Limitations ### Plugin Limitations
1. **Installation method**: Currently only supports manifest and Kustomize 1. **Sidecar resource sharing**: The plugin sidecar container shares pod
installation ([#351](https://github.com/cloudnative-pg/plugin-barman-cloud/issues/351) -
Helm chart requested)
2. **Sidecar resource sharing**: The plugin sidecar container shares pod
resources with PostgreSQL resources with PostgreSQL
3. **Plugin restart behavior**: Restarting the sidecar container requires 2. **Plugin restart behavior**: Restarting the sidecar container requires
restarting the entire PostgreSQL pod restarting the entire PostgreSQL pod
## Recap of General Debugging Steps ## Recap of General Debugging Steps
@ -588,4 +584,3 @@ kubectl get secret -n <namespace> <secret-name> -o jsonpath='{.data}' | jq 'keys
* **"NoSuchBucket"** — Verify the bucket exists and the endpoint URL is correct. * **"NoSuchBucket"** — Verify the bucket exists and the endpoint URL is correct.
* **"Connection timeout"** — Check network connectivity and firewall rules. * **"Connection timeout"** — Check network connectivity and firewall rules.
* **"SSL certificate problem"** — For self-signed certificates, verify the CA bundle configuration. * **"SSL certificate problem"** — For self-signed certificates, verify the CA bundle configuration.

View File

@ -21,7 +21,12 @@ const config: Config = {
deploymentBranch: 'gh-pages', deploymentBranch: 'gh-pages',
onBrokenLinks: 'throw', onBrokenLinks: 'throw',
markdown: {
hooks: {
onBrokenMarkdownLinks: 'throw', onBrokenMarkdownLinks: 'throw',
},
},
// Even if you don't use internationalization, you can use this field to set // Even if you don't use internationalization, you can use this field to set
// useful metadata like html lang. For example, if your site is Chinese, you // useful metadata like html lang. For example, if your site is Chinese, you

View File

@ -15,8 +15,8 @@
"typecheck": "tsc" "typecheck": "tsc"
}, },
"dependencies": { "dependencies": {
"@docusaurus/core": "3.10.1", "@docusaurus/core": "3.10.2",
"@docusaurus/preset-classic": "3.10.1", "@docusaurus/preset-classic": "3.10.2",
"@easyops-cn/docusaurus-search-local": "^0.55.0", "@easyops-cn/docusaurus-search-local": "^0.55.0",
"@mdx-js/react": "^3.0.0", "@mdx-js/react": "^3.0.0",
"clsx": "^2.0.0", "clsx": "^2.0.0",
@ -25,10 +25,10 @@
"react-dom": "^19.0.0" "react-dom": "^19.0.0"
}, },
"devDependencies": { "devDependencies": {
"@docusaurus/module-type-aliases": "3.10.1", "@docusaurus/module-type-aliases": "3.10.2",
"@docusaurus/tsconfig": "3.10.1", "@docusaurus/tsconfig": "3.10.2",
"@docusaurus/types": "3.10.1", "@docusaurus/types": "3.10.2",
"typescript": "~6.0.0" "typescript": "~7.0.0"
}, },
"browserslist": { "browserslist": {
"production": [ "production": [
@ -47,6 +47,7 @@
}, },
"resolutions": { "resolutions": {
"webpackbar": "^7.0.0", "webpackbar": "^7.0.0",
"serialize-javascript": ">=7.0.5" "serialize-javascript": ">=7.0.5",
"uuid": ">=11.1.1"
} }
} }

View File

@ -0,0 +1,36 @@
import {ReactElement} from 'react';
import CodeBlock from '@theme/CodeBlock';
import {useActiveVersion, useLatestVersion} from '@docusaurus/plugin-content-docs/client';
// HelmInstallationSnippet is the Helm command to install the plugin.
//
// - Latest release: no override. The chart already defaults to
// itself.
// - Older release: pin image.tag and sidecarImage.tag to that
// version. We check this again on every build using
// useLatestVersion, so an old page updates itself once a newer
// version ships.
// - Dev docs: also no override, but this does NOT install a dev
// build. Setting the tag alone would not be enough, since the
// chart's own templates (CRDs, RBAC...) can be older than what
// main needs. Use the kubectl method to test a dev build.
export function HelmInstallationSnippet(): ReactElement<null> {
const activeVersion = useActiveVersion('default');
const latestVersion = useLatestVersion('default');
const isOlderRelease = activeVersion
&& activeVersion.name !== 'current'
&& activeVersion.name !== latestVersion.name;
const setArgs = isOlderRelease
? ` \\
--set image.tag=v${activeVersion.name} \\
--set sidecarImage.tag=v${activeVersion.name}`
: '';
return (
<CodeBlock language="sh">
{`helm repo add cnpg https://cloudnative-pg.github.io/charts --force-update
helm upgrade --install plugin-barman-cloud \\
--namespace cnpg-system${setArgs} \\
cnpg/plugin-barman-cloud`}
</CodeBlock>
);
}

View File

@ -1,16 +1,60 @@
import {ReactElement} from 'react'; import {ReactElement} from 'react';
import CodeBlock from '@theme/CodeBlock'; import CodeBlock from '@theme/CodeBlock';
import {useCurrentVersion} from '@site/src/hooks/versions'; import Link from '@docusaurus/Link';
import {useLocation} from '@docusaurus/router';
import {useActiveVersion} from '@docusaurus/plugin-content-docs/client';
// InstallationSnippet is the kubectl incantation to install the lastest // DEV_MANIFEST_URL is the URL of the manifest.yaml on the main branch of the plugin repo.
// available version of the Barman Cloud Plugin. const DEV_MANIFEST_URL =
'https://raw.githubusercontent.com/cloudnative-pg/plugin-barman-cloud/refs/heads/main/manifest.yaml';
// InstallationSnippet is the kubectl incantation to install the Barman
// Cloud Plugin: the manifest matching the doc version being viewed, or
// (on the unreleased "current" docs) the latest manifest on main.
export function InstallationSnippet(): ReactElement<null> { export function InstallationSnippet(): ReactElement<null> {
const latest = useCurrentVersion('latestReleased'); const activeVersion = useActiveVersion('default');
const url = activeVersion && activeVersion.name !== 'current'
? `https://github.com/cloudnative-pg/plugin-barman-cloud/releases/download/v${activeVersion.name}/manifest.yaml`
: DEV_MANIFEST_URL;
return ( return (
<CodeBlock language="sh"> <CodeBlock language="sh">
{`kubectl apply -f \\ {`kubectl apply -f \\
https://github.com/cloudnative-pg/plugin-barman-cloud/releases/download/v${latest}/manifest.yaml`} ${url}`}
</CodeBlock> </CodeBlock>
); );
} }
// ManifestVersion names the manifest the snippet below installs: the
// release tag for a versioned docs page, or the main branch on Dev docs.
export function ManifestVersion(): ReactElement<null> {
const activeVersion = useActiveVersion('default');
return activeVersion && activeVersion.name !== 'current'
? <code>v{activeVersion.name}</code>
: <>the latest development snapshot from the <code>main</code> branch</>;
}
// DevSnapshotSection shows how to test the main-branch manifest. On
// the Dev docs, the kubectl install above already does that, so we
// hide this section there. (The Helm tab there installs the latest
// release, not a dev build.)
export function DevSnapshotSection(): ReactElement {
const activeVersion = useActiveVersion('default');
const {pathname} = useLocation();
if (!activeVersion || activeVersion.name === 'current') {
return (
<p>The <Link to={`${pathname}?install-method=kubectl#installing-the-barman-cloud-plugin`}>kubectl
install command above</Link> already applies the latest development
snapshot from the <code>main</code> branch.</p>
);
}
return (
<>
<p>You can also test the latest development snapshot of the plugin
with the following command:</p>
<CodeBlock language="sh">
{`kubectl apply -f \\
${DEV_MANIFEST_URL}`}
</CodeBlock>
</>
);
}

View File

@ -1,36 +0,0 @@
import {useActiveVersion, useLatestVersion, useVersions} from '@docusaurus/plugin-content-docs/client';
export function useCurrentVersion(fallback: 'latest' | 'latestReleased' = 'latest'): string {
switch (fallback) {
case 'latestReleased':
return useLatestReleasedVersion();
case 'latest': {
const version = useActiveVersion('default');
return version?.name ?? useLatestVersion('default')?.name;
}
default:
// The following line ensures that if `fallback` is not 'latest' or 'latestReleased',
// an error is thrown. This can be useful for catching unexpected states.
throw new Error(`Unhandled fallback type: ${fallback}`);
}
}
export function useLatestReleasedVersion(): string {
const allVersions = useVersions('default');
// Filter out "current" to only consider versioned docs
const versionedDocs = allVersions.filter(version => version.name !== 'current');
// Handle the case where no versioned documents are found
if (versionedDocs.length === 0) {
return "unknown_version";
}
const sortedVersions = versionedDocs.sort((a, b) => {
return b.name.localeCompare(a.name, undefined, { numeric: true, sensitivity: 'base' });
});
// The latest version is the first in the sorted list since versionedDocs was not empty,
return sortedVersions[0].name;
}

View File

@ -1,109 +0,0 @@
---
sidebar_position: 20
---
# Installation
:::important
1. The plugin **must** be installed in the same namespace as the CloudNativePG
operator (typically `cnpg-system`).
2. Keep in mind that the operator's **listening namespaces** may differ from its
installation namespace. Double-check this to avoid configuration issues.
:::
## Verifying the Requirements
Before installing the plugin, make sure the [requirements](intro.md#requirements) are met.
### CloudNativePG Version
Ensure you're running a version of CloudNativePG that is compatible with the
plugin. If installed in the default `cnpg-system` namespace, you can verify the
version with:
```sh
kubectl get deployment -n cnpg-system cnpg-controller-manager \
-o jsonpath="{.spec.template.spec.containers[*].image}"
```
Example output:
```output
ghcr.io/cloudnative-pg/cloudnative-pg:1.26.0
```
The version **must be 1.26 or newer**.
### cert-manager
Use the [cmctl](https://cert-manager.io/docs/reference/cmctl/#installation)
tool to confirm that `cert-manager` is installed and available:
```sh
cmctl check api
```
Example output:
```output
The cert-manager API is ready
```
Both checks are required before proceeding with the installation.
## Installing the Barman Cloud Plugin
import { InstallationSnippet } from '@site/src/components/Installation';
Install the plugin using `kubectl` by applying the manifest for the latest
release:
<InstallationSnippet />
Example output:
```output
customresourcedefinition.apiextensions.k8s.io/objectstores.barmancloud.cnpg.io created
serviceaccount/plugin-barman-cloud created
role.rbac.authorization.k8s.io/leader-election-role created
clusterrole.rbac.authorization.k8s.io/metrics-auth-role created
clusterrole.rbac.authorization.k8s.io/metrics-reader created
clusterrole.rbac.authorization.k8s.io/objectstore-editor-role created
clusterrole.rbac.authorization.k8s.io/objectstore-viewer-role created
clusterrole.rbac.authorization.k8s.io/plugin-barman-cloud created
rolebinding.rbac.authorization.k8s.io/leader-election-rolebinding created
clusterrolebinding.rbac.authorization.k8s.io/metrics-auth-rolebinding created
clusterrolebinding.rbac.authorization.k8s.io/plugin-barman-cloud-binding created
secret/plugin-barman-cloud-8tfddg42gf created
service/barman-cloud created
deployment.apps/barman-cloud configured
certificate.cert-manager.io/barman-cloud-client created
certificate.cert-manager.io/barman-cloud-server created
issuer.cert-manager.io/selfsigned-issuer created
```
Finally, check that the deployment is up and running:
```sh
kubectl rollout status deployment \
-n cnpg-system barman-cloud
```
Example output:
```output
deployment "barman-cloud" successfully rolled out
```
This confirms that the plugin is deployed and ready to use.
## Testing the latest development snapshot
You can also test the latest development snapshot of the plugin with the
following command:
```sh
kubectl apply -f \
https://raw.githubusercontent.com/cloudnative-pg/plugin-barman-cloud/refs/heads/main/manifest.yaml
```

View File

@ -15,7 +15,7 @@ for space, speed, or a balance of both.
- `bzip2` - `bzip2`
- `gzip` - `gzip`
- `lz4` (WAL only) - `lz4`
- `snappy` - `snappy`
- `xz` (WAL only) - `xz` (WAL only)
- `zstd` (WAL only) - `zstd` (WAL only)
@ -41,3 +41,5 @@ network throughput.
| bzip2 | 25,404 | 13,886 | 395 | 67 | 5.9:1 | | bzip2 | 25,404 | 13,886 | 395 | 67 | 5.9:1 |
| gzip | 116,281 | 3,077 | 395 | 91 | 4.3:1 | | gzip | 116,281 | 3,077 | 395 | 91 | 4.3:1 |
| snappy | 8,134 | 8,341 | 395 | 166 | 2.4:1 | | snappy | 8,134 | 8,341 | 395 | 166 | 2.4:1 |
Numbers come from a 2021 Barman proof of concept ([EnterpriseDB/barman#344](https://github.com/EnterpriseDB/barman/issues/344#issuecomment-992547396)), which predates `lz4` support for base backups. `lz4` is not yet benchmarked.

View File

@ -43,7 +43,7 @@ as **tarballs** in the `base` directory, following the
The plugin also offers advanced capabilities, including The plugin also offers advanced capabilities, including
[backup tagging](misc.md#backup-object-tagging) and [backup tagging](misc.md#backup-object-tagging) and
[extra options for backups and WAL archiving](misc.md#extra-options-for-backup-and-wal-archiving). [extra options for backups and WAL archiving](misc.md#extra-options-for-backup-wal-archiving-and-restore).
:::tip :::tip
For details, refer to the For details, refer to the

View File

@ -54,10 +54,47 @@ Both checks are required before proceeding with the installation.
## Installing the Barman Cloud Plugin ## Installing the Barman Cloud Plugin
import { InstallationSnippet } from '@site/src/components/Installation'; import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
import { InstallationSnippet, ManifestVersion } from '@site/src/components/Installation';
import { HelmInstallationSnippet } from '@site/src/components/HelmInstallation';
Install the plugin using `kubectl` by applying the manifest for the latest <Tabs groupId="install-method">
release: <TabItem value="helm" label="Helm Chart" default>
The plugin can be installed using the provided [Helm chart](https://github.com/cloudnative-pg/charts/tree/main/charts/plugin-barman-cloud):
<HelmInstallationSnippet />
Example output:
```output
Release "plugin-barman-cloud" does not exist. Installing it now.
NAME: plugin-barman-cloud
LAST DEPLOYED: Wed Jul 1 09:05:16 2026
NAMESPACE: cnpg-system
STATUS: deployed
REVISION: 1
DESCRIPTION: Install complete
TEST SUITE: None
```
Finally, check that the deployment is up and running:
```sh
kubectl -n cnpg-system rollout status deploy/plugin-barman-cloud
```
Example output:
```output
deployment "plugin-barman-cloud" successfully rolled out
```
</TabItem>
<TabItem value="kubectl" label="Manifest (kubectl)">
Install the plugin using `kubectl` by applying the manifest for <ManifestVersion />:
<InstallationSnippet /> <InstallationSnippet />
@ -86,8 +123,7 @@ issuer.cert-manager.io/selfsigned-issuer created
Finally, check that the deployment is up and running: Finally, check that the deployment is up and running:
```sh ```sh
kubectl rollout status deployment \ kubectl -n cnpg-system rollout status deploy/barman-cloud
-n cnpg-system barman-cloud
``` ```
Example output: Example output:
@ -96,14 +132,15 @@ Example output:
deployment "barman-cloud" successfully rolled out deployment "barman-cloud" successfully rolled out
``` ```
</TabItem>
</Tabs>
---
This confirms that the plugin is deployed and ready to use. This confirms that the plugin is deployed and ready to use.
## Testing the latest development snapshot ## Testing the latest development snapshot
You can also test the latest development snapshot of the plugin with the import { DevSnapshotSection } from '@site/src/components/Installation';
following command:
```sh <DevSnapshotSection />
kubectl apply -f \
https://raw.githubusercontent.com/cloudnative-pg/plugin-barman-cloud/refs/heads/main/manifest.yaml
```

View File

@ -32,17 +32,20 @@ spec:
[...] [...]
``` ```
## Extra Options for Backup and WAL Archiving ## Extra Options for Backup, WAL Archiving, and Restore
You can pass additional command-line arguments to `barman-cloud-backup` and You can pass additional command-line arguments to the underlying
`barman-cloud-wal-archive` using the `additionalCommandArgs` field in the `barman-cloud-*` commands using the corresponding fields in the `ObjectStore`
`ObjectStore` configuration. configuration.
- `.spec.configuration.data.additionalCommandArgs`: for `barman-cloud-backup` - `.spec.configuration.data.additionalCommandArgs`: for `barman-cloud-backup`
- `.spec.configuration.data.restoreAdditionalCommandArgs`: for `barman-cloud-restore`
- `.spec.configuration.wal.archiveAdditionalCommandArgs`: for `barman-cloud-wal-archive` - `.spec.configuration.wal.archiveAdditionalCommandArgs`: for `barman-cloud-wal-archive`
- `.spec.configuration.wal.restoreAdditionalCommandArgs`: for `barman-cloud-wal-restore`
Each field accepts a list of string arguments. If an argument is already Each field accepts a list of string arguments. If an argument conflicts with
configured elsewhere in the plugin, the duplicate will be ignored. one already set by the plugin, the user-provided value will be ignored. These
fields are intended to pass options the plugin does not configure automatically.
### Example: Extra Backup Options ### Example: Extra Backup Options
@ -58,6 +61,19 @@ spec:
- "--read-timeout=60" - "--read-timeout=60"
``` ```
### Example: Extra Restore Options
```yaml
kind: ObjectStore
metadata:
name: my-store
spec:
configuration:
data:
restoreAdditionalCommandArgs:
- "--read-timeout=900"
```
### Example: Extra WAL Archive Options ### Example: Extra WAL Archive Options
```yaml ```yaml
@ -72,6 +88,19 @@ spec:
- "--read-timeout=60" - "--read-timeout=60"
``` ```
### Example: Extra WAL Restore Options
```yaml
kind: ObjectStore
metadata:
name: my-store
spec:
configuration:
wal:
restoreAdditionalCommandArgs:
- "--read-timeout=60"
```
For a complete list of supported options, refer to the For a complete list of supported options, refer to the
[official Barman Cloud documentation](https://docs.pgbarman.org/release/latest/). [official Barman Cloud documentation](https://docs.pgbarman.org/release/latest/).

View File

@ -485,14 +485,10 @@ If problems persist:
### Plugin Limitations ### Plugin Limitations
1. **Installation method**: Currently only supports manifest and Kustomize 1. **Sidecar resource sharing**: The plugin sidecar container shares pod
installation ([#351](https://github.com/cloudnative-pg/plugin-barman-cloud/issues/351) -
Helm chart requested)
2. **Sidecar resource sharing**: The plugin sidecar container shares pod
resources with PostgreSQL resources with PostgreSQL
3. **Plugin restart behavior**: Restarting the sidecar container requires 2. **Plugin restart behavior**: Restarting the sidecar container requires
restarting the entire PostgreSQL pod restarting the entire PostgreSQL pod
## Recap of General Debugging Steps ## Recap of General Debugging Steps
@ -588,4 +584,3 @@ kubectl get secret -n <namespace> <secret-name> -o jsonpath='{.data}' | jq 'keys
* **"NoSuchBucket"** — Verify the bucket exists and the endpoint URL is correct. * **"NoSuchBucket"** — Verify the bucket exists and the endpoint URL is correct.
* **"Connection timeout"** — Check network connectivity and firewall rules. * **"Connection timeout"** — Check network connectivity and firewall rules.
* **"SSL certificate problem"** — For self-signed certificates, verify the CA bundle configuration. * **"SSL certificate problem"** — For self-signed certificates, verify the CA bundle configuration.

View File

@ -15,7 +15,7 @@ for space, speed, or a balance of both.
- `bzip2` - `bzip2`
- `gzip` - `gzip`
- `lz4` (WAL only) - `lz4`
- `snappy` - `snappy`
- `xz` (WAL only) - `xz` (WAL only)
- `zstd` (WAL only) - `zstd` (WAL only)
@ -41,3 +41,5 @@ network throughput.
| bzip2 | 25,404 | 13,886 | 395 | 67 | 5.9:1 | | bzip2 | 25,404 | 13,886 | 395 | 67 | 5.9:1 |
| gzip | 116,281 | 3,077 | 395 | 91 | 4.3:1 | | gzip | 116,281 | 3,077 | 395 | 91 | 4.3:1 |
| snappy | 8,134 | 8,341 | 395 | 166 | 2.4:1 | | snappy | 8,134 | 8,341 | 395 | 166 | 2.4:1 |
Numbers come from a 2021 Barman proof of concept ([EnterpriseDB/barman#344](https://github.com/EnterpriseDB/barman/issues/344#issuecomment-992547396)), which predates `lz4` support for base backups. `lz4` is not yet benchmarked.

View File

@ -43,7 +43,7 @@ as **tarballs** in the `base` directory, following the
The plugin also offers advanced capabilities, including The plugin also offers advanced capabilities, including
[backup tagging](misc.md#backup-object-tagging) and [backup tagging](misc.md#backup-object-tagging) and
[extra options for backups and WAL archiving](misc.md#extra-options-for-backup-and-wal-archiving). [extra options for backups and WAL archiving](misc.md#extra-options-for-backup-wal-archiving-and-restore).
:::tip :::tip
For details, refer to the For details, refer to the

View File

@ -54,10 +54,47 @@ Both checks are required before proceeding with the installation.
## Installing the Barman Cloud Plugin ## Installing the Barman Cloud Plugin
import { InstallationSnippet } from '@site/src/components/Installation'; import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
import { InstallationSnippet, ManifestVersion } from '@site/src/components/Installation';
import { HelmInstallationSnippet } from '@site/src/components/HelmInstallation';
Install the plugin using `kubectl` by applying the manifest for the latest <Tabs groupId="install-method">
release: <TabItem value="helm" label="Helm Chart" default>
The plugin can be installed using the provided [Helm chart](https://github.com/cloudnative-pg/charts/tree/main/charts/plugin-barman-cloud):
<HelmInstallationSnippet />
Example output:
```output
Release "plugin-barman-cloud" does not exist. Installing it now.
NAME: plugin-barman-cloud
LAST DEPLOYED: Wed Jul 1 09:05:16 2026
NAMESPACE: cnpg-system
STATUS: deployed
REVISION: 1
DESCRIPTION: Install complete
TEST SUITE: None
```
Finally, check that the deployment is up and running:
```sh
kubectl -n cnpg-system rollout status deploy/plugin-barman-cloud
```
Example output:
```output
deployment "plugin-barman-cloud" successfully rolled out
```
</TabItem>
<TabItem value="kubectl" label="Manifest (kubectl)">
Install the plugin using `kubectl` by applying the manifest for <ManifestVersion />:
<InstallationSnippet /> <InstallationSnippet />
@ -86,8 +123,7 @@ issuer.cert-manager.io/selfsigned-issuer created
Finally, check that the deployment is up and running: Finally, check that the deployment is up and running:
```sh ```sh
kubectl rollout status deployment \ kubectl -n cnpg-system rollout status deploy/barman-cloud
-n cnpg-system barman-cloud
``` ```
Example output: Example output:
@ -96,14 +132,13 @@ Example output:
deployment "barman-cloud" successfully rolled out deployment "barman-cloud" successfully rolled out
``` ```
</TabItem>
</Tabs>
This confirms that the plugin is deployed and ready to use. This confirms that the plugin is deployed and ready to use.
## Testing the latest development snapshot ## Testing the latest development snapshot
You can also test the latest development snapshot of the plugin with the import { DevSnapshotSection } from '@site/src/components/Installation';
following command:
```sh <DevSnapshotSection />
kubectl apply -f \
https://raw.githubusercontent.com/cloudnative-pg/plugin-barman-cloud/refs/heads/main/manifest.yaml
```

View File

@ -32,17 +32,20 @@ spec:
[...] [...]
``` ```
## Extra Options for Backup and WAL Archiving ## Extra Options for Backup, WAL Archiving, and Restore
You can pass additional command-line arguments to `barman-cloud-backup` and You can pass additional command-line arguments to the underlying
`barman-cloud-wal-archive` using the `additionalCommandArgs` field in the `barman-cloud-*` commands using the corresponding fields in the `ObjectStore`
`ObjectStore` configuration. configuration.
- `.spec.configuration.data.additionalCommandArgs`: for `barman-cloud-backup` - `.spec.configuration.data.additionalCommandArgs`: for `barman-cloud-backup`
- `.spec.configuration.data.restoreAdditionalCommandArgs`: for `barman-cloud-restore`
- `.spec.configuration.wal.archiveAdditionalCommandArgs`: for `barman-cloud-wal-archive` - `.spec.configuration.wal.archiveAdditionalCommandArgs`: for `barman-cloud-wal-archive`
- `.spec.configuration.wal.restoreAdditionalCommandArgs`: for `barman-cloud-wal-restore`
Each field accepts a list of string arguments. If an argument is already Each field accepts a list of string arguments. If an argument conflicts with
configured elsewhere in the plugin, the duplicate will be ignored. one already set by the plugin, the user-provided value will be ignored. These
fields are intended to pass options the plugin does not configure automatically.
### Example: Extra Backup Options ### Example: Extra Backup Options
@ -58,6 +61,19 @@ spec:
- "--read-timeout=60" - "--read-timeout=60"
``` ```
### Example: Extra Restore Options
```yaml
kind: ObjectStore
metadata:
name: my-store
spec:
configuration:
data:
restoreAdditionalCommandArgs:
- "--read-timeout=900"
```
### Example: Extra WAL Archive Options ### Example: Extra WAL Archive Options
```yaml ```yaml
@ -72,6 +88,19 @@ spec:
- "--read-timeout=60" - "--read-timeout=60"
``` ```
### Example: Extra WAL Restore Options
```yaml
kind: ObjectStore
metadata:
name: my-store
spec:
configuration:
wal:
restoreAdditionalCommandArgs:
- "--read-timeout=60"
```
For a complete list of supported options, refer to the For a complete list of supported options, refer to the
[official Barman Cloud documentation](https://docs.pgbarman.org/release/latest/). [official Barman Cloud documentation](https://docs.pgbarman.org/release/latest/).

View File

@ -129,7 +129,6 @@ These strategies help you safeguard backups without requiring broad delete
permissions, ensuring both security and compliance with minimal operational permissions, ensuring both security and compliance with minimal operational
overhead. overhead.
### S3-Compatible Storage Providers ### S3-Compatible Storage Providers
You can use S3-compatible services like **MinIO**, **Linode (Akamai) Object Storage**, You can use S3-compatible services like **MinIO**, **Linode (Akamai) Object Storage**,

View File

@ -485,14 +485,10 @@ If problems persist:
### Plugin Limitations ### Plugin Limitations
1. **Installation method**: Currently only supports manifest and Kustomize 1. **Sidecar resource sharing**: The plugin sidecar container shares pod
installation ([#351](https://github.com/cloudnative-pg/plugin-barman-cloud/issues/351) -
Helm chart requested)
2. **Sidecar resource sharing**: The plugin sidecar container shares pod
resources with PostgreSQL resources with PostgreSQL
3. **Plugin restart behavior**: Restarting the sidecar container requires 2. **Plugin restart behavior**: Restarting the sidecar container requires
restarting the entire PostgreSQL pod restarting the entire PostgreSQL pod
## Recap of General Debugging Steps ## Recap of General Debugging Steps
@ -588,4 +584,3 @@ kubectl get secret -n <namespace> <secret-name> -o jsonpath='{.data}' | jq 'keys
* **"NoSuchBucket"** — Verify the bucket exists and the endpoint URL is correct. * **"NoSuchBucket"** — Verify the bucket exists and the endpoint URL is correct.
* **"Connection timeout"** — Check network connectivity and firewall rules. * **"Connection timeout"** — Check network connectivity and firewall rules.
* **"SSL certificate problem"** — For self-signed certificates, verify the CA bundle configuration. * **"SSL certificate problem"** — For self-signed certificates, verify the CA bundle configuration.

Some files were not shown because too many files have changed in this diff Show More