@@ -3,6 +3,7 @@ package packager
3
3
import (
4
4
"bytes"
5
5
"fmt"
6
+ "io"
6
7
"io/ioutil"
7
8
"os"
8
9
"os/user"
@@ -27,7 +28,7 @@ import (
27
28
// Init is the entrypoint initialization function.
28
29
// It generates a new application definition based on the provided parameters
29
30
// and returns the path to the created application definition.
30
- func Init (name string , composeFile string ) (string , error ) {
31
+ func Init (errWriter io. Writer , name string , composeFile string ) (string , error ) {
31
32
if err := internal .ValidateAppName (name ); err != nil {
32
33
return "" , err
33
34
}
@@ -48,7 +49,7 @@ func Init(name string, composeFile string) (string, error) {
48
49
if composeFile == "" {
49
50
err = initFromScratch (name )
50
51
} else {
51
- err = initFromComposeFile (name , composeFile )
52
+ err = initFromComposeFile (errWriter , name , composeFile )
52
53
}
53
54
if err != nil {
54
55
return "" , err
@@ -79,22 +80,52 @@ func checkComposeFileVersion(compose map[string]interface{}) error {
79
80
return schema .Validate (compose , fmt .Sprintf ("%v" , version ))
80
81
}
81
82
82
- func initFromComposeFile (name string , composeFile string ) error {
83
- logrus .Debugf ("Initializing from compose file %s" , composeFile )
84
-
85
- dirName := internal .DirNameFromAppName (name )
86
-
87
- composeRaw , err := ioutil .ReadFile (composeFile )
88
- if err != nil {
89
- return errors .Wrap (err , "failed to read compose file" )
83
+ func getEnvFiles (svcName string , envFileEntry interface {}) ([]string , error ) {
84
+ var envFiles []string
85
+ switch envFileEntry .(type ) {
86
+ case string :
87
+ envFiles = append (envFiles , envFileEntry .(string ))
88
+ case []interface {}:
89
+ for _ , env := range envFileEntry .([]interface {}) {
90
+ envFiles = append (envFiles , env .(string ))
91
+ }
92
+ default :
93
+ return nil , fmt .Errorf ("unknown entries in 'env_file' for service %s -> %v" ,
94
+ svcName , envFileEntry )
90
95
}
91
- cfgMap , err := composeloader .ParseYAML (composeRaw )
92
- if err != nil {
93
- return errors .Wrap (err , "failed to parse compose file" )
96
+ return envFiles , nil
97
+ }
98
+
99
+ func checkEnvFiles (errWriter io.Writer , appName string , cfgMap map [string ]interface {}) error {
100
+ services := cfgMap ["services" ]
101
+ servicesMap , ok := services .(map [string ]interface {})
102
+ if ! ok {
103
+ return fmt .Errorf ("invalid Compose file" )
94
104
}
95
- if err := checkComposeFileVersion (cfgMap ); err != nil {
96
- return err
105
+ for svcName , svc := range servicesMap {
106
+ svcContent , ok := svc .(map [string ]interface {})
107
+ if ! ok {
108
+ return fmt .Errorf ("invalid service %q" , svcName )
109
+ }
110
+ envFileEntry , ok := svcContent ["env_file" ]
111
+ if ! ok {
112
+ continue
113
+ }
114
+ envFiles , err := getEnvFiles (svcName , envFileEntry )
115
+ if err != nil {
116
+ return errors .Wrap (err , "invalid Compose file" )
117
+ }
118
+ for _ , envFilePath := range envFiles {
119
+ fmt .Fprintf (errWriter ,
120
+ "%s.env_file %q will not be copied into %s.dockerapp. " +
121
+ "Please copy it manually and update the path accordingly in the compose file.\n " ,
122
+ svcName , envFilePath , appName )
123
+ }
97
124
}
125
+ return nil
126
+ }
127
+
128
+ func getParamsFromDefaultEnvFile (composeFile string , composeRaw []byte ) (map [string ]string , bool , error ) {
98
129
params := make (map [string ]string )
99
130
envs , err := opts .ParseEnvFile (filepath .Join (filepath .Dir (composeFile ), ".env" ))
100
131
if err == nil {
@@ -107,7 +138,7 @@ func initFromComposeFile(name string, composeFile string) error {
107
138
}
108
139
vars , err := compose .ExtractVariables (composeRaw , compose .ExtrapolationPattern )
109
140
if err != nil {
110
- return errors .Wrap (err , "failed to parse compose file" )
141
+ return nil , false , errors .Wrap (err , "failed to parse compose file" )
111
142
}
112
143
needsFilling := false
113
144
for k , v := range vars {
@@ -120,6 +151,32 @@ func initFromComposeFile(name string, composeFile string) error {
120
151
}
121
152
}
122
153
}
154
+ return params , needsFilling , nil
155
+ }
156
+
157
+ func initFromComposeFile (errWriter io.Writer , name string , composeFile string ) error {
158
+ logrus .Debugf ("Initializing from compose file %s" , composeFile )
159
+
160
+ dirName := internal .DirNameFromAppName (name )
161
+
162
+ composeRaw , err := ioutil .ReadFile (composeFile )
163
+ if err != nil {
164
+ return errors .Wrapf (err , "failed to read compose file %q" , composeFile )
165
+ }
166
+ cfgMap , err := composeloader .ParseYAML (composeRaw )
167
+ if err != nil {
168
+ return errors .Wrap (err , "failed to parse compose file" )
169
+ }
170
+ if err := checkComposeFileVersion (cfgMap ); err != nil {
171
+ return err
172
+ }
173
+ if err := checkEnvFiles (errWriter , name , cfgMap ); err != nil {
174
+ return err
175
+ }
176
+ params , needsFilling , err := getParamsFromDefaultEnvFile (composeFile , composeRaw )
177
+ if err != nil {
178
+ return err
179
+ }
123
180
expandedParams , err := parameters .FromFlatten (params )
124
181
if err != nil {
125
182
return errors .Wrap (err , "failed to expand parameters" )
0 commit comments