Skip to content

Commit 9052fb2

Browse files
lpabonliuxu
authored and
liuxu
committed
Compress database when storing in a K8S Secret
With this change, the database is compressed before storing in a Kuberntes Secret, which currently has a maximum size of 1Mi. Because of this limit, it has been found that the maximum number of devices allowed is 12000. This creates a db which is around 30Mi, but is compressed down to around 900Ki. Closes heketi#697 Signed-off-by: Luis Pabón <[email protected]> Signed-off-by: liuxu <[email protected]>
1 parent 6429455 commit 9052fb2

File tree

6 files changed

+121
-12
lines changed

6 files changed

+121
-12
lines changed

apps/glusterfs/app_middleware_test.go

+66
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@
1010
package glusterfs
1111

1212
import (
13+
"bytes"
14+
"compress/gzip"
15+
"io/ioutil"
1316
"net/http"
1417
"net/http/httptest"
1518
"os"
@@ -24,6 +27,69 @@ func init() {
2427
logger.SetLevel(utils.LEVEL_NOLOG)
2528
}
2629

30+
func TestBackupToKubeSecretMaxSize(t *testing.T) {
31+
tmpfile := tests.Tempfile()
32+
defer os.Remove(tmpfile)
33+
34+
// Create the app
35+
app := NewTestApp(tmpfile)
36+
37+
// Create a Max cluster size when using Secrets
38+
// Max secret size is 1024M in Kubernetes
39+
// Max = 12000 Drives
40+
err := setupSampleDbWithTopology(app,
41+
1, // clusters
42+
120, // nodes_per_cluster
43+
100, // devices_per_node,
44+
5*TB, // disksize)
45+
)
46+
tests.Assert(t, err == nil)
47+
app.Close()
48+
49+
// Gzip database
50+
var b bytes.Buffer
51+
gz := gzip.NewWriter(&b)
52+
dbData, err := ioutil.ReadFile(tmpfile)
53+
tests.Assert(t, err == nil)
54+
_, err = gz.Write(dbData)
55+
tests.Assert(t, err == nil)
56+
err = gz.Close()
57+
tests.Assert(t, err == nil)
58+
tests.Assert(t, b.Len() < 1024*MB)
59+
}
60+
61+
func TestBackupToKubeSecretMaxSizeFailure(t *testing.T) {
62+
tmpfile := tests.Tempfile()
63+
defer os.Remove(tmpfile)
64+
65+
// Create the app
66+
app := NewTestApp(tmpfile)
67+
68+
// Create a Max cluster size when using Secrets
69+
// Max secret size is 1024M in Kubernetes
70+
// Max = 12000 Drives
71+
// So here pick 24000 Drives in two clusters
72+
err := setupSampleDbWithTopology(app,
73+
2, // clusters
74+
120, // nodes_per_cluster
75+
100, // devices_per_node,
76+
5*TB, // disksize)
77+
)
78+
tests.Assert(t, err == nil)
79+
app.Close()
80+
81+
// Gzip database
82+
var b bytes.Buffer
83+
gz := gzip.NewWriter(&b)
84+
dbData, err := ioutil.ReadFile(tmpfile)
85+
tests.Assert(t, err == nil)
86+
_, err = gz.Write(dbData)
87+
tests.Assert(t, err == nil)
88+
err = gz.Close()
89+
tests.Assert(t, err == nil)
90+
tests.Assert(t, b.Len() > 1024*MB)
91+
}
92+
2793
func TestBackupToKubeSecretBackupOnNonGet(t *testing.T) {
2894
tmpfile := tests.Tempfile()
2995
defer os.Remove(tmpfile)

extras/docker/fromsource/heketi-start.sh

+9-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,14 @@
11
#!/bin/sh
22

3-
if [ -f /backupdb/heketi.db ] ; then
4-
cp /backupdb/heketi.db /var/lib/heketi/heketi.db
3+
if [ -f /backupdb/heketi.db.gz ] ; then
4+
gunzip -c /backupdb/heketi.db.gz > /var/lib/heketi/heketi.db
5+
if [ $? -ne 0 ] ; then
6+
echo "Unable to copy database"
7+
exit 1
8+
fi
9+
echo "Copied backup db to /var/lib/heketi/heketi.db"
10+
elif [ -f /backupdb/heketi.db ] ; then
11+
cp /backupdb/heketi.db > /var/lib/heketi/heketi.db
512
if [ $? -ne 0 ] ; then
613
echo "Unable to copy database"
714
exit 1

extras/docker/rpi/heketi-start.sh

+9-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,14 @@
11
#!/bin/sh
22

3-
if [ -f /backupdb/heketi.db ] ; then
4-
cp /backupdb/heketi.db /var/lib/heketi/heketi.db
3+
if [ -f /backupdb/heketi.db.gz ] ; then
4+
gunzip -c /backupdb/heketi.db.gz > /var/lib/heketi/heketi.db
5+
if [ $? -ne 0 ] ; then
6+
echo "Unable to copy database"
7+
exit 1
8+
fi
9+
echo "Copied backup db to /var/lib/heketi/heketi.db"
10+
elif [ -f /backupdb/heketi.db ] ; then
11+
cp /backupdb/heketi.db > /var/lib/heketi/heketi.db
512
if [ $? -ne 0 ] ; then
613
echo "Unable to copy database"
714
exit 1

extras/kubernetes/heketi-start.sh

+9-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,14 @@
11
#!/bin/sh
22

3-
if [ -f /backupdb/heketi.db ] ; then
4-
cp /backupdb/heketi.db /var/lib/heketi/heketi.db
3+
if [ -f /backupdb/heketi.db.gz ] ; then
4+
gunzip -c /backupdb/heketi.db.gz > /var/lib/heketi/heketi.db
5+
if [ $? -ne 0 ] ; then
6+
echo "Unable to copy database"
7+
exit 1
8+
fi
9+
echo "Copied backup db to /var/lib/heketi/heketi.db"
10+
elif [ -f /backupdb/heketi.db ] ; then
11+
cp /backupdb/heketi.db > /var/lib/heketi/heketi.db
512
if [ $? -ne 0 ] ; then
613
echo "Unable to copy database"
714
exit 1

pkg/kubernetes/backupdb.go

+8-2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ package kubernetes
1111

1212
import (
1313
"bytes"
14+
"compress/gzip"
1415
"fmt"
1516
"os"
1617

@@ -66,10 +67,15 @@ func KubeBackupDbToSecret(db *bolt.DB) error {
6667
// Get a backup
6768
err = db.View(func(tx *bolt.Tx) error {
6869
var backup bytes.Buffer
69-
_, err := tx.WriteTo(&backup)
70+
71+
gz := gzip.NewWriter(&backup)
72+
_, err := tx.WriteTo(gz)
7073
if err != nil {
7174
return fmt.Errorf("Unable to access database: %v", err)
7275
}
76+
if err := gz.Close(); err != nil {
77+
return fmt.Errorf("Unable to close gzipped database: %v", err)
78+
}
7379

7480
// Create a secret with backup
7581
secret := &v1.Secret{}
@@ -78,7 +84,7 @@ func KubeBackupDbToSecret(db *bolt.DB) error {
7884
secret.APIVersion = "v1"
7985
secret.ObjectMeta.Name = dbSecretName
8086
secret.Data = map[string][]byte{
81-
"heketi.db": backup.Bytes(),
87+
"heketi.db.gz": backup.Bytes(),
8288
}
8389

8490
// Submit secret

pkg/kubernetes/backupdb_test.go

+20-4
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
package kubernetes
1111

1212
import (
13+
"bytes"
14+
"compress/gzip"
1315
"fmt"
1416
"io/ioutil"
1517
"os"
@@ -217,15 +219,22 @@ func TestBackupToKubeSecretVerifyBackup(t *testing.T) {
217219
secret, err := fakeclient.CoreV1().Secrets(ns).Get("heketi-db-backup")
218220
tests.Assert(t, err == nil)
219221

222+
// Gunzip
223+
b := bytes.NewReader(secret.Data["heketi.db.gz"])
224+
gzr, err := gzip.NewReader(b)
225+
tests.Assert(t, err == nil)
226+
newdbData, err := ioutil.ReadAll(gzr)
227+
tests.Assert(t, err == nil)
228+
220229
// Verify
221230
newdb := tests.Tempfile()
222231
defer os.Remove(newdb)
223-
err = ioutil.WriteFile(newdb, secret.Data["heketi.db"], 0644)
232+
err = ioutil.WriteFile(newdb, newdbData, 0644)
224233
tests.Assert(t, err == nil)
225234

226235
// Load new app with backup
227236
db.Close()
228-
db, err = bolt.Open(tmpfile, 0600, &bolt.Options{Timeout: 3 * time.Second})
237+
db, err = bolt.Open(newdb, 0600, &bolt.Options{Timeout: 3 * time.Second})
229238
tests.Assert(t, err == nil)
230239
defer db.Close()
231240

@@ -298,15 +307,22 @@ func TestBackupToKubeSecretVerifyBackupWithName(t *testing.T) {
298307
secret, err := fakeclient.CoreV1().Secrets(ns).Get(secretName)
299308
tests.Assert(t, err == nil)
300309

310+
// Gunzip
311+
b := bytes.NewReader(secret.Data["heketi.db.gz"])
312+
gzr, err := gzip.NewReader(b)
313+
tests.Assert(t, err == nil)
314+
newdbData, err := ioutil.ReadAll(gzr)
315+
tests.Assert(t, err == nil)
316+
301317
// Verify
302318
newdb := tests.Tempfile()
303319
defer os.Remove(newdb)
304-
err = ioutil.WriteFile(newdb, secret.Data["heketi.db"], 0644)
320+
err = ioutil.WriteFile(newdb, newdbData, 0644)
305321
tests.Assert(t, err == nil)
306322

307323
// Load new app with backup
308324
db.Close()
309-
db, err = bolt.Open(tmpfile, 0600, &bolt.Options{Timeout: 3 * time.Second})
325+
db, err = bolt.Open(newdb, 0600, &bolt.Options{Timeout: 3 * time.Second})
310326
tests.Assert(t, err == nil)
311327
defer db.Close()
312328

0 commit comments

Comments
 (0)