diff --git a/generator/configMap.go b/generator/configMap.go index d65811d..61cfd23 100644 --- a/generator/configMap.go +++ b/generator/configMap.go @@ -9,6 +9,7 @@ import ( "path/filepath" "regexp" "strings" + "unicode/utf8" "github.com/compose-spec/compose-go/types" corev1 "k8s.io/api/core/v1" @@ -140,7 +141,7 @@ func NewConfigMapFromDirectory(service types.ServiceConfig, appName, path string // cumulate the path to the WorkingDir path = filepath.Join(service.WorkingDir, path) path = filepath.Clean(path) - cm.AppendDir(path) + cm.AppenddDir(path) return cm } @@ -149,9 +150,17 @@ func (c *ConfigMap) AddData(key, value string) { c.Data[key] = value } +// AddBinaryData adds binary data to the configmap. Append or overwrite the value if the key already exists. +func (c *ConfigMap) AddBinaryData(key string, value []byte) { + if c.BinaryData == nil { + c.BinaryData = make(map[string][]byte) + } + c.BinaryData[key] = value +} + // AddFile adds files from given path to the configmap. It is not recursive, to add all files in a directory, // you need to call this function for each subdirectory. -func (c *ConfigMap) AppendDir(path string) { +func (c *ConfigMap) AppenddDir(path string) { // read all files in the path and add them to the configmap stat, err := os.Stat(path) if err != nil { @@ -165,6 +174,7 @@ func (c *ConfigMap) AppendDir(path string) { } for _, file := range files { if file.IsDir() { + utils.Warn("Subdirectories are ignored for the moment, skipping", filepath.Join(path, file.Name())) continue } path := filepath.Join(path, file.Name()) @@ -174,7 +184,12 @@ func (c *ConfigMap) AppendDir(path string) { } // remove the path from the file filename := filepath.Base(path) - c.AddData(filename, string(content)) + if utf8.Valid(content) { + c.AddData(filename, string(content)) + } else { + c.AddBinaryData(filename, content) + } + } } else { // add the file to the configmap @@ -182,7 +197,12 @@ func (c *ConfigMap) AppendDir(path string) { if err != nil { log.Fatal(err) } - c.AddData(filepath.Base(path), string(content)) + filename := filepath.Base(path) + if utf8.Valid(content) { + c.AddData(filename, string(content)) + } else { + c.AddBinaryData(filename, content) + } } } @@ -199,7 +219,12 @@ func (c *ConfigMap) AppendFile(path string) { if err != nil { log.Fatal(err) } - c.AddData(filepath.Base(path), string(content)) + if utf8.Valid(content) { + c.AddData(filepath.Base(path), string(content)) + } else { + c.AddBinaryData(filepath.Base(path), content) + } + } } diff --git a/generator/volume_test.go b/generator/volume_test.go index ef365be..700fa6d 100644 --- a/generator/volume_test.go +++ b/generator/volume_test.go @@ -2,8 +2,13 @@ package generator import ( "fmt" + "image" + "image/color" + "image/png" "katenary/generator/labels" + "log" "os" + "path/filepath" "testing" v1 "k8s.io/api/apps/v1" @@ -149,6 +154,73 @@ services: } } +func TestBinaryMount(t *testing.T) { + composeFile := ` +services: + web: + image: nginx + volumes: + - ./images/foo.png:/var/www/foo + labels: + %[1]s/configmap-files: |- + - ./images/foo.png +` + composeFile = fmt.Sprintf(composeFile, labels.KatenaryLabelPrefix) + tmpDir := setup(composeFile) + log.Println(tmpDir) + defer teardown(tmpDir) + + os.Mkdir(filepath.Join(tmpDir, "images"), 0o755) + + // create a png image + pngFile := tmpDir + "/images/foo.png" + w, h := 100, 100 + img := image.NewRGBA(image.Rect(0, 0, w, h)) + red := color.RGBA{255, 0, 0, 255} + for y := 0; y < h; y++ { + for x := 0; x < w; x++ { + img.Set(x, y, red) + } + } + + blue := color.RGBA{0, 0, 255, 255} + for y := 30; y < 70; y++ { + for x := 30; x < 70; x++ { + img.Set(x, y, blue) + } + } + currentDir, _ := os.Getwd() + os.Chdir(tmpDir) + defer os.Chdir(currentDir) + + f, err := os.Create(pngFile) + if err != nil { + t.Fatal(err) + } + png.Encode(f, img) + f.Close() + output := internalCompileTest(t, "-s", "templates/web/deployment.yaml") + d := v1.Deployment{} + yaml.Unmarshal([]byte(output), &d) + volumes := d.Spec.Template.Spec.Volumes + if len(volumes) != 1 { + t.Errorf("Expected 1 volume, got %d", len(volumes)) + } + + cm := corev1.ConfigMap{} + cmContent, err := helmTemplate(ConvertOptions{ + OutputDir: "chart", + }, "-s", "templates/web/statics/images/configmap.yaml") + yaml.Unmarshal([]byte(cmContent), &cm) + if im, ok := cm.BinaryData["foo.png"]; !ok { + t.Errorf("Expected foo.png to be in the configmap") + } else { + if len(im) == 0 { + t.Errorf("Expected image to be non-empty") + } + } +} + func TestBindFrom(t *testing.T) { composeFile := ` services: