Add service.env_file support

Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
This commit is contained in:
Nicolas De Loof 2020-08-11 15:48:12 +02:00
parent 7d927ebe4f
commit 5ed328d8df
No known key found for this signature in database
GPG Key ID: 9858809D6F8F6E7E
5 changed files with 85 additions and 22 deletions

View File

@ -29,6 +29,7 @@ require (
github.com/gorilla/mux v1.7.3 // indirect github.com/gorilla/mux v1.7.3 // indirect
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed // indirect github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed // indirect
github.com/jinzhu/gorm v1.9.12 // indirect github.com/jinzhu/gorm v1.9.12 // indirect
github.com/joho/godotenv v1.3.0
github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 // indirect github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 // indirect
github.com/lib/pq v1.3.0 // indirect github.com/lib/pq v1.3.0 // indirect
github.com/manifoldco/promptui v0.7.0 github.com/manifoldco/promptui v0.7.0

View File

@ -26,6 +26,36 @@ func TestSimpleConvert(t *testing.T) {
golden.Assert(t, result, expected) golden.Assert(t, result, expected)
} }
func TestEnvFile(t *testing.T) {
template := convertYaml(t, "test", `
services:
foo:
image: hello_world
env_file:
- testdata/input/envfile
`)
def := template.Resources["FooTaskDefinition"].(*ecs.TaskDefinition)
env := def.ContainerDefinitions[0].Environment
assert.Equal(t, env[0].Name, "FOO")
assert.Equal(t, env[0].Value, "BAR")
}
func TestEnvFileAndEnv(t *testing.T) {
template := convertYaml(t, "test", `
services:
foo:
image: hello_world
env_file:
- testdata/input/envfile
environment:
- "FOO=ZOT"
`)
def := template.Resources["FooTaskDefinition"].(*ecs.TaskDefinition)
env := def.ContainerDefinitions[0].Environment
assert.Equal(t, env[0].Name, "FOO")
assert.Equal(t, env[0].Value, "ZOT")
}
func TestRollingUpdateLimits(t *testing.T) { func TestRollingUpdateLimits(t *testing.T) {
template := convertYaml(t, "test", ` template := convertYaml(t, "test", `
services: services:

View File

@ -26,6 +26,7 @@ var compatibleComposeAttributes = []string{
"services.deploy.update_config.parallelism", "services.deploy.update_config.parallelism",
"services.entrypoint", "services.entrypoint",
"services.environment", "services.environment",
"services.env_file",
"service.image", "service.image",
"services.init", "services.init",
"services.healthcheck", "services.healthcheck",

View File

@ -3,13 +3,13 @@ package backend
import ( import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"os"
"path/filepath"
"sort" "sort"
"strconv" "strconv"
"strings" "strings"
"time" "time"
"github.com/docker/ecs-plugin/secrets"
"github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws"
ecsapi "github.com/aws/aws-sdk-go/service/ecs" ecsapi "github.com/aws/aws-sdk-go/service/ecs"
"github.com/awslabs/goformation/v4/cloudformation" "github.com/awslabs/goformation/v4/cloudformation"
@ -18,6 +18,8 @@ import (
"github.com/compose-spec/compose-go/types" "github.com/compose-spec/compose-go/types"
"github.com/docker/cli/opts" "github.com/docker/cli/opts"
"github.com/docker/ecs-plugin/pkg/compose" "github.com/docker/ecs-plugin/pkg/compose"
"github.com/docker/ecs-plugin/secrets"
"github.com/joho/godotenv"
) )
const secretsInitContainerImage = "docker/ecs-secrets-sidecar" const secretsInitContainerImage = "docker/ecs-secrets-sidecar"
@ -121,6 +123,11 @@ func Convert(project *types.Project, service types.ServiceConfig) (*ecs.TaskDefi
}) })
} }
pairs, err := createEnvironment(project, service)
if err != nil {
return nil, err
}
containers = append(containers, ecs.TaskDefinition_ContainerDefinition{ containers = append(containers, ecs.TaskDefinition_ContainerDefinition{
Command: service.Command, Command: service.Command,
DisableNetworking: service.NetworkMode == "none", DisableNetworking: service.NetworkMode == "none",
@ -129,7 +136,7 @@ func Convert(project *types.Project, service types.ServiceConfig) (*ecs.TaskDefi
DnsServers: service.DNS, DnsServers: service.DNS,
DockerSecurityOptions: service.SecurityOpt, DockerSecurityOptions: service.SecurityOpt,
EntryPoint: service.Entrypoint, EntryPoint: service.Entrypoint,
Environment: toKeyValuePair(service.Environment), Environment: pairs,
Essential: true, Essential: true,
ExtraHosts: toHostEntryPtr(service.ExtraHosts), ExtraHosts: toHostEntryPtr(service.ExtraHosts),
FirelensConfiguration: nil, FirelensConfiguration: nil,
@ -173,6 +180,48 @@ func Convert(project *types.Project, service types.ServiceConfig) (*ecs.TaskDefi
}, nil }, nil
} }
func createEnvironment(project *types.Project, service types.ServiceConfig) ([]ecs.TaskDefinition_KeyValuePair, error) {
environment := map[string]*string{}
for _, f := range service.EnvFile {
if !filepath.IsAbs(f) {
f = filepath.Join(project.WorkingDir, f)
}
if _, err := os.Stat(f); os.IsNotExist(err) {
return nil, err
}
file, err := os.Open(f)
if err != nil {
return nil, err
}
defer file.Close()
env, err := godotenv.Parse(file)
if err != nil {
return nil, err
}
for k, v := range env {
environment[k] = &v
}
}
for k, v := range service.Environment {
environment[k] = v
}
var pairs []ecs.TaskDefinition_KeyValuePair
for k, v := range environment {
name := k
var value string
if v != nil {
value = *v
}
pairs = append(pairs, ecs.TaskDefinition_KeyValuePair{
Name: name,
Value: value,
})
}
return pairs, nil
}
func toTags(labels types.Labels) []tags.Tag { func toTags(labels types.Labels) []tags.Tag {
t := []tags.Tag{} t := []tags.Tag{}
for n, v := range labels { for n, v := range labels {
@ -391,25 +440,6 @@ func toHostEntryPtr(hosts types.HostsList) []ecs.TaskDefinition_HostEntry {
return e return e
} }
func toKeyValuePair(environment types.MappingWithEquals) []ecs.TaskDefinition_KeyValuePair {
if environment == nil || len(environment) == 0 {
return nil
}
pairs := []ecs.TaskDefinition_KeyValuePair{}
for k, v := range environment {
name := k
var value string
if v != nil {
value = *v
}
pairs = append(pairs, ecs.TaskDefinition_KeyValuePair{
Name: name,
Value: value,
})
}
return pairs
}
func getRepoCredentials(service types.ServiceConfig) *ecs.TaskDefinition_RepositoryCredentials { func getRepoCredentials(service types.ServiceConfig) *ecs.TaskDefinition_RepositoryCredentials {
// extract registry and namespace string from image name // extract registry and namespace string from image name
for key, value := range service.Extensions { for key, value := range service.Extensions {

View File

@ -0,0 +1 @@
FOO=BAR