Skip to content

Commit

Permalink
Merge pull request #71 from stormcat24/feature/env_file
Browse files Browse the repository at this point in the history
support env_file
  • Loading branch information
Akinori Yamada committed Dec 28, 2015
2 parents bf2b075 + fc7c8e3 commit 8f434fc
Show file tree
Hide file tree
Showing 8 changed files with 196 additions and 15 deletions.
4 changes: 4 additions & 0 deletions Makefile
Expand Up @@ -19,6 +19,10 @@ deps-test:
go get github.com/golang/lint/golint
go get github.com/jstemmer/go-junit-report

update:
rm -rf ./vendor
GO15VENDOREXPERIMENT=1 glide update --cache

build:
GO15VENDOREXPERIMENT=1 go build -o bin/ecs-formation main.go

Expand Down
14 changes: 14 additions & 0 deletions README.md
Expand Up @@ -234,6 +234,20 @@ You can set value for these parameters by using `-p` option.
ecs-formation task -p NGINX_VERSION=1.0 -p NGINX_PORT=80 plan your-web-task
```
#### env_file
You can use `env_file` like docker-compose. https://docs.docker.com/compose/compose-file/#env-file
```Ruby
nginx:
image: stormcat24/nginx:${NGINX_VERSION}
ports:
- 80:${NGINX_PORT}
env_file:
- ./test1.env
- ../test2.env
```
License
===
See [LICENSE](LICENSE).
Expand Down
17 changes: 7 additions & 10 deletions glide.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion glide.yaml
Expand Up @@ -10,7 +10,7 @@ import:
- package: gopkg.in/yaml.v2
version: 7ad95dd0798a40da1ccdff6dff35fd177b5edf40
- package: github.com/aws/aws-sdk-go
ref: v1.0.6
ref: v1.0.7
subpackages:
- aws
- private/endpoints
Expand Down Expand Up @@ -39,3 +39,5 @@ import:
version: f4e566c536cf69158e808ec28ef4182a37fdc981
- package: github.com/naoina/go-stringutil
version: 360db0db4b01d34e12a2ec042c09e7d37fece761
- package: github.com/joho/godotenv
version: 4ed13390c0acd2ff4e371e64d8b97c8954138243
2 changes: 1 addition & 1 deletion operation/version.go
@@ -1,3 +1,3 @@
package operation

const Version string = "0.2.0-RC2"
const Version string = "0.2.0-RC3"
42 changes: 41 additions & 1 deletion task/schema.go
Expand Up @@ -3,7 +3,9 @@ package task
import (
"errors"
"fmt"
"github.com/joho/godotenv"
"gopkg.in/yaml.v2"
"path/filepath"
)

type TaskDefinition struct {
Expand All @@ -16,6 +18,7 @@ type ContainerDefinition struct {
Image string `yaml:"image"`
Ports []string `yaml:"ports"`
Environment map[string]string `yaml:"environment"`
EnvFiles []string `yaml:"env_file"`
Links []string `yaml:"links"`
Volumes []string `yaml:"volumes"`
VolumesFrom []string `yaml:"volumes_from"`
Expand Down Expand Up @@ -45,7 +48,7 @@ type Ulimit struct {
Hard int64 `yaml:"hard"`
}

func CreateTaskDefinition(taskDefName string, data string) (*TaskDefinition, error) {
func CreateTaskDefinition(taskDefName string, data string, basedir string) (*TaskDefinition, error) {

containerMap := map[string]ContainerDefinition{}
if err := yaml.Unmarshal([]byte(data), &containerMap); err != nil {
Expand All @@ -56,6 +59,33 @@ func CreateTaskDefinition(taskDefName string, data string) (*TaskDefinition, err
for name, container := range containerMap {
con := container
con.Name = name

environment := map[string]string{}
if len(container.EnvFiles) > 0 {
for _, envfile := range container.EnvFiles {
var path string
if filepath.IsAbs(envfile) {
path = envfile
} else {
path = fmt.Sprintf("%s/%s", basedir, envfile)
}

envmap, err := readEnvFile(path)
if err != nil {
return nil, err
}

for key, value := range envmap {
environment[key] = value
}
}
}

for key, value := range container.Environment {
environment[key] = value
}

con.Environment = environment
containers[name] = &con
}

Expand All @@ -66,3 +96,13 @@ func CreateTaskDefinition(taskDefName string, data string) (*TaskDefinition, err

return &taskDef, nil
}

func readEnvFile(envpath string) (map[string]string, error) {

envmap, err := godotenv.Read(envpath)
if err != nil {
return map[string]string{}, err
}

return envmap, nil
}
8 changes: 6 additions & 2 deletions task/task.go
Expand Up @@ -55,7 +55,7 @@ func (self *TaskDefinitionController) searchTaskDefinitions(projectDir string) (
taskDefMap := map[string]*TaskDefinition{}
filePattern := regexp.MustCompile(`^.+\/(.+)\.yml$`)

filepath.Walk(taskDir, func(path string, info os.FileInfo, err error) error {
err := filepath.Walk(taskDir, func(path string, info os.FileInfo, err error) error {
if info.IsDir() || !strings.HasSuffix(path, ".yml") {
return nil
}
Expand All @@ -69,7 +69,7 @@ func (self *TaskDefinitionController) searchTaskDefinitions(projectDir string) (
tokens := filePattern.FindStringSubmatch(path)
taskDefName := tokens[1]

taskDefinition, err := CreateTaskDefinition(taskDefName, merged)
taskDefinition, err := CreateTaskDefinition(taskDefName, merged, filepath.Dir(path))
if err != nil {
return err
}
Expand All @@ -79,6 +79,10 @@ func (self *TaskDefinitionController) searchTaskDefinitions(projectDir string) (
return nil
})

if err != nil {
return taskDefMap, err
}

return taskDefMap, nil
}

Expand Down
120 changes: 120 additions & 0 deletions task/task_test.go
@@ -1,6 +1,9 @@
package task

import (
"fmt"
"io/ioutil"
"path/filepath"
"testing"
)

Expand Down Expand Up @@ -85,6 +88,7 @@ func TestCreateContainerDefinition(t *testing.T) {
ExtraHosts: []string{
"host1:192.168.1.100",
},
Hostname: "example.com",
LogDriver: "syslog",
LogOpt: map[string]string{
"syslog-address": "tcp://192.168.0.42:123",
Expand Down Expand Up @@ -300,3 +304,119 @@ func TestCreateContainerDefinition(t *testing.T) {
}

}

func TestReadEnvFileEnvFormat(t *testing.T) {

f, _ := ioutil.TempFile("", "TestReadEnvFileEnvFormat.env")
f.WriteString(`
PARAM1=VALUE1_env
PARAM2=VALUE2_env
`)
defer f.Close()

actual, err := readEnvFile(f.Name())
if err != nil {
t.Fatalf("cannot open file.")
}

if 2 != len(actual) {
t.Fatalf("len: expect = %v, but actual = %v", 2, len(actual))
}

if val, ok := actual["PARAM1"]; ok {
if "VALUE1_env" != val {
t.Errorf("actual[PARAM1]: expect = %v, but actual = %v", "VALUE1_env", val)
}
} else {
t.Errorf("actual[PARAM1]: not found")
}

}

func TestReadEnvFileYamlFormat(t *testing.T) {

f, _ := ioutil.TempFile("", "TestReadEnvFileYamlFormat.env")
f.WriteString(`
PARAM1: VALUE1_env
PARAM2: VALUE2_env
`)
defer f.Close()

actual, err := readEnvFile(f.Name())
if err != nil {
t.Fatalf("cannot open file.")
}

if 2 != len(actual) {
t.Fatalf("len: expect = %v, but actual = %v", 2, len(actual))
}

if val, ok := actual["PARAM1"]; ok {
if "VALUE1_env" != val {
t.Errorf("actual[PARAM1]: expect = %v, but actual = %v", "VALUE1_env", val)
}
} else {
t.Errorf("actual[PARAM1]: not found")
}

}

func TestCreateTaskDefinition(t *testing.T) {

f, _ := ioutil.TempFile("", "TestCreateTaskDefinition.env")
f.WriteString(`
PARAM2: VALUE2_env
PARAM3: VALUE3_env
`)
defer f.Close()

yaml := fmt.Sprintf(`
nginx:
image: nginx:latest
ports:
- 80:80
env_file:
- %s
environment:
PARAM1: un_override_value
PARAM2: override_value
memory: 1024
cpu_units: 1024
essential: true
`, f.Name())

taskdef, err := CreateTaskDefinition("test-web", yaml, filepath.Dir(f.Name()))
if err != nil {
t.Fatal(err)
}

if "test-web" != taskdef.Name {
t.Errorf("Name: expect = %v, but actual = %v", "test-web", taskdef.Name)
}

if con, ok := taskdef.ContainerDefinitions["nginx"]; ok {
if "nginx" != con.Name {
t.Errorf("Name: expect = %v, but actual = %v", "nginx", con.Name)
}

value1, _ := con.Environment["PARAM1"]
value2, _ := con.Environment["PARAM2"]
value3, _ := con.Environment["PARAM3"]

if "un_override_value" != value1 {
t.Errorf("con.Environment[%v]: expect = %v, but actual = %v", "PARAM1", "un_override_value", value1)
}

if "override_value" != value2 {
t.Errorf("con.Environment[%v]: expect = %v, but actual = %v", "PARAM2", "override_value", value2)
}

if "VALUE3_env" != value3 {
t.Errorf("con.Environment[%v]: expect = %v, but actual = %v", "PARAM3", "override_value", value3)
}

} else {
t.Errorf("ContainerDefinitions[nginx]: not found")
}

}

0 comments on commit 8f434fc

Please sign in to comment.