diff --git a/pkg/loader/compose/v3.go b/pkg/loader/compose/v3.go index 74c86492..be68bafa 100644 --- a/pkg/loader/compose/v3.go +++ b/pkg/loader/compose/v3.go @@ -29,8 +29,25 @@ import ( log "github.com/Sirupsen/logrus" "github.com/kubernetes-incubator/kompose/pkg/kobject" "github.com/pkg/errors" + "os" ) +// converts os.Environ() ([]string) to map[string]string +// based on https://github.com/docker/cli/blob/5dd30732a23bbf14db1c64d084ae4a375f592cfa/cli/command/stack/deploy_composefile.go#L143 +func buildEnvironment() (map[string]string, error) { + env := os.Environ() + result := make(map[string]string, len(env)) + for _, s := range env { + // if value is empty, s is like "K=", not "K". + if !strings.Contains(s, "=") { + return result, errors.Errorf("unexpected environment %q", s) + } + kv := strings.SplitN(s, "=", 2) + result[kv[0]] = kv[1] + } + return result, nil +} + // The purpose of this is not to deploy, but to be able to parse // v3 of Docker Compose into a suitable format. In this case, whatever is returned // by docker/cli's ServiceConfig @@ -63,12 +80,17 @@ func parseV3(files []string) (kobject.KomposeObject, error) { Config: parsedComposeFile, } + // get environment variables + env, err := buildEnvironment() + if err != nil { + return kobject.KomposeObject{}, errors.Wrap(err, "cannot build environment variables") + } + // Config details - // Environment is nil as docker/cli loads the appropriate environmental values itself configDetails := types.ConfigDetails{ WorkingDir: workingDir, ConfigFiles: []types.ConfigFile{configFile}, - Environment: nil, + Environment: env, } // Actual config diff --git a/script/test/cmd/tests.sh b/script/test/cmd/tests.sh index d7257a3d..d56afab3 100755 --- a/script/test/cmd/tests.sh +++ b/script/test/cmd/tests.sh @@ -274,6 +274,9 @@ convert::expect_success "kompose convert --stdout -j -f $KOMPOSE_ROOT/script/tes # Test environment variables are passed correctly convert::expect_success "kompose convert --stdout -j -f $KOMPOSE_ROOT/script/test/fixtures/v3/docker-compose-env.yaml" "$KOMPOSE_ROOT/script/test/fixtures/v3/output-env-k8s.json" +# Test environment variables substitution +convert::expect_success "kompose convert --stdout -j -f $KOMPOSE_ROOT/script/test/fixtures/v3/docker-compose-env-subs.yaml" "$KOMPOSE_ROOT/script/test/fixtures/v3/output-env-subs.json" + # Test that two files that are different versions fail convert::expect_failure "kompose convert --stdout -j -f $KOMPOSE_ROOT/script/test/fixtures/v3/docker-compose.yaml -f $KOMPOSE_ROOT/script/test/fixtures/etherpad/docker-compose.yml" diff --git a/script/test/fixtures/v3/docker-compose-env-subs.yaml b/script/test/fixtures/v3/docker-compose-env-subs.yaml new file mode 100644 index 00000000..dc1bf711 --- /dev/null +++ b/script/test/fixtures/v3/docker-compose-env-subs.yaml @@ -0,0 +1,6 @@ +version: '3' +services: + foo: + image: foo/bar:latest + environment: + FOO: $foo diff --git a/script/test/fixtures/v3/output-env-subs.json b/script/test/fixtures/v3/output-env-subs.json new file mode 100644 index 00000000..a81b9dd0 --- /dev/null +++ b/script/test/fixtures/v3/output-env-subs.json @@ -0,0 +1,74 @@ +{ + "kind": "List", + "apiVersion": "v1", + "metadata": {}, + "items": [ + { + "kind": "Service", + "apiVersion": "v1", + "metadata": { + "name": "foo", + "creationTimestamp": null, + "labels": { + "io.kompose.service": "foo" + } + }, + "spec": { + "ports": [ + { + "name": "headless", + "port": 55555, + "targetPort": 0 + } + ], + "selector": { + "io.kompose.service": "foo" + }, + "clusterIP": "None" + }, + "status": { + "loadBalancer": {} + } + }, + { + "kind": "Deployment", + "apiVersion": "extensions/v1beta1", + "metadata": { + "name": "foo", + "creationTimestamp": null, + "labels": { + "io.kompose.service": "foo" + } + }, + "spec": { + "replicas": 1, + "template": { + "metadata": { + "creationTimestamp": null, + "labels": { + "io.kompose.service": "foo" + } + }, + "spec": { + "containers": [ + { + "name": "foo", + "image": "foo/bar:latest", + "env": [ + { + "name": "FOO", + "value": "bar" + } + ], + "resources": {} + } + ], + "restartPolicy": "Always" + } + }, + "strategy": {} + }, + "status": {} + } + ] +}