Repository: cloudnative-pg/cloudnative-pg

Issue:
[Feature]: Support zstandard and lz4 fully in object store backups
### Is there an existing issue already for this feature request/idea?

- [x] I have searched for an existing issue, and could not find anything. I believe this is a new feature request to be evaluated.

### What problem is this feature going to solve? Why should it be added?

Production databases have a trade-off on backup size and CPU usage. Not all algorithms have the same ratios, and newer ones can even perform better for free. When we were testing for HBase we found ZSTD and Lz4 to be good for live runs (I haven't tested xz for wal compression). When these requests have come up previously, the answers have been that Barman Cloud doesn't support other compression algos. I think that has changed with recent versions: https://github.com/EnterpriseDB/barman/releases/tag/release%2F3.12.0

### Describe the solution you'd like

- [x] Update to 3.12.1 for barman
- [x] Change `CompressionType` to accept the new standard and lz4
- [x] Change the kubebuilder annotations on CompressionType to accept the new strings.
- [x] Add documentation for https://cloudnative-pg.io/documentation/1.25/backup_barmanobjectstore/#compression-algorithms

### Describe alternatives you've considered

N/A

### Additional context

#6363 was closed, but work remains to complete this feature. I re-filed it since I don't have permission to re-open it.

### Backport?

No

### Are you willing to actively contribute to this feature?

Yes

### Code of Conduct

- [x] I agree to follow this project's Code of Conduct

Hints from issue comments:
@mnencia: PR created in barman-cloud library
https://github.com/cloudnative-pg/barman-cloud/pull/82

Solution patch:
diff --git a/.wordlist-en-custom.txt b/.wordlist-en-custom.txt
index eca5fe59..eb470824 100644
--- a/.wordlist-en-custom.txt
+++ b/.wordlist-en-custom.txt
@@ -958,6 +958,7 @@ logLevel
 lookups
 lsn
 lt
+lz
 macOS
 malcolm
 mallocs
@@ -1417,5 +1418,7 @@ www
 xact
 xlog
 xml
+xz
 yaml
 yml
+zstd
diff --git a/config/crd/bases/postgresql.cnpg.io_clusters.yaml b/config/crd/bases/postgresql.cnpg.io_clusters.yaml
index 7fcdabd3..4e27dd29 100644
--- a/config/crd/bases/postgresql.cnpg.io_clusters.yaml
+++ b/config/crd/bases/postgresql.cnpg.io_clusters.yaml
@@ -1152,11 +1152,14 @@ spec:
                             description: |-
                               Compress a backup file (a tar file per tablespace) while streaming it
                               to the object store. Available options are empty string (no
-                              compression, default), `gzip`, `bzip2` or `snappy`.
+                              compression, default), `gzip`, `bzip2`, `lz4`, `snappy`, `xz`, and `zstd`.
                             enum:
-                            - gzip
                             - bzip2
+                            - gzip
+                            - lz4
                             - snappy
+                            - xz
+                            - zstd
                             type: string
                           encryption:
                             description: |-
@@ -1343,11 +1346,15 @@ spec:
                           compression:
                             description: |-
                               Compress a WAL file before sending it to the object store. Available
-                              options are empty string (no compression, default), `gzip`, `bzip2` or `snappy`.
+                              options are empty string (no compression, default), `gzip`, `bzip2`,
+                              `lz4`, `snappy`, `xz`, and `zstd`.
                             enum:
-                            - gzip
                             - bzip2
+                            - gzip
+                            - lz4
                             - snappy
+                            - xz
+                            - zstd
                             type: string
                           encryption:
                             description: |-
@@ -2654,11 +2661,14 @@ spec:
                               description: |-
                                 Compress a backup file (a tar file per tablespace) while streaming it
                                 to the object store. Available options are empty string (no
-                                compression, default), `gzip`, `bzip2` or `snappy`.
+                                compression, default), `gzip`, `bzip2`, `lz4`, `snappy`, `xz`, and `zstd`.
                               enum:
-                              - gzip
                               - bzip2
+                              - gzip
+                              - lz4
                               - snappy
+                              - xz
+                              - zstd
                               type: string
                             encryption:
                               description: |-
@@ -2845,11 +2855,15 @@ spec:
                             compression:
                               description: |-
                                 Compress a WAL file before sending it to the object store. Available
-                                options are empty string (no compression, default), `gzip`, `bzip2` or `snappy`.
+                                options are empty string (no compression, default), `gzip`, `bzip2`,
+                                `lz4`, `snappy`, `xz`, and `zstd`.
                               enum:
-                              - gzip
                               - bzip2
+                              - gzip
+                              - lz4
                               - snappy
+                              - xz
+                              - zstd
                               type: string
                             encryption:
                               description: |-
diff --git a/docs/src/backup_barmanobjectstore.md b/docs/src/backup_barmanobjectstore.md
index 5859966a..ba2ed407 100644
--- a/docs/src/backup_barmanobjectstore.md
+++ b/docs/src/backup_barmanobjectstore.md
@@ -93,7 +93,10 @@ algorithms via `barman-cloud-backup` (for backups) and
 
 * bzip2
 * gzip
+* lz4
 * snappy
+* xz
+* zstd
 
 The compression settings for backups and WALs are independent. See the
 [DataBackupConfiguration](https://pkg.go.dev/github.com/cloudnative-pg/barman-cloud/pkg/api#DataBackupConfiguration) and
diff --git a/go.mod b/go.mod
index 5b7c8218..df8e4f36 100644
--- a/go.mod
+++ b/go.mod
@@ -8,7 +8,7 @@ require (
 	github.com/avast/retry-go/v4 v4.6.1
 	github.com/blang/semver v3.5.1+incompatible
 	github.com/cheynewallace/tabby v1.1.1
-	github.com/cloudnative-pg/barman-cloud v0.1.0
+	github.com/cloudnative-pg/barman-cloud v0.3.0
 	github.com/cloudnative-pg/cnpg-i v0.1.1-0.20250321093050-de4ab51537cb
 	github.com/cloudnative-pg/machinery v0.1.0
 	github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc
diff --git a/go.sum b/go.sum
index c332c3c3..d841fae2 100644
--- a/go.sum
+++ b/go.sum
@@ -18,8 +18,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/cheynewallace/tabby v1.1.1 h1:JvUR8waht4Y0S3JF17G6Vhyt+FRhnqVCkk8l4YrOU54=
 github.com/cheynewallace/tabby v1.1.1/go.mod h1:Pba/6cUL8uYqvOc9RkyvFbHGrQ9wShyrn6/S/1OYVys=
-github.com/cloudnative-pg/barman-cloud v0.1.0 h1:e/z52CehMBIh1LjZqNBJnncWJbS+1JYvRMBR8Js6Uiw=
-github.com/cloudnative-pg/barman-cloud v0.1.0/go.mod h1:rJUJO/f1yNckLZiVxHAyRmKY+4EPJkYRJsGbTZRJQSY=
+github.com/cloudnative-pg/barman-cloud v0.3.0 h1:tCtIF7nsHDH5X7nAXXd7VqNKKNGHrycXAyyKKKpdGS4=
+github.com/cloudnative-pg/barman-cloud v0.3.0/go.mod h1:8m6W117343zT28ctcskUYEu/dy+MX3hUUW4DynH8MLI=
 github.com/cloudnative-pg/cnpg-i v0.1.1-0.20250321093050-de4ab51537cb h1:FPORwCxjZwlnKnF7dOkuOAz0GBSQ3Hrn+8lm4uMiWeM=
 github.com/cloudnative-pg/cnpg-i v0.1.1-0.20250321093050-de4ab51537cb/go.mod h1:n+kbHm3rzRCY5IJKuE1tGMbG6JaeYz8yycYoLt7BeKo=
 github.com/cloudnative-pg/machinery v0.1.0 h1:tjRmsqQmsO/OlaT0uFmkEtVqgr+SGPM88cKZOHYKLBo=



Test patch:
diff --git a/pkg/management/postgres/backup_test.go b/pkg/management/postgres/backup_test.go
index 8ff4796c..bfd037e4 100644
--- a/pkg/management/postgres/backup_test.go
+++ b/pkg/management/postgres/backup_test.go
@@ -150,39 +150,39 @@ var _ = Describe("testing backup command", func() {
 
 var _ = Describe("generate backup options", func() {
 	const namespace = "test"
-	capabilities := barmanCapabilities.Capabilities{
-		Version:                    nil,
-		HasAzure:                   true,
-		HasS3:                      true,
-		HasGoogle:                  true,
-		HasRetentionPolicy:         true,
-		HasTags:                    true,
-		HasCheckWalArchive:         true,
-		HasSnappy:                  true,
-		HasErrorCodesForWALRestore: true,
-		HasAzureManagedIdentity:    true,
-	}
-	cluster := &apiv1.Cluster{
-		ObjectMeta: metav1.ObjectMeta{Name: "test-cluster", Namespace: namespace},
-		Spec: apiv1.ClusterSpec{
-			Backup: &apiv1.BackupConfiguration{
-				BarmanObjectStore: &apiv1.BarmanObjectStoreConfiguration{
-					Data: &apiv1.DataBackupConfiguration{
-						Compression:         "gzip",
-						Encryption:          "aes256",
-						ImmediateCheckpoint: true,
-						Jobs:                ptr.To(int32(2)),
+
+	var (
+		capabilities *barmanCapabilities.Capabilities
+		cluster      *apiv1.Cluster
+	)
+
+	BeforeEach(func() {
+		var err error
+		capabilities, err = barmanCapabilities.CurrentCapabilities()
+		Expect(err).ShouldNot(HaveOccurred())
+
+		cluster = &apiv1.Cluster{
+			ObjectMeta: metav1.ObjectMeta{Name: "test-cluster", Namespace: namespace},
+			Spec: apiv1.ClusterSpec{
+				Backup: &apiv1.BackupConfiguration{
+					BarmanObjectStore: &apiv1.BarmanObjectStoreConfiguration{
+						Data: &apiv1.DataBackupConfiguration{
+							Compression:         "gzip",
+							Encryption:          "aes256",
+							ImmediateCheckpoint: true,
+							Jobs:                ptr.To(int32(2)),
+						},
 					},
 				},
 			},
-		},
-	}
+		}
+	})
 
 	It("should generate correct options", func() {
 		extraOptions := []string{"--min-chunk-size=5MB", "--read-timeout=60", "-vv"}
 		cluster.Spec.Backup.BarmanObjectStore.Data.AdditionalCommandArgs = extraOptions
 
-		cmd := barmanBackup.NewBackupCommand(cluster.Spec.Backup.BarmanObjectStore, &capabilities)
+		cmd := barmanBackup.NewBackupCommand(cluster.Spec.Backup.BarmanObjectStore, capabilities)
 		options, err := cmd.GetDataConfiguration([]string{})
 		Expect(err).ToNot(HaveOccurred())
 
@@ -203,7 +203,7 @@ var _ = Describe("generate backup options", func() {
 			"--encryption=aes256",
 		}
 		cluster.Spec.Backup.BarmanObjectStore.Data.AdditionalCommandArgs = extraOptions
-		cmd := barmanBackup.NewBackupCommand(cluster.Spec.Backup.BarmanObjectStore, &capabilities)
+		cmd := barmanBackup.NewBackupCommand(cluster.Spec.Backup.BarmanObjectStore, capabilities)
 		options, err := cmd.GetDataConfiguration([]string{})
 		Expect(err).ToNot(HaveOccurred())