Skip to content

Commit 2eed3f0

Browse files
authored
Merge pull request #1420 from databus23/compression
Add compression to configmap storage driver
2 parents b0c113d + eb4b78b commit 2eed3f0

2 files changed

Lines changed: 67 additions & 2 deletions

File tree

pkg/storage/driver/cfgmaps.go

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,11 @@ limitations under the License.
1717
package driver // import "k8s.io/helm/pkg/storage/driver"
1818

1919
import (
20+
"bytes"
21+
"compress/gzip"
2022
"encoding/base64"
2123
"fmt"
24+
"io/ioutil"
2225
"log"
2326
"strconv"
2427
"time"
@@ -40,6 +43,8 @@ const ConfigMapsDriverName = "ConfigMap"
4043

4144
var b64 = base64.StdEncoding
4245

46+
var magicGzip = []byte{0x1f, 0x8b, 0x08}
47+
4348
// ConfigMaps is a wrapper around an implementation of a kubernetes
4449
// ConfigMapsInterface.
4550
type ConfigMaps struct {
@@ -254,13 +259,23 @@ func newConfigMapsObject(key string, rls *rspb.Release, lbs labels) (*api.Config
254259
}
255260

256261
// encodeRelease encodes a release returning a base64 encoded
257-
// binary protobuf encoding representation, or error.
262+
// gzipped binary protobuf encoding representation, or error.
258263
func encodeRelease(rls *rspb.Release) (string, error) {
259264
b, err := proto.Marshal(rls)
260265
if err != nil {
261266
return "", err
262267
}
263-
return b64.EncodeToString(b), nil
268+
var buf bytes.Buffer
269+
w, err := gzip.NewWriterLevel(&buf, gzip.BestCompression)
270+
if err != nil {
271+
return "", err
272+
}
273+
if _, err = w.Write(b); err != nil {
274+
return "", err
275+
}
276+
w.Close()
277+
278+
return b64.EncodeToString(buf.Bytes()), nil
264279
}
265280

266281
// decodeRelease decodes the bytes in data into a release
@@ -274,6 +289,21 @@ func decodeRelease(data string) (*rspb.Release, error) {
274289
return nil, err
275290
}
276291

292+
// For backwards compatibility with releases that were stored before
293+
// compression was introduced we skip decompression if the
294+
// gzip magic header is not found
295+
if bytes.Equal(b[0:3], magicGzip) {
296+
r, err := gzip.NewReader(bytes.NewReader(b))
297+
if err != nil {
298+
return nil, err
299+
}
300+
b2, err := ioutil.ReadAll(r)
301+
if err != nil {
302+
return nil, err
303+
}
304+
b = b2
305+
}
306+
277307
var rls rspb.Release
278308
// unmarshal protobuf bytes
279309
if err := proto.Unmarshal(b, &rls); err != nil {

pkg/storage/driver/cfgmaps_test.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,14 @@ limitations under the License.
1414
package driver
1515

1616
import (
17+
"encoding/base64"
1718
"reflect"
1819
"testing"
1920

21+
"github.com/gogo/protobuf/proto"
22+
2023
rspb "k8s.io/helm/pkg/proto/hapi/release"
24+
"k8s.io/kubernetes/pkg/api"
2125
)
2226

2327
func TestConfigMapName(t *testing.T) {
@@ -46,6 +50,37 @@ func TestConfigMapGet(t *testing.T) {
4650
}
4751
}
4852

53+
func TestUNcompressedConfigMapGet(t *testing.T) {
54+
vers := int32(1)
55+
name := "smug-pigeon"
56+
key := testKey(name, vers)
57+
rel := releaseStub(name, vers, rspb.Status_DEPLOYED)
58+
59+
// Create a test fixture which contains an uncompressed release
60+
cfgmap, err := newConfigMapsObject(key, rel, nil)
61+
if err != nil {
62+
t.Fatalf("Failed to create configmap: %s", err)
63+
}
64+
b, err := proto.Marshal(rel)
65+
if err != nil {
66+
t.Fatalf("Failed to marshal release: %s", err)
67+
}
68+
cfgmap.Data["release"] = base64.StdEncoding.EncodeToString(b)
69+
var mock MockConfigMapsInterface
70+
mock.objects = map[string]*api.ConfigMap{key: cfgmap}
71+
cfgmaps := NewConfigMaps(&mock)
72+
73+
// get release with key
74+
got, err := cfgmaps.Get(key)
75+
if err != nil {
76+
t.Fatalf("Failed to get release: %s", err)
77+
}
78+
// compare fetched release with original
79+
if !reflect.DeepEqual(rel, got) {
80+
t.Errorf("Expected {%q}, got {%q}", rel, got)
81+
}
82+
}
83+
4984
func TestConfigMapList(t *testing.T) {
5085
cfgmaps := newTestFixtureCfgMaps(t, []*rspb.Release{
5186
releaseStub("key-1", 1, rspb.Status_DELETED),

0 commit comments

Comments
 (0)