diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 45e3e3ea..e344f868 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -34,6 +34,8 @@ jobs: ref: ${{ github.event.pull_request.head.sha }} - name: Install Task uses: arduino/setup-task@v2 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} - name: Install Dagger env: # renovate: datasource=github-tags depName=dagger/dagger versioning=semver @@ -51,8 +53,8 @@ jobs: github.event_name == 'workflow_dispatch' || github.event.pull_request.head.repo.full_name == github.repository env: - REGISTRY_USER: ${{ github.actor }} - REGISTRY_PASSWORD: ${{ secrets.GITHUB_TOKEN }} + REGISTRY_USER: ${{ secrets.REGISTRY_USER }} + REGISTRY_PASSWORD: ${{ secrets.REGISTRY_PASSWORD }} run: | task publish - name: Attach manifest to workflow run diff --git a/.github/workflows/release-please.yml b/.github/workflows/release-please.yml index 13fd80d4..92f07d63 100644 --- a/.github/workflows/release-please.yml +++ b/.github/workflows/release-please.yml @@ -27,8 +27,8 @@ jobs: curl -L https://dl.dagger.io/dagger/install.sh | BIN_DIR=$HOME/.local/bin sh - name: Create image and manifest env: - REGISTRY_USER: ${{ github.actor }} - REGISTRY_PASSWORD: ${{ secrets.GITHUB_TOKEN }} + REGISTRY_USER: ${{ secrets.REGISTRY_USER }} + REGISTRY_PASSWORD: ${{ secrets.REGISTRY_PASSWORD }} run: | task publish task manifest diff --git a/.github/workflows/release-publish.yml b/.github/workflows/release-publish.yml index 8799361a..9a19ec1a 100644 --- a/.github/workflows/release-publish.yml +++ b/.github/workflows/release-publish.yml @@ -19,8 +19,8 @@ jobs: curl -L https://dl.dagger.io/dagger/install.sh | BIN_DIR=$HOME/.local/bin sh - name: Create image and manifest env: - REGISTRY_USER: ${{ github.actor }} - REGISTRY_PASSWORD: ${{ secrets.GITHUB_TOKEN }} + REGISTRY_USER: ${{ secrets.REGISTRY_USER }} + REGISTRY_PASSWORD: ${{ secrets.REGISTRY_PASSWORD }} run: | task publish task manifest diff --git a/.golangci.yml b/.golangci.yml index 32ac9d93..6ce61b79 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -1,45 +1,26 @@ -linters-settings: - lll: - line-length: 120 - gci: - sections: - - standard - - default - - prefix(github.com/operasoftware/cnpg-plugin-pgbackrest) - - blank - - dot - gosec: - excludes: - - G101 # remove this exclude when https://github.com/securego/gosec/issues/1001 is fixed - +version: "2" linters: - # please, do not use `enable-all`: it's deprecated and will be removed soon. - # inverted configuration with `enable-all` and `disable` is not scalable during updates of golangci-lint - disable-all: true + # inverted configuration with `default: all` and `disable` is not scalable during updates of golangci-lint + default: none enable: - asciicheck - bodyclose + - copyloopvar - dogsled - dupl - durationcheck - errcheck - - copyloopvar - - gci + - ginkgolinter - gocognit - goconst - gocritic - gocyclo - - gofmt - - gofumpt - goheader - - goimports - gomoddirectives - gomodguard - goprintffuncname - gosec - - gosimple - govet - - ginkgolinter - importas - ineffassign - lll @@ -53,10 +34,8 @@ linters: - rowserrcheck - sqlclosecheck - staticcheck - - stylecheck - thelper - tparallel - - typecheck - unconvert - unparam - unused @@ -90,45 +69,59 @@ linters: # - godox # - gomnd # - testpackage - # - wsl - - # deprecated: - # - deadcode - # - golint - # - interfacer - # - maligned - # - scopelint - # - structcheck - # - varcheck - -run: - timeout: 10m - -issues: - exclude-rules: - # Allow dot imports for ginkgo and gomega - - source: ginkgo|gomega - linters: - - revive - text: "should not use dot imports" - # Exclude some linters from running on tests files. - - path: _test\.go - linters: - - goconst - # Exclude lll issues for lines with long annotations - - linters: - - lll - source: "//\\s*\\+" - # We have no control of this in zz_generated files and it looks like that excluding those files is not enough - # so we disable "ST1016: methods on the same type should have the same receiver name" in api directory - - linters: - - stylecheck - text: "ST1016:" - path: api/ - exclude-use-default: false - exclude-dirs: - # This tests are generated by kubebuilder - - test - exclude-files: - - zz_generated.* - - internal/operator/controller/suite_test.go + # - + + settings: + lll: + line-length: 120 + exclusions: + generated: lax + rules: + # Allow dot imports for ginkgo and gomega + - linters: + - revive + text: should not use dot imports + source: ginkgo|gomega + # Exclude some linters from running on tests files. + - linters: + - goconst + path: _test\.go + # Exclude lll issues for lines with long annotations + - linters: + - lll + source: //\s*\+ + paths: + - zz_generated.* + - internal/operator/controller/suite_test.go + # Those tests are generated by kubebuilder + - test + # Added by "golangci-lint migrate", to be removed? + - third_party$ + - builtin$ + - examples$ + +formatters: + enable: + - gci + - gofmt + - gofumpt + - goimports + settings: + gci: + sections: + - standard + - default + - prefix(github.com/operasoftware/cnpg-plugin-pgbackrest) + - blank + - dot + exclusions: + generated: lax + paths: + - zz_generated.* + - internal/operator/controller/suite_test.go + # Those tests are generated by kubebuilder + - test + # Added by "golangci-lint migrate", to be removed? + - third_party$ + - builtin$ + - examples$ diff --git a/.wordlist.txt b/.wordlist.txt index d9b1b054..31d4f20d 100644 --- a/.wordlist.txt +++ b/.wordlist.txt @@ -39,6 +39,7 @@ objectstore objectstores pgbackrestObjectName pgbackrest +pgBackRest pgbackrestArchive pluginConfiguration postgresql diff --git a/Makefile b/Makefile index 702f0574..ba9941a6 100644 --- a/Makefile +++ b/Makefile @@ -160,9 +160,9 @@ GOLANGCI_LINT = $(LOCALBIN)/golangci-lint ## Tool Versions KUSTOMIZE_VERSION ?= v5.4.3 -CONTROLLER_TOOLS_VERSION ?= v0.16.1 +CONTROLLER_TOOLS_VERSION ?= v0.16.2 ENVTEST_VERSION ?= release-0.19 -GOLANGCI_LINT_VERSION ?= v1.59.1 +GOLANGCI_LINT_VERSION ?= v2.1.5 .PHONY: kustomize kustomize: $(KUSTOMIZE) ## Download kustomize locally if necessary. diff --git a/Taskfile.yml b/Taskfile.yml index 5699ff2f..c8091f53 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -266,6 +266,8 @@ tasks: vars: # renovate: datasource=docker depName=golang versioning=semver GOLANG_IMAGE_VERSION: 1.23.5 + # renovate: datasource=docker depName=k3s versioning=semver + K3S_IMAGE_VERSION: 1.29.15 env: _EXPERIMENTAL_DAGGER_RUNNER_HOST: docker-container://{{ .DAGGER_ENGINE_CONTAINER_NAME }} cmds: @@ -274,6 +276,7 @@ tasks: --source . --ca certs/ca.pem --registry {{.REGISTRY_NAME}}:{{.REGISTRY_PORT}} + --kubernetes-version v{{ .K3S_IMAGE_VERSION }}-k3s1 --go-version {{ .GOLANG_IMAGE_VERSION }} ci: @@ -299,8 +302,8 @@ tasks: - REGISTRY_USER - REGISTRY_PASSWORD vars: - PLUGIN_IMAGE_NAME: ghcr.io/{{.GITHUB_REPOSITORY}}{{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}} + PLUGIN_IMAGE_NAME: '{{.GITHUB_REPOSITORY}}{{if not (hasPrefix "refs/tags/v" .GITHUB_REF)}}-testing{{end}}' + SIDECAR_IMAGE_NAME: '{{.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, # 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}"}}' @@ -310,12 +313,12 @@ tasks: cmds: - > dagger call -m github.com/purpleclay/daggerverse/docker@${DAGGER_DOCKER_SHA} - --registry ghcr.io --username $REGISTRY_USER --password env:REGISTRY_PASSWORD + --registry docker.io --username $REGISTRY_USER --password env:REGISTRY_PASSWORD build --dir . --file containers/Dockerfile.plugin --platform linux/amd64 --platform linux/arm64 publish --ref {{.PLUGIN_IMAGE_NAME}} --tags {{.IMAGE_VERSION}} - > dagger call -m github.com/purpleclay/daggerverse/docker@${DAGGER_DOCKER_SHA} - --registry ghcr.io --username $REGISTRY_USER --password env:REGISTRY_PASSWORD + --registry docker.io --username $REGISTRY_USER --password env:REGISTRY_PASSWORD build --dir . --file containers/Dockerfile.sidecar --platform linux/amd64 --platform linux/arm64 publish --ref {{.SIDECAR_IMAGE_NAME}} --tags {{.IMAGE_VERSION}} @@ -344,7 +347,7 @@ tasks: - controller-gen desc: Generate the manifest for the main branch vars: - GITHUB_REPOSITORY: cloudnative-pg/plugin-pgbackrest + GITHUB_REPOSITORY: operasoftware/cnpg-plugin-pgbackrest GITHUB_REF: main GITHUB_REF_NAME: main cmds: @@ -383,8 +386,8 @@ tasks: - GITHUB_REF - GITHUB_REF_NAME vars: - PLUGIN_IMAGE_NAME: ghcr.io/{{.GITHUB_REPOSITORY}}{{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}} + PLUGIN_IMAGE_NAME: '{{.GITHUB_REPOSITORY}}{{if not (hasPrefix "refs/tags/v" .GITHUB_REF)}}-testing{{end}}' + SIDECAR_IMAGE_NAME: '{{.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, # 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}"}}' diff --git a/api/v1/archive_types.go b/api/v1/archive_types.go index 43fafa97..2e611ef1 100644 --- a/api/v1/archive_types.go +++ b/api/v1/archive_types.go @@ -17,10 +17,10 @@ limitations under the License. package v1 import ( - pgbackrestApi "github.com/operasoftware/cnpg-plugin-pgbackrest/internal/pgbackrest/api" - corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + pgbackrestApi "github.com/operasoftware/cnpg-plugin-pgbackrest/internal/pgbackrest/api" ) // InstanceSidecarConfiguration defines the configuration for the sidecar that runs in the instance pods. diff --git a/config/crd/bases/pgbackrest.cnpg.opera.com_archives.yaml b/config/crd/bases/pgbackrest.cnpg.opera.com_archives.yaml index d9112f22..bb59046d 100644 --- a/config/crd/bases/pgbackrest.cnpg.opera.com_archives.yaml +++ b/config/crd/bases/pgbackrest.cnpg.opera.com_archives.yaml @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.16.1 + controller-gen.kubebuilder.io/version: v0.16.2 name: archives.pgbackrest.cnpg.opera.com spec: group: pgbackrest.cnpg.opera.com @@ -40,6 +40,8 @@ spec: description: ArchiveSpec defines the desired state of Archive. properties: configuration: + description: PgbackrestConfiguration is the configuration of all pgBackRest + operations properties: compression: description: |- @@ -102,6 +104,10 @@ spec: type: object repositories: items: + description: |- + PgbackrestRepository contains configuration of a single Pgbackrest backup target + repository, including all data needed to properly connect and authenticate with + a selected object store. properties: bucket: minLength: 1 diff --git a/dagger/e2e/main.go b/dagger/e2e/main.go index 759f96b9..a60da1a6 100644 --- a/dagger/e2e/main.go +++ b/dagger/e2e/main.go @@ -62,12 +62,19 @@ func (m *E2E) RunEphemeral( // +optional // +default="e2e" name string, + // version of the k3s image to use + // +optional + // +default="latest" + kubernetesVersion string, // version of the golang image to use // +optional // +default="latest" goVersion string, ) (string, error) { - k3s := dag.K3S(name) + k3sImage := fmt.Sprintf("rancher/k3s:%s", kubernetesVersion) + k3s := dag.K3S(name, dagger.K3SOpts{ + Image: k3sImage, + }) ctr := k3s.Container() if ca != nil { ctr = ctr.WithMountedFile("/usr/local/share/ca-certificates/ca.crt", ca) diff --git a/internal/cnpgi/common/wal.go b/internal/cnpgi/common/wal.go index 0fec50cd..a847cfd2 100644 --- a/internal/cnpgi/common/wal.go +++ b/internal/cnpgi/common/wal.go @@ -27,11 +27,6 @@ import ( cnpgv1 "github.com/cloudnative-pg/cloudnative-pg/api/v1" "github.com/cloudnative-pg/cnpg-i/pkg/wal" "github.com/cloudnative-pg/machinery/pkg/log" - "github.com/operasoftware/cnpg-plugin-pgbackrest/internal/pgbackrest/archiver" - pgbackrestCommand "github.com/operasoftware/cnpg-plugin-pgbackrest/internal/pgbackrest/command" - pgbackrestCredentials "github.com/operasoftware/cnpg-plugin-pgbackrest/internal/pgbackrest/credentials" - pgbackrestRestorer "github.com/operasoftware/cnpg-plugin-pgbackrest/internal/pgbackrest/restorer" - "github.com/operasoftware/cnpg-plugin-pgbackrest/internal/pgbackrest/utils" apierrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/types" "sigs.k8s.io/controller-runtime/pkg/client" @@ -39,6 +34,11 @@ import ( pgbackrestv1 "github.com/operasoftware/cnpg-plugin-pgbackrest/api/v1" "github.com/operasoftware/cnpg-plugin-pgbackrest/internal/cnpgi/metadata" "github.com/operasoftware/cnpg-plugin-pgbackrest/internal/cnpgi/operator/config" + "github.com/operasoftware/cnpg-plugin-pgbackrest/internal/pgbackrest/archiver" + pgbackrestCommand "github.com/operasoftware/cnpg-plugin-pgbackrest/internal/pgbackrest/command" + pgbackrestCredentials "github.com/operasoftware/cnpg-plugin-pgbackrest/internal/pgbackrest/credentials" + pgbackrestRestorer "github.com/operasoftware/cnpg-plugin-pgbackrest/internal/pgbackrest/restorer" + "github.com/operasoftware/cnpg-plugin-pgbackrest/internal/pgbackrest/utils" ) // WALServiceImplementation is the implementation of the WAL Service @@ -439,6 +439,7 @@ func gatherWALFilesToRestore(walName string, parallel int, controlledPromotion b if controlledPromotion && (len(segmentList) < parallel || parallel == 1) { // Last WAL file during a token-based promotion can be (always is?) a partial one // and pgbackrest won't download it unless extension is explicitly included. + // nolint: makezero // This is a rare operation that most likely should be rewritten anyway. walList = append(walList, walList[len(walList)-1]+".partial") } diff --git a/internal/cnpgi/instance/backup.go b/internal/cnpgi/instance/backup.go index af1b51c4..e66dd757 100644 --- a/internal/cnpgi/instance/backup.go +++ b/internal/cnpgi/instance/backup.go @@ -28,16 +28,16 @@ import ( "github.com/cloudnative-pg/machinery/pkg/fileutils" "github.com/cloudnative-pg/machinery/pkg/log" pgTime "github.com/cloudnative-pg/machinery/pkg/postgres/time" - pgbackrestBackup "github.com/operasoftware/cnpg-plugin-pgbackrest/internal/pgbackrest/backup" - "github.com/operasoftware/cnpg-plugin-pgbackrest/internal/pgbackrest/catalog" - pgbackrestCredentials "github.com/operasoftware/cnpg-plugin-pgbackrest/internal/pgbackrest/credentials" - "github.com/operasoftware/cnpg-plugin-pgbackrest/internal/pgbackrest/utils" "sigs.k8s.io/controller-runtime/pkg/client" pgbackrestv1 "github.com/operasoftware/cnpg-plugin-pgbackrest/api/v1" "github.com/operasoftware/cnpg-plugin-pgbackrest/internal/cnpgi/common" "github.com/operasoftware/cnpg-plugin-pgbackrest/internal/cnpgi/metadata" "github.com/operasoftware/cnpg-plugin-pgbackrest/internal/cnpgi/operator/config" + pgbackrestBackup "github.com/operasoftware/cnpg-plugin-pgbackrest/internal/pgbackrest/backup" + "github.com/operasoftware/cnpg-plugin-pgbackrest/internal/pgbackrest/catalog" + pgbackrestCredentials "github.com/operasoftware/cnpg-plugin-pgbackrest/internal/pgbackrest/credentials" + "github.com/operasoftware/cnpg-plugin-pgbackrest/internal/pgbackrest/utils" ) // BackupServiceImplementation is the implementation @@ -76,7 +76,6 @@ func (b BackupServiceImplementation) Backup( contextLogger.Info("Starting backup") backupConfig, err := decoder.DecodeBackup(request.BackupDefinition) - if err != nil { contextLogger.Error(err, "while getting backup definition") return nil, err diff --git a/internal/cnpgi/operator/lifecycle.go b/internal/cnpgi/operator/lifecycle.go index 2125089e..06ac7528 100644 --- a/internal/cnpgi/operator/lifecycle.go +++ b/internal/cnpgi/operator/lifecycle.go @@ -202,9 +202,9 @@ func (impl LifecycleImplementation) collectAdditionalEnvs( } func (impl LifecycleImplementation) collectArchiveEnvs( - ctx context.Context, + _ context.Context, archive *pgbackrestv1.Archive, -) ([]corev1.EnvVar, error) { +) ([]corev1.EnvVar, error) { // nolint: unparam return archive.Spec.InstanceSidecarConfiguration.Env, nil } diff --git a/internal/cnpgi/operator/specs/secrets.go b/internal/cnpgi/operator/specs/secrets.go index c90e4aae..15c6ce64 100644 --- a/internal/cnpgi/operator/specs/secrets.go +++ b/internal/cnpgi/operator/specs/secrets.go @@ -19,6 +19,7 @@ package specs import ( machineryapi "github.com/cloudnative-pg/machinery/pkg/api" + pgbackrestApi "github.com/operasoftware/cnpg-plugin-pgbackrest/internal/pgbackrest/api" ) diff --git a/internal/cnpgi/restore/identity.go b/internal/cnpgi/restore/identity.go index fdd74d4e..fcaaa418 100644 --- a/internal/cnpgi/restore/identity.go +++ b/internal/cnpgi/restore/identity.go @@ -12,6 +12,8 @@ import ( // IdentityImplementation implements IdentityServer type IdentityImplementation struct { identity.UnimplementedIdentityServer + // TODO: Should this field be removed? + // nolint: unused archiveObjectKey client.ObjectKey Client client.Client } diff --git a/internal/cnpgi/restore/restore.go b/internal/cnpgi/restore/restore.go index 8858ecb4..bf99c23f 100644 --- a/internal/cnpgi/restore/restore.go +++ b/internal/cnpgi/restore/restore.go @@ -33,6 +33,12 @@ import ( "github.com/cloudnative-pg/machinery/pkg/execlog" "github.com/cloudnative-pg/machinery/pkg/fileutils" "github.com/cloudnative-pg/machinery/pkg/log" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "sigs.k8s.io/controller-runtime/pkg/client" + + pgbackrestv1 "github.com/operasoftware/cnpg-plugin-pgbackrest/api/v1" + "github.com/operasoftware/cnpg-plugin-pgbackrest/internal/cnpgi/metadata" + "github.com/operasoftware/cnpg-plugin-pgbackrest/internal/cnpgi/operator/config" pgbackrestApi "github.com/operasoftware/cnpg-plugin-pgbackrest/internal/pgbackrest/api" pgbackrestArchiver "github.com/operasoftware/cnpg-plugin-pgbackrest/internal/pgbackrest/archiver" pgbackrestCatalog "github.com/operasoftware/cnpg-plugin-pgbackrest/internal/pgbackrest/catalog" @@ -40,12 +46,6 @@ import ( pgbackrestCredentials "github.com/operasoftware/cnpg-plugin-pgbackrest/internal/pgbackrest/credentials" pgbackrestRestorer "github.com/operasoftware/cnpg-plugin-pgbackrest/internal/pgbackrest/restorer" pgbackrestUtils "github.com/operasoftware/cnpg-plugin-pgbackrest/internal/pgbackrest/utils" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "sigs.k8s.io/controller-runtime/pkg/client" - - pgbackrestv1 "github.com/operasoftware/cnpg-plugin-pgbackrest/api/v1" - "github.com/operasoftware/cnpg-plugin-pgbackrest/internal/cnpgi/metadata" - "github.com/operasoftware/cnpg-plugin-pgbackrest/internal/cnpgi/operator/config" ) const ( @@ -213,6 +213,7 @@ func (impl JobHookImpl) restoreDataDir( } // TODO: Likely doesn't make sense for pgbackrest. Might be tricky to implement properly. +// nolint: unused func (impl JobHookImpl) ensureArchiveContainsLastCheckpointRedoWAL( ctx context.Context, env []string, @@ -233,12 +234,21 @@ func (impl JobHookImpl) ensureArchiveContainsLastCheckpointRedoWAL( return err } - rest, err := pgbackrestRestorer.New(ctx, env, impl.SpoolDirectory) + rest, err := pgbackrestRestorer.New( + ctx, + env, + impl.SpoolDirectory, + ) if err != nil { return err } - opts, err := pgbackrestCommand.CloudWalRestoreOptions(ctx, pgbackrestConfiguration, backup.Status.ServerName, testWALPath) + opts, err := pgbackrestCommand.CloudWalRestoreOptions( + ctx, + pgbackrestConfiguration, + backup.Status.ServerName, + testWALPath, + ) if err != nil { return err } diff --git a/internal/pgbackrest/api/config.go b/internal/pgbackrest/api/config.go index ec810f19..e4762abd 100644 --- a/internal/pgbackrest/api/config.go +++ b/internal/pgbackrest/api/config.go @@ -82,7 +82,7 @@ type S3Credentials struct { // S3 Repository URI style, either "host" (default) or "path". // TODO: Enforce values via Enum like iin compression. // +optional - UriStyle string `json:"uriStyle,omitempty"` + URIStyle string `json:"uriStyle,omitempty"` } // PgbackrestCredentials an object containing the potential credentials for each cloud provider @@ -236,6 +236,9 @@ type DataBackupConfiguration struct { AdditionalCommandArgs []string `json:"additionalCommandArgs,omitempty"` } +// PgbackrestRepository contains configuration of a single Pgbackrest backup target +// repository, including all data needed to properly connect and authenticate with +// a selected object store. type PgbackrestRepository struct { // The potential credentials for each cloud provider PgbackrestCredentials `json:",inline"` @@ -277,6 +280,8 @@ type PgbackrestRepository struct { // +optional Retention *PgbackrestRetention `json:"retention,omitempty"` } + +// PgbackrestConfiguration is the configuration of all pgBackRest operations type PgbackrestConfiguration struct { Repositories []PgbackrestRepository `json:"repositories"` @@ -318,6 +323,7 @@ func (cfg *WalBackupConfiguration) AppendRestoreAdditionalCommandArgs(options [] } return appendAdditionalCommandArgs(cfg.RestoreAdditionalCommandArgs, options) } + func appendAdditionalCommandArgs(additionalCommandArgs []string, options []string) []string { optionKeys := map[string]bool{} for _, option := range options { diff --git a/internal/pgbackrest/archiver/archiver.go b/internal/pgbackrest/archiver/archiver.go index 3d39fdd6..0c38e553 100644 --- a/internal/pgbackrest/archiver/archiver.go +++ b/internal/pgbackrest/archiver/archiver.go @@ -91,7 +91,9 @@ func New( } // DeleteFromSpool checks if a WAL file is in the spool and, if it is, remove it -func (archiver *WALArchiver) DeleteFromSpool(walName string) (hasBeenDeleted bool, err error) { +func (archiver *WALArchiver) DeleteFromSpool( + walName string, +) (hasBeenDeleted bool, err error) { var isContained bool // this code assumes the wal-archive command is run at most once at each instant, @@ -110,7 +112,11 @@ func (archiver *WALArchiver) ArchiveList( walNames []string, options []string, ) (result []WALArchiverResult) { - res := archiver.pgbackrestArchiver.ArchiveList(ctx, walNames, options) + res := archiver.pgbackrestArchiver.ArchiveList( + ctx, + walNames, + options, + ) for _, re := range res { result = append(result, WALArchiverResult{ WalName: re.WalName, @@ -124,7 +130,12 @@ func (archiver *WALArchiver) ArchiveList( // CheckWalArchiveDestination checks if the destination archive is ready to perform // archiving, i.e. if proper stanzas exist. -func (archiver *WALArchiver) CheckWalArchiveDestination(ctx context.Context, configuration *pgbackrestApi.PgbackrestConfiguration, stanza string, env []string) error { +func (archiver *WALArchiver) CheckWalArchiveDestination( + ctx context.Context, + configuration *pgbackrestApi.PgbackrestConfiguration, + stanza string, + env []string, +) error { // Probably the easiest way to check if stanza exists is to run "pgbackrest info". // It's possible to use stanza-create instead but it requires the lock file // which makes it unusable during backups. @@ -146,12 +157,22 @@ func (archiver *WALArchiver) PgbackrestCheckWalArchiveOptions( return nil, err } - options, err = pgbackrestCommand.AppendStanzaOptionsFromConfiguration(ctx, options, configuration, archiver.pgDataDirectory, true) + options, err = pgbackrestCommand.AppendStanzaOptionsFromConfiguration( + ctx, + options, + configuration, + archiver.pgDataDirectory, + true, + ) if err != nil { return nil, err } - options, err = pgbackrestCommand.AppendLogOptionsFromConfiguration(ctx, options, configuration) + options, err = pgbackrestCommand.AppendLogOptionsFromConfiguration( + ctx, + options, + configuration, + ) if err != nil { return nil, err } diff --git a/internal/pgbackrest/archiver/command_test.go b/internal/pgbackrest/archiver/command_test.go index 5b9537a3..00fe4d2c 100644 --- a/internal/pgbackrest/archiver/command_test.go +++ b/internal/pgbackrest/archiver/command_test.go @@ -61,7 +61,7 @@ var _ = Describe("pgbackrestWalArchiveOptions", func() { }) It("should generate correct arguments", func(ctx SpecContext) { - archiver, err := New(ctx, nil, "spool", "pgdata", tempEmptyWalArchivePath) + archiver, err := New(ctx, nil, "/tmp/pgbackrest-test-spool", "pgdata", tempEmptyWalArchivePath) Expect(err).ToNot(HaveOccurred()) extraOptions := []string{"--buffer-size=5MB", "--io-timeout=60"} diff --git a/internal/pgbackrest/backup/backup.go b/internal/pgbackrest/backup/backup.go index 4fa14539..876026a7 100644 --- a/internal/pgbackrest/backup/backup.go +++ b/internal/pgbackrest/backup/backup.go @@ -15,6 +15,7 @@ See the License for the specific language governing permissions and limitations under the License. */ +// Package backup manages the backup creation process package backup import ( @@ -25,10 +26,10 @@ import ( "strconv" "github.com/blang/semver" + cnpgApiV1 "github.com/cloudnative-pg/api/pkg/api/v1" "github.com/cloudnative-pg/machinery/pkg/execlog" "github.com/cloudnative-pg/machinery/pkg/log" - cnpgApiV1 "github.com/cloudnative-pg/api/pkg/api/v1" pgbackrestApi "github.com/operasoftware/cnpg-plugin-pgbackrest/internal/pgbackrest/api" pgbackrestCatalog "github.com/operasoftware/cnpg-plugin-pgbackrest/internal/pgbackrest/catalog" pgbackrestCommand "github.com/operasoftware/cnpg-plugin-pgbackrest/internal/pgbackrest/command" @@ -134,7 +135,13 @@ func (b *Command) GetPgbackrestBackupOptions( return nil, err } - options, err = pgbackrestCommand.AppendStanzaOptionsFromConfiguration(ctx, options, b.configuration, b.pgDataDirectory, true) + options, err = pgbackrestCommand.AppendStanzaOptionsFromConfiguration( + ctx, + options, + b.configuration, + b.pgDataDirectory, + true, + ) if err != nil { return nil, err } @@ -180,12 +187,22 @@ func (b *Command) getStanzaCreateOptions( return nil, err } - options, err = pgbackrestCommand.AppendStanzaOptionsFromConfiguration(ctx, options, b.configuration, b.pgDataDirectory, true) + options, err = pgbackrestCommand.AppendStanzaOptionsFromConfiguration( + ctx, + options, + b.configuration, + b.pgDataDirectory, + true, + ) if err != nil { return nil, err } - options, err = pgbackrestCommand.AppendLogOptionsFromConfiguration(ctx, options, b.configuration) + options, err = pgbackrestCommand.AppendLogOptionsFromConfiguration( + ctx, + options, + b.configuration, + ) if err != nil { return nil, err } @@ -218,10 +235,11 @@ func (b *Command) GetExecutedBackupInfo( } // IsCompatible checks if pgbackrest can back up this version of PostgreSQL -func (b *Command) IsCompatible(postgresVers semver.Version) error { +func (b *Command) IsCompatible(postgresVers semver.Version) error { // nolint: revive // Pgbackrest supports latest 10 major Postgres versions while operator itself // only supports currently maintained releases, i.e. 5 or so. // That means it should be safe to skip this check completely. + // TODO: Consider removal. return nil } diff --git a/internal/pgbackrest/catalog/catalog.go b/internal/pgbackrest/catalog/catalog.go index 31ae2aa7..27ce405a 100644 --- a/internal/pgbackrest/catalog/catalog.go +++ b/internal/pgbackrest/catalog/catalog.go @@ -27,8 +27,14 @@ import ( "github.com/cloudnative-pg/machinery/pkg/types" ) -const LatestTimelineId = -1 -const BackupNameAnnotation = "cnpg-backup-name" +const ( + // LatestTimelineID is used to mark the "latest" timeline option + LatestTimelineID = -1 + // BackupNameAnnotation is used to add CNPG backup name to the pgBackRest backup's + // metadata as an annotation. This makes it possible to trace specific backup to + // a Backup resource. + BackupNameAnnotation = "cnpg-backup-name" +) // NewCatalogFromPgbackrestInfo parses the output of pgbackrest info func NewCatalogFromPgbackrestInfo(rawJSON string) (*Catalog, error) { @@ -160,7 +166,6 @@ func (catalog *Catalog) findClosestBackupFromTargetLSN( targetLSNString string, targetTimeline int64, ) (*PgbackrestBackup, error) { - targetLSN := types.LSN(targetLSNString) if _, err := targetLSN.Parse(); err != nil { return nil, fmt.Errorf("while parsing recovery target targetLSN: %s", err.Error()) @@ -174,7 +179,7 @@ func (catalog *Catalog) findClosestBackupFromTargetLSN( if !pgbackrestBackup.isBackupDone() { continue } - if (startTimeline <= targetTimeline || targetTimeline == LatestTimelineId) && + if (startTimeline <= targetTimeline || targetTimeline == LatestTimelineID) && types.LSN(pgbackrestBackup.LSN.Stop).Less(targetLSN) { return &catalog.Backups[i], nil } @@ -204,7 +209,7 @@ func (catalog *Catalog) findClosestBackupFromTargetTime( // the timeline is the latest one unless it has finished after the specified // restore time. if (startTimeline <= targetTimeline || - targetTimeline == LatestTimelineId) && + targetTimeline == LatestTimelineID) && !time.Unix(pgbackrestBackup.Time.Stop, 0).After(targetTime) { return &catalog.Backups[i], nil } @@ -226,7 +231,7 @@ func (catalog *Catalog) findLatestBackupFromTimeline(targetTimeline int64) *Pgba } // Backups are iterated from newest to oldest, so the first backup that spans // the timeline is the latest one. - if startTimeline <= targetTimeline || targetTimeline == LatestTimelineId { + if startTimeline <= targetTimeline || targetTimeline == LatestTimelineID { return &catalog.Backups[i] } } @@ -249,7 +254,9 @@ func (catalog *Catalog) findBackupFromID(backupID string) (*PgbackrestBackup, er return nil, fmt.Errorf("no backup found with ID %s", backupID) } -func (catalog *Catalog) GetBackupIdFromAnnotatedName(backupName string) string { +// GetBackupIDFromAnnotatedName returns the ID of the backup with the custom CNPG +// annotation set to the provided name. +func (catalog *Catalog) GetBackupIDFromAnnotatedName(backupName string) string { // This function is usually called to retrieve latest backup so it's more efficient // to iterate from the end. for i := len(catalog.Backups) - 1; i >= 0; i-- { @@ -261,6 +268,7 @@ func (catalog *Catalog) GetBackupIdFromAnnotatedName(backupName string) string { return "" } +// PgbackrestBackupLSN represents an LSN range the backup contains type PgbackrestBackupLSN struct { // The LSN where the backup started Start string `json:"start"` @@ -268,6 +276,7 @@ type PgbackrestBackupLSN struct { Stop string `json:"stop"` } +// PgbackrestBackupDatabase contains identifying metadata of the database in the stanza type PgbackrestBackupDatabase struct { ID int `json:"id"` RepoKey int `json:"repo_key"` @@ -275,6 +284,7 @@ type PgbackrestBackupDatabase struct { Version string `json:"version,omitempty"` } +// PgbackrestWALArchive represents a pgBackRest WAL archive for a specific database type PgbackrestWALArchive struct { ID string `json:"id"` // First WAL in the archive @@ -284,6 +294,7 @@ type PgbackrestWALArchive struct { Database PgbackrestBackupDatabase `json:"database"` } +// PgbackrestBackupWALArchive represents a WAL archive range the backup contains type PgbackrestBackupWALArchive struct { // The WAL where the backup started Start string `json:"start"` @@ -291,6 +302,7 @@ type PgbackrestBackupWALArchive struct { Stop string `json:"stop"` } +// PgbackrestBackupTime represents a time span of the creation of a single backup type PgbackrestBackupTime struct { // The moment where the backup started Start int64 `json:"start"` @@ -316,6 +328,7 @@ type PgbackrestBackup struct { Type string `json:"type"` } +// Catalog represents a catalog of archive and backup storages of a specific stanza type Catalog struct { Archive []PgbackrestWALArchive `json:"archive"` Backups []PgbackrestBackup `json:"backup"` @@ -341,6 +354,7 @@ func (b *PgbackrestBackup) startTimeline() (int64, error) { return strconv.ParseInt(b.WAL.Start[:8], 16, 0) } -func (b *PgbackrestBackup) stopTimeline() (int64, error) { +func (b *PgbackrestBackup) stopTimeline() (int64, error) { // nolint: unused + // TODO: Is this method needed? return strconv.ParseInt(b.WAL.Stop[:8], 16, 0) } diff --git a/internal/pgbackrest/command/backuplist.go b/internal/pgbackrest/command/backuplist.go index 731b6826..fcefd07d 100644 --- a/internal/pgbackrest/command/backuplist.go +++ b/internal/pgbackrest/command/backuplist.go @@ -139,8 +139,8 @@ func GetBackupByAnnotatedName( if err != nil { return nil, err } - backupId := fullCatalog.GetBackupIdFromAnnotatedName(backupName) - if backupId == "" { + backupID := fullCatalog.GetBackupIDFromAnnotatedName(backupName) + if backupID == "" { contextLogger.Error(err, "Can't find backup with name", "name", backupName) return nil, err @@ -150,7 +150,7 @@ func GetBackupByAnnotatedName( ctx, pgbackrestConfiguration, stanza, - []string{"--set", backupId}, + []string{"--set", backupID}, env, ) if err != nil { diff --git a/internal/pgbackrest/command/commandbuilder.go b/internal/pgbackrest/command/commandbuilder.go index fbf7f2b1..1bb0ecf4 100644 --- a/internal/pgbackrest/command/commandbuilder.go +++ b/internal/pgbackrest/command/commandbuilder.go @@ -91,11 +91,12 @@ func AppendRetentionOptionsFromConfiguration( // appendRetentionOptions takes an options array and adds the retention options specified // for the repository as arguments func appendRetentionOptions( - ctx context.Context, + _ context.Context, options []string, repoIndex int, repository *pgbackrestApi.PgbackrestRepository, -) ([]string, error) { +) ([]string, error) { // nolint: unparam + // TODO: Handle invalid parameters and return errors then remove the nolint comment. if repository.Retention == nil { return options, nil } @@ -143,16 +144,15 @@ func appendRetentionOptions( } return options, nil - } // appendCloudProviderOptions takes an options array and adds the cloud provider specified as arguments func appendCloudProviderOptions( - ctx context.Context, + _ context.Context, options []string, repoIndex int, repository pgbackrestApi.PgbackrestRepository, -) ([]string, error) { +) ([]string, error) { // nolint: unparam options = append( options, utils.FormatRepoFlag(repoIndex, "type"), @@ -173,11 +173,11 @@ func appendCloudProviderOptions( utils.FormatRepoFlag(repoIndex, "path"), repository.DestinationPath, ) if repository.AWS != nil { - if len(repository.AWS.UriStyle) > 0 { + if len(repository.AWS.URIStyle) > 0 { options = append( options, utils.FormatRepoFlag(repoIndex, "s3-uri-style"), - repository.AWS.UriStyle) + repository.AWS.URIStyle) } } return options, nil @@ -188,7 +188,7 @@ func appendCloudProviderOptions( func AppendStanzaOptionsFromConfiguration( ctx context.Context, options []string, - configuration *pgbackrestApi.PgbackrestConfiguration, + configuration *pgbackrestApi.PgbackrestConfiguration, // nolint: revive pgDataDirectory string, clusterRunning bool, ) (resOptions []string, err error) { @@ -201,7 +201,7 @@ func AppendStanzaOptionsFromConfiguration( // appendStanzaOptions takes an options array and adds the stanza-specific pgbackrest // options required for all operations connecting to the database func appendStanzaOptions( - ctx context.Context, + _ context.Context, options []string, index int, pgDataDirectory string, @@ -231,7 +231,7 @@ func appendStanzaOptions( func AppendLogOptionsFromConfiguration( ctx context.Context, options []string, - configuration *pgbackrestApi.PgbackrestConfiguration, + configuration *pgbackrestApi.PgbackrestConfiguration, // nolint: revive ) (resOptions []string, err error) { return appendLogOptions(ctx, options) } @@ -239,7 +239,7 @@ func AppendLogOptionsFromConfiguration( // appendLogOptions takes an options array and adds the stanza-specific pgbackrest // options required for all operations connecting to the database func appendLogOptions( - ctx context.Context, + _ context.Context, options []string, ) ([]string, error) { // TODO: Those options likely shouldn't be hardcoded. diff --git a/internal/pgbackrest/command/errors.go b/internal/pgbackrest/command/errors.go index 26740ec0..ff6c49d0 100644 --- a/internal/pgbackrest/command/errors.go +++ b/internal/pgbackrest/command/errors.go @@ -78,7 +78,7 @@ func (err *CloudRestoreError) IsRetriable() bool { // UnmarshalPgbackrestRestoreExitCode returns the correct error // for a certain pgbackrest exit code -func UnmarshalPgbackrestRestoreExitCode(ctx context.Context, exitCode int) error { +func UnmarshalPgbackrestRestoreExitCode(_ context.Context, exitCode int) error { if exitCode == 0 { return nil } diff --git a/internal/pgbackrest/credentials/credentials.go b/internal/pgbackrest/credentials/credentials.go index 3765279d..817ae303 100644 --- a/internal/pgbackrest/credentials/credentials.go +++ b/internal/pgbackrest/credentials/credentials.go @@ -15,6 +15,8 @@ See the License for the specific language governing permissions and limitations under the License. */ +// Package credentials handles the retrieval and injection of credentials stored in +// Kubernetes secrets package credentials import ( @@ -22,10 +24,11 @@ import ( "fmt" machineryapi "github.com/cloudnative-pg/machinery/pkg/api" - pgbackrestApi "github.com/operasoftware/cnpg-plugin-pgbackrest/internal/pgbackrest/api" - "github.com/operasoftware/cnpg-plugin-pgbackrest/internal/pgbackrest/utils" corev1 "k8s.io/api/core/v1" "sigs.k8s.io/controller-runtime/pkg/client" + + pgbackrestApi "github.com/operasoftware/cnpg-plugin-pgbackrest/internal/pgbackrest/api" + "github.com/operasoftware/cnpg-plugin-pgbackrest/internal/pgbackrest/utils" ) const ( @@ -58,6 +61,8 @@ const ( BarmanEndpointCACertificateFileName = "barman-ca.crt" ) +// EnvSetBackupCloudCredentials sets the AWS environment variables needed for backups +// given the configuration inside the cluster func EnvSetBackupCloudCredentials( ctx context.Context, c client.Client, @@ -114,7 +119,6 @@ func envSetCloudCredentials( return nil, err } } - } return env, nil } diff --git a/internal/pgbackrest/restorer/restorer.go b/internal/pgbackrest/restorer/restorer.go index c7ae0c1e..7fe78c77 100644 --- a/internal/pgbackrest/restorer/restorer.go +++ b/internal/pgbackrest/restorer/restorer.go @@ -15,6 +15,7 @@ See the License for the specific language governing permissions and limitations under the License. */ +// Package restorer manages the cluster restoration process package restorer import ( @@ -183,7 +184,6 @@ func (restorer *WALRestorer) RestoreList( result.DestinationPath = restorer.spool.FileName(strings.TrimSuffix(result.WalName, ".partial")) } else { result.DestinationPath = restorer.spool.FileName(result.WalName) - } } @@ -275,5 +275,4 @@ func (restorer *WALRestorer) Restore( return fmt.Errorf("encountered an error: '%d' while executing %s", exitCode, "pgbackrest archive-get") - } diff --git a/internal/pgbackrest/spool/spool.go b/internal/pgbackrest/spool/spool.go index 313eb7de..ee29026c 100644 --- a/internal/pgbackrest/spool/spool.go +++ b/internal/pgbackrest/spool/spool.go @@ -14,6 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ +// Package spool maintains the scratch space used for WAL retrieval package spool import ( diff --git a/internal/pgbackrest/utils/doc.go b/internal/pgbackrest/utils/doc.go new file mode 100644 index 00000000..0693627b --- /dev/null +++ b/internal/pgbackrest/utils/doc.go @@ -0,0 +1,2 @@ +// Package utils provides utility functions that help with configuring pgBackrest +package utils diff --git a/internal/pgbackrest/utils/env_utils.go b/internal/pgbackrest/utils/env_utils.go index 86be6bb0..45a59f82 100644 --- a/internal/pgbackrest/utils/env_utils.go +++ b/internal/pgbackrest/utils/env_utils.go @@ -22,18 +22,29 @@ import ( "regexp" ) -// This pattern should match all service discovery environment variables injected to +// PgbackrestServiceEnvVarPattern should match all service discovery environment variables injected to // the pod by Kubernetes for services with names starting with "pgbackrest". var PgbackrestServiceEnvVarPattern = regexp.MustCompile("^PGBACKREST_(?:[A-Z0-9]+_)*(?:PORT|SERVICE)") +// FormatEnv takes an environment variable name and its value. It returns a properly +// formatted variable with a prefix used by pgBackRest to detect its config variables. +// Returned value is ready to be passed as a part of the command's env array. func FormatEnv(env string, value string) string { return fmt.Sprintf("PGBACKREST_%s=%s", env, value) } +// FormatRepoEnv takes a zero-based repository index, an environment variable name and +// its value. It returns a properly formatted repo-scoped variable with a prefix used +// by pgBackRest to detect its config variables. +// Returned value is ready to be passed as a part of the command's env array. func FormatRepoEnv(repository int, env string, value string) string { return fmt.Sprintf("PGBACKREST_REPO%d_%s=%s", repository+1, env, value) } +// FormatDbEnv takes a zero-based database index, an environment variable name and +// its value. It returns a properly formatted db-scoped variable with a prefix used +// by pgBackRest to detect its config variables. +// Returned value is ready to be passed as a part of the command's env array. func FormatDbEnv(database int, env string, value string) string { return fmt.Sprintf("PGBACKREST_PG%d_%s=%s", database, env, value) } diff --git a/internal/pgbackrest/utils/flag_utils.go b/internal/pgbackrest/utils/flag_utils.go index 0ad20e1f..220eeb15 100644 --- a/internal/pgbackrest/utils/flag_utils.go +++ b/internal/pgbackrest/utils/flag_utils.go @@ -13,18 +13,23 @@ 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. */ + package utils import ( "fmt" ) +// FormatRepoFlag takes a zero-based repository index and a flag name and returns +// a properly formatted repo-scoped flag ready to be passed as a command argument. func FormatRepoFlag(repository int, flag string) string { // Repositories must be indexed from 1 while all iterations are 0-based. // Using repo0 causes a segfault. return fmt.Sprintf("--repo%d-%s", repository+1, flag) } +// FormatDbFlag takes a zero-based database index and a flag name and returns +// a properly formatted db-scoped flag ready to be passed as a command argument. func FormatDbFlag(database int, flag string) string { // Databases must be indexed from 1 while all iterations are 0-based. return fmt.Sprintf("--pg%d-%s", database+1, flag) diff --git a/internal/pgbackrest/walarchive/cmd.go b/internal/pgbackrest/walarchive/cmd.go index 73641122..dcd1c65a 100644 --- a/internal/pgbackrest/walarchive/cmd.go +++ b/internal/pgbackrest/walarchive/cmd.go @@ -1,5 +1,6 @@ /* Copyright The CloudNativePG Contributors +Copyright 2025, Opera Norway AS Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,6 +15,7 @@ See the License for the specific language governing permissions and limitations under the License. */ +// Package walarchive provides support for WAL archive upload package walarchive import ( @@ -29,8 +31,12 @@ import ( "github.com/cloudnative-pg/machinery/pkg/log" ) -const ArchiveCommand = "archive-push" -const PgbackrestExecutable = "pgbackrest" +const ( + // ArchiveCommand defines the pgBackRest command for WAL archive upload + ArchiveCommand = "archive-push" + // PgbackrestExecutable defines the name of the pgBackRest binary + PgbackrestExecutable = "pgbackrest" +) // PgbackrestArchiver implements a WAL archiver based // on pgbackrest diff --git a/kubernetes/kustomization.yaml b/kubernetes/kustomization.yaml index 39f5ec8d..3a40622d 100644 --- a/kubernetes/kustomization.yaml +++ b/kubernetes/kustomization.yaml @@ -11,9 +11,9 @@ resources: - ../config/rbac images: - name: plugin-pgbackrest - newName: ghcr.io/operasoftware/cnpg-plugin-pgbackrest-testing + newName: operasoftware/cnpg-plugin-pgbackrest-testing newTag: main secretGenerator: - literals: - - SIDECAR_IMAGE=ghcr.io/operasoftware/cnpg-plugin-pgbackrest-sidecar-testing:main + - SIDECAR_IMAGE=operasoftware/cnpg-plugin-pgbackrest-sidecar-testing:main name: plugin-pgbackrest diff --git a/manifest.yaml b/manifest.yaml index 8af0975b..162e9145 100644 --- a/manifest.yaml +++ b/manifest.yaml @@ -2,7 +2,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.16.1 + controller-gen.kubebuilder.io/version: v0.16.2 name: archives.pgbackrest.cnpg.opera.com spec: group: pgbackrest.cnpg.opera.com @@ -39,6 +39,8 @@ spec: description: ArchiveSpec defines the desired state of Archive. properties: configuration: + description: PgbackrestConfiguration is the configuration of all pgBackRest + operations properties: compression: description: |- @@ -101,6 +103,10 @@ spec: type: object repositories: items: + description: |- + PgbackrestRepository contains configuration of a single Pgbackrest backup target + repository, including all data needed to properly connect and authenticate with + a selected object store. properties: bucket: minLength: 1 @@ -775,11 +781,11 @@ subjects: apiVersion: v1 data: SIDECAR_IMAGE: | - Z2hjci5pby9vcGVyYXNvZnR3YXJlL2NucGctcGx1Z2luLXBnYmFja3Jlc3Qtc2lkZWNhci - 10ZXN0aW5nOm1haW4= + b3BlcmFzb2Z0d2FyZS9jbnBnLXBsdWdpbi1wZ2JhY2tyZXN0LXNpZGVjYXItdGVzdGluZz + ptYWlu kind: Secret metadata: - name: plugin-pgbackrest-gd89t8kd44 + name: plugin-pgbackrest-7fb6h2h74f namespace: cnpg-system type: Opaque --- @@ -836,8 +842,8 @@ spec: valueFrom: secretKeyRef: key: SIDECAR_IMAGE - name: plugin-pgbackrest-gd89t8kd44 - image: ghcr.io/operasoftware/cnpg-plugin-pgbackrest-testing:main + name: plugin-pgbackrest-7fb6h2h74f + image: operasoftware/cnpg-plugin-pgbackrest-testing:main name: pgbackrest ports: - containerPort: 9090 diff --git a/test/e2e/e2e_suite_test.go b/test/e2e/e2e_suite_test.go index 461c46bf..74e6cd45 100644 --- a/test/e2e/e2e_suite_test.go +++ b/test/e2e/e2e_suite_test.go @@ -56,7 +56,7 @@ var _ = SynchronizedBeforeSuite(func(ctx SpecContext) []byte { Resources: []string{pgbackrestKustomizationPath}, Images: []kustomizeTypes.Image{ { - Name: "docker.io/library/plugin-pgbackrest", + Name: "operasoftware/cnpg-plugin-pgbackrest-testing", NewName: "registry.pgbackrest-plugin:5000/plugin-pgbackrest", NewTag: "testing", }, diff --git a/test/e2e/internal/objectstore/minio.go b/test/e2e/internal/objectstore/minio.go index 85f55d11..0d6e1abe 100644 --- a/test/e2e/internal/objectstore/minio.go +++ b/test/e2e/internal/objectstore/minio.go @@ -193,7 +193,7 @@ func newMinioProvisioningJob(namespace, name string) *batchv1.Job { RestartPolicy: corev1.RestartPolicyOnFailure, Containers: []corev1.Container{ { - Name: name, + Name: name + "-provisioner", Image: "minio/minio:latest", Command: []string{"bash"}, Args: []string{ @@ -201,12 +201,7 @@ func newMinioProvisioningJob(namespace, name string) *batchv1.Job { fmt.Sprintf("mc alias set local https://%s:9000 $MINIO_ROOT_USER $MINIO_ROOT_PASSWORD --insecure;\n", name) + "mc mb --insecure local/backups", }, - Ports: []corev1.ContainerPort{ - { - ContainerPort: 9000, - Name: name, - }, - }, + TerminationMessagePolicy: "FallbackToLogsOnError", Env: []corev1.EnvVar{ { Name: "MINIO_ROOT_USER", @@ -336,7 +331,7 @@ func NewMinioArchive(namespace, name, minioOSName string) *pluginPgbackrestV1.Ar Region: "dummy", // There is no ingress that would provide domain-based // routing. - UriStyle: "path", + URIStyle: "path", }, }, EndpointURL: net.JoinHostPort(minioOSName, "9000"),