diff --git a/docs/conversion.md b/docs/conversion.md index 2a805c01..5d9be45b 100644 --- a/docs/conversion.md +++ b/docs/conversion.md @@ -23,7 +23,7 @@ __Glossary:__ | cap_add, cap_drop | ✓ | ✓ | ✓ | Pod.Spec.Container.SecurityContext.Capabilities.Add/Drop | | | command | ✓ | ✓ | ✓ | Pod.Spec.Container.Command | | | configs | n | n | ✓ | | | -| configs: short-syntax | n | n | n | | Only create configMap | +| configs: short-syntax | n | n | ✓ | | Only create configMap | | configs: long-syntax | n | n | ✓ | | If target path is /, ignore this and only create configMap | | cgroup_parent | x | x | x | | Not supported within Kubernetes. See issue https://github.com/kubernetes/kubernetes/issues/11986 | | container_name | ✓ | ✓ | ✓ | Metadata.Name + Deployment.Spec.Containers.Name | | diff --git a/pkg/kobject/kobject.go b/pkg/kobject/kobject.go index 910f9ae3..17faeb8b 100644 --- a/pkg/kobject/kobject.go +++ b/pkg/kobject/kobject.go @@ -19,7 +19,9 @@ package kobject import ( dockerCliTypes "github.com/docker/cli/cli/compose/types" "github.com/docker/libcompose/yaml" + "github.com/pkg/errors" "k8s.io/kubernetes/pkg/api" + "path/filepath" ) // KomposeObject holds the generic struct of Kompose transformation @@ -164,3 +166,23 @@ type Volumes struct { PVCSize string // PVC size SelectorValue string // Value of the label selector } + +// GetConfigMapKeyFromMeta... +// given a source name ,find the file and extract the filename which will be act as ConfigMap key +// return "" if not found +func (s *ServiceConfig) GetConfigMapKeyFromMeta(name string) (string, error) { + if s.ConfigsMetaData == nil { + return "", errors.Errorf("config %s not found", name) + } + if _, ok := s.ConfigsMetaData[name]; !ok { + return "", errors.Errorf("config %s not found", name) + } + + config := s.ConfigsMetaData[name] + if config.External.External { + return "", errors.Errorf("config %s is external", name) + } + + return filepath.Base(config.File), nil + +} diff --git a/pkg/loader/compose/v3.go b/pkg/loader/compose/v3.go index e07f407d..3d9ed29b 100755 --- a/pkg/loader/compose/v3.go +++ b/pkg/loader/compose/v3.go @@ -798,18 +798,12 @@ func checkUnsupportedKeyForV3(composeObject *types.Config) []string { var keysFound []string for _, service := range composeObject.Services { - //For short syntax, volume mount path must be /, but this will cause pod create fail in kubernetes - //So we ignore this attribute for _, tmpConfig := range service.Configs { - if tmpConfig.Mode == nil { - keysFound = append(keysFound, "short syntax config") - } else { - if tmpConfig.GID != "" { - keysFound = append(keysFound, "long syntax config gid") - } - if tmpConfig.UID != "" { - keysFound = append(keysFound, "long syntax config uid") - } + if tmpConfig.GID != "" { + keysFound = append(keysFound, "long syntax config gid") + } + if tmpConfig.UID != "" { + keysFound = append(keysFound, "long syntax config uid") } } diff --git a/pkg/transformer/kubernetes/kubernetes.go b/pkg/transformer/kubernetes/kubernetes.go index 82f632ca..8c7401b2 100755 --- a/pkg/transformer/kubernetes/kubernetes.go +++ b/pkg/transformer/kubernetes/kubernetes.go @@ -155,32 +155,48 @@ func (k *Kubernetes) InitPodSpecWithConfigMap(name string, image string, service var volumeMounts []api.VolumeMount var volumes []api.Volume - if len(service.Configs) > 0 && service.Configs[0].Mode != nil { - //This is for LONG SYNTAX - for _, value := range service.Configs { - if value.Target == "/" { - log.Warnf("Long syntax config, target path can not be /") - continue - } - tmpKey := FormatFileName(value.Source) - volumeMounts = append(volumeMounts, - api.VolumeMount{ - Name: tmpKey, - MountPath: "/" + FormatFileName(value.Target), - }) + log.Debugf("fuck config: %+v", service.Configs) - tmpVolume := api.Volume{ - Name: tmpKey, - } - tmpVolume.ConfigMap = &api.ConfigMapVolumeSource{} - tmpVolume.ConfigMap.Name = tmpKey - var tmpMode int32 - tmpMode = int32(*value.Mode) - tmpVolume.ConfigMap.DefaultMode = &tmpMode - volumes = append(volumes, tmpVolume) + for _, value := range service.Configs { + cmVolName := FormatFileName(value.Source) + target := value.Target + if target == "" { + // short syntax, = / + target = "/" + value.Source } - } else { - //This is for SHORT SYNTAX, unsupported + subPath := filepath.Base(target) + + volSource := api.ConfigMapVolumeSource{} + volSource.Name = cmVolName + key, err := service.GetConfigMapKeyFromMeta(value.Source) + if err != nil { + log.Warnf("cannot parse config %s , %s", value.Source, err.Error()) + // mostly it's external + continue + } + volSource.Items = []api.KeyToPath{{ + Key: key, + Path: subPath, + }} + + if value.Mode != nil { + tmpMode := int32(*value.Mode) + volSource.DefaultMode = &tmpMode + } + + cmVol := api.Volume{ + Name: cmVolName, + VolumeSource: api.VolumeSource{ConfigMap: &volSource}, + } + + volumeMounts = append(volumeMounts, + api.VolumeMount{ + Name: cmVolName, + MountPath: target, + SubPath: subPath, + }) + volumes = append(volumes, cmVol) + } pod := api.PodSpec{ @@ -337,11 +353,8 @@ func (k *Kubernetes) InitConfigMapFromFile(name string, service kobject.ServiceC log.Fatalf("Unable to retrieve file: %s", err) } - originFileName := FormatFileName(fileName) - dataMap := make(map[string]string) - - dataMap[originFileName] = content + dataMap[filepath.Base(fileName)] = content configMapName := "" for key, tmpConfig := range service.ConfigsMetaData { diff --git a/script/test/cmd/tests.sh b/script/test/cmd/tests.sh index ad97d1b4..5cd034d7 100755 --- a/script/test/cmd/tests.sh +++ b/script/test/cmd/tests.sh @@ -882,7 +882,7 @@ convert::expect_success "$cmd" "/tmp/output-os.json" cmd="kompose convert --stdout -j -f $KOMPOSE_ROOT/script/test/fixtures/compose-v3.3-test/compose-config-short.yaml" sed -e "s;%VERSION%;$version;g" -e "s;%CMD%;$cmd;g" $KOMPOSE_ROOT/script/test/fixtures/compose-v3.3-test/output-k8s-config-short.json > /tmp/output-k8s.json -convert::expect_success_and_warning "$cmd" "/tmp/output-k8s.json" +convert::expect_success "$cmd" "/tmp/output-k8s.json" cmd="kompose convert --stdout -j -f $KOMPOSE_ROOT/script/test/fixtures/compose-v3.3-test/compose-config-short-warning.yaml" sed -e "s;%VERSION%;$version;g" -e "s;%CMD%;$cmd;g" $KOMPOSE_ROOT/script/test/fixtures/compose-v3.3-test/output-k8s-config-short-warning.json > /tmp/output-k8s.json @@ -917,7 +917,7 @@ convert::expect_success_and_warning "$cmd" "/tmp/output-os.json" cmd="kompose --provider openshift convert --stdout -j -f $KOMPOSE_ROOT/script/test/fixtures/compose-v3.3-test/compose-config-short.yaml" sed -e "s;%VERSION%;$version;g" -e "s;%CMD%;$cmd;g" $KOMPOSE_ROOT/script/test/fixtures/compose-v3.3-test/output-os-config-short.json > /tmp/output-os.json -convert::expect_success_and_warning "$cmd" "/tmp/output-os.json" +convert::expect_success "$cmd" "/tmp/output-os.json" cmd="kompose --provider openshift convert --stdout -j -f $KOMPOSE_ROOT/script/test/fixtures/compose-v3.3-test/compose-endpoint-mode-1.yaml" sed -e "s;%VERSION%;$version;g" -e "s;%CMD%;$cmd;g" $KOMPOSE_ROOT/script/test/fixtures/compose-v3.3-test/output-os-mode-1.json > /tmp/output-os.json diff --git a/script/test/fixtures/compose-v3.3-test/output-k8s-config-long-warning.json b/script/test/fixtures/compose-v3.3-test/output-k8s-config-long-warning.json index 7338ccbf..9624f7df 100644 --- a/script/test/fixtures/compose-v3.3-test/output-k8s-config-long-warning.json +++ b/script/test/fixtures/compose-v3.3-test/output-k8s-config-long-warning.json @@ -14,7 +14,7 @@ } }, "data": { - "my-config.txt": "aaaa" + "my_config.txt": "aaaa" } }, { @@ -59,8 +59,9 @@ "resources": {}, "volumeMounts": [ { - "mountPath": "/redis-config", - "name": "my-config" + "mountPath": "/redis_config", + "name": "my-config", + "subPath": "redis_config" } ] } @@ -70,8 +71,14 @@ "volumes": [ { "configMap": { - "name": "my-config", - "defaultMode": 288 + "defaultMode": 288, + "items": [ + { + "key": "my_config.txt", + "path": "redis_config" + } + ], + "name": "my-config" }, "name": "my-config" } diff --git a/script/test/fixtures/compose-v3.3-test/output-k8s-config-long.json b/script/test/fixtures/compose-v3.3-test/output-k8s-config-long.json index 7338ccbf..9624f7df 100644 --- a/script/test/fixtures/compose-v3.3-test/output-k8s-config-long.json +++ b/script/test/fixtures/compose-v3.3-test/output-k8s-config-long.json @@ -14,7 +14,7 @@ } }, "data": { - "my-config.txt": "aaaa" + "my_config.txt": "aaaa" } }, { @@ -59,8 +59,9 @@ "resources": {}, "volumeMounts": [ { - "mountPath": "/redis-config", - "name": "my-config" + "mountPath": "/redis_config", + "name": "my-config", + "subPath": "redis_config" } ] } @@ -70,8 +71,14 @@ "volumes": [ { "configMap": { - "name": "my-config", - "defaultMode": 288 + "defaultMode": 288, + "items": [ + { + "key": "my_config.txt", + "path": "redis_config" + } + ], + "name": "my-config" }, "name": "my-config" } diff --git a/script/test/fixtures/compose-v3.3-test/output-k8s-config-short-warning.json b/script/test/fixtures/compose-v3.3-test/output-k8s-config-short-warning.json index 50c5c71e..e85b19fb 100644 --- a/script/test/fixtures/compose-v3.3-test/output-k8s-config-short-warning.json +++ b/script/test/fixtures/compose-v3.3-test/output-k8s-config-short-warning.json @@ -14,7 +14,7 @@ } }, "data": { - "my-config.txt": "aaaa" + "my_config.txt": "aaaa" } }, { @@ -56,12 +56,32 @@ "image": "redis:latest", "imagePullPolicy": "", "name": "redis", - "resources": {} + "resources": {}, + "volumeMounts": [ + { + "mountPath": "/my_config", + "name": "my-config", + "subPath": "my_config" + } + ] } ], "restartPolicy": "Always", "serviceAccountName": "", - "volumes": null + "volumes": [ + { + "configMap": { + "items": [ + { + "key": "my_config.txt", + "path": "my_config" + } + ], + "name": "my-config" + }, + "name": "my-config" + } + ] } } }, diff --git a/script/test/fixtures/compose-v3.3-test/output-k8s-config-short.json b/script/test/fixtures/compose-v3.3-test/output-k8s-config-short.json index 50c5c71e..e85b19fb 100644 --- a/script/test/fixtures/compose-v3.3-test/output-k8s-config-short.json +++ b/script/test/fixtures/compose-v3.3-test/output-k8s-config-short.json @@ -14,7 +14,7 @@ } }, "data": { - "my-config.txt": "aaaa" + "my_config.txt": "aaaa" } }, { @@ -56,12 +56,32 @@ "image": "redis:latest", "imagePullPolicy": "", "name": "redis", - "resources": {} + "resources": {}, + "volumeMounts": [ + { + "mountPath": "/my_config", + "name": "my-config", + "subPath": "my_config" + } + ] } ], "restartPolicy": "Always", "serviceAccountName": "", - "volumes": null + "volumes": [ + { + "configMap": { + "items": [ + { + "key": "my_config.txt", + "path": "my_config" + } + ], + "name": "my-config" + }, + "name": "my-config" + } + ] } } }, diff --git a/script/test/fixtures/compose-v3.3-test/output-os-config-long.json b/script/test/fixtures/compose-v3.3-test/output-os-config-long.json index de47f093..5cdb2a30 100644 --- a/script/test/fixtures/compose-v3.3-test/output-os-config-long.json +++ b/script/test/fixtures/compose-v3.3-test/output-os-config-long.json @@ -14,7 +14,7 @@ } }, "data": { - "my-config.txt": "aaaa" + "my_config.txt": "aaaa" } }, { @@ -71,6 +71,12 @@ "name": "my-config", "configMap": { "name": "my-config", + "items": [ + { + "key": "my_config.txt", + "path": "redis_config" + } + ], "defaultMode": 288 } } @@ -83,7 +89,8 @@ "volumeMounts": [ { "name": "my-config", - "mountPath": "/redis-config" + "mountPath": "/redis_config", + "subPath": "redis_config" } ] } diff --git a/script/test/fixtures/compose-v3.3-test/output-os-config-short.json b/script/test/fixtures/compose-v3.3-test/output-os-config-short.json index 15bd6c52..e1638edb 100644 --- a/script/test/fixtures/compose-v3.3-test/output-os-config-short.json +++ b/script/test/fixtures/compose-v3.3-test/output-os-config-short.json @@ -14,7 +14,7 @@ } }, "data": { - "my-config.txt": "aaaa" + "my_config.txt": "aaaa" } }, { @@ -66,11 +66,32 @@ } }, "spec": { + "volumes": [ + { + "name": "my-config", + "configMap": { + "name": "my-config", + "items": [ + { + "key": "my_config.txt", + "path": "my_config" + } + ] + } + } + ], "containers": [ { "name": "redis", "image": " ", - "resources": {} + "resources": {}, + "volumeMounts": [ + { + "name": "my-config", + "mountPath": "/my_config", + "subPath": "my_config" + } + ] } ], "restartPolicy": "Always" diff --git a/script/test/fixtures/merge-multiple-compose/output-other-toplevel-merge-template.json b/script/test/fixtures/merge-multiple-compose/output-other-toplevel-merge-template.json index b38fc575..483ccdac 100644 --- a/script/test/fixtures/merge-multiple-compose/output-other-toplevel-merge-template.json +++ b/script/test/fixtures/merge-multiple-compose/output-other-toplevel-merge-template.json @@ -14,7 +14,7 @@ } }, "data": { - "first-config.txt": "First config\n" + "first_config.txt": "First config\n" } }, { @@ -61,8 +61,9 @@ "resources": {}, "volumeMounts": [ { - "mountPath": "/nginx.conf", - "name": "firstconfig" + "mountPath": "/etc/nginx.conf", + "name": "firstconfig", + "subPath": "nginx.conf" }, { "mountPath": "/var/www/nginx", @@ -76,8 +77,14 @@ "volumes": [ { "configMap": { - "name": "firstconfig", - "defaultMode": 644 + "defaultMode": 644, + "items": [ + { + "key": "first_config.txt", + "path": "nginx.conf" + } + ], + "name": "firstconfig" }, "name": "firstconfig" }, @@ -126,7 +133,7 @@ } }, "data": { - "second-config.txt": "Second config\n" + "second_config.txt": "Second config\n" } }, { @@ -173,8 +180,9 @@ "resources": {}, "volumeMounts": [ { - "mountPath": "/nginx.conf", - "name": "secondconfig" + "mountPath": "/etc/nginx.conf", + "name": "secondconfig", + "subPath": "nginx.conf" }, { "mountPath": "/var/www/nginx", @@ -188,8 +196,14 @@ "volumes": [ { "configMap": { - "name": "secondconfig", - "defaultMode": 644 + "defaultMode": 644, + "items": [ + { + "key": "second_config.txt", + "path": "nginx.conf" + } + ], + "name": "secondconfig" }, "name": "secondconfig" }, diff --git a/script/test/fixtures/merge-multiple-compose/output-other-toplevel-override-template.json b/script/test/fixtures/merge-multiple-compose/output-other-toplevel-override-template.json index 1b3c5377..93494c0c 100644 --- a/script/test/fixtures/merge-multiple-compose/output-other-toplevel-override-template.json +++ b/script/test/fixtures/merge-multiple-compose/output-other-toplevel-override-template.json @@ -14,7 +14,7 @@ } }, "data": { - "second-config.txt": "Second config\n" + "second_config.txt": "Second config\n" } }, { @@ -61,8 +61,9 @@ "resources": {}, "volumeMounts": [ { - "mountPath": "/nginx.conf", - "name": "firstconfig" + "mountPath": "/etc/nginx.conf", + "name": "firstconfig", + "subPath": "nginx.conf" }, { "mountPath": "/var/www/nginx", @@ -76,8 +77,14 @@ "volumes": [ { "configMap": { - "name": "firstconfig", - "defaultMode": 644 + "defaultMode": 644, + "items": [ + { + "key": "second_config.txt", + "path": "nginx.conf" + } + ], + "name": "firstconfig" }, "name": "firstconfig" },