fix(stack): env placeholder as host path [BE-11187] (#12192)

pull/12200/head
Oscar Zhou 3 months ago committed by GitHub
parent 6cff21477e
commit 80e607ab30
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -110,6 +110,11 @@ func (wrapper *PluginWrapper) Validate(ctx context.Context, filePaths []string,
return err
}
func (wrapper *PluginWrapper) Config(ctx context.Context, filePaths []string, options libstack.Options) ([]byte, error) {
configArgs := append([]string{"config"}, options.ConfigOptions...)
return wrapper.command(newCommand(configArgs, filePaths), options)
}
// Command execute a docker-compose command
func (wrapper *PluginWrapper) command(command composeCommand, options libstack.Options) ([]byte, error) {
program := utils.ProgramPath(wrapper.binaryPath, "docker-compose")

@ -143,3 +143,230 @@ func containerExists(containerName string) bool {
return strings.Contains(string(out), containerName)
}
func Test_Config(t *testing.T) {
checkPrerequisites(t)
ctx := context.Background()
dir := t.TempDir()
projectName := "configtest"
defer os.RemoveAll(dir)
testCases := []struct {
name string
composeFileContent string
expectFileContent string
envFileContent string
}{
{
name: "compose file with relative path",
composeFileContent: `services:
app:
image: 'nginx:latest'
ports:
- '80:80'
volumes:
- ./nginx-data:/data`,
expectFileContent: `name: configtest
services:
app:
image: nginx:latest
networks:
default: null
ports:
- mode: ingress
target: 80
published: "80"
protocol: tcp
volumes:
- type: bind
source: ./nginx-data
target: /data
bind:
create_host_path: true
networks:
default:
name: configtest_default
`,
envFileContent: "",
},
{
name: "compose file with absolute path",
composeFileContent: `services:
app:
image: 'nginx:latest'
ports:
- '80:80'
volumes:
- /nginx-data:/data`,
expectFileContent: `name: configtest
services:
app:
image: nginx:latest
networks:
default: null
ports:
- mode: ingress
target: 80
published: "80"
protocol: tcp
volumes:
- type: bind
source: /nginx-data
target: /data
bind:
create_host_path: true
networks:
default:
name: configtest_default
`,
envFileContent: "",
},
{
name: "compose file with declared volume",
composeFileContent: `services:
app:
image: 'nginx:latest'
ports:
- '80:80'
volumes:
- nginx-data:/data
volumes:
nginx-data:
driver: local`,
expectFileContent: `name: configtest
services:
app:
image: nginx:latest
networks:
default: null
ports:
- mode: ingress
target: 80
published: "80"
protocol: tcp
volumes:
- type: volume
source: nginx-data
target: /data
volume: {}
networks:
default:
name: configtest_default
volumes:
nginx-data:
name: configtest_nginx-data
driver: local
`,
envFileContent: "",
},
{
name: "compose file with relative path environment variable placeholder",
composeFileContent: `services:
nginx:
image: nginx:latest
ports:
- 8019:80
volumes:
- ${WEB_HOME}:/usr/share/nginx/html/
env_file:
- stack.env
`,
expectFileContent: `name: configtest
services:
nginx:
environment:
WEB_HOME: ./html
image: nginx:latest
networks:
default: null
ports:
- mode: ingress
target: 80
published: "8019"
protocol: tcp
volumes:
- type: bind
source: ./html
target: /usr/share/nginx/html
bind:
create_host_path: true
networks:
default:
name: configtest_default
`,
envFileContent: `WEB_HOME=./html`,
},
{
name: "compose file with absolute path environment variable placeholder",
composeFileContent: `services:
nginx:
image: nginx:latest
ports:
- 8019:80
volumes:
- ${WEB_HOME}:/usr/share/nginx/html/
env_file:
- stack.env
`,
expectFileContent: `name: configtest
services:
nginx:
environment:
WEB_HOME: /usr/share/nginx/html
image: nginx:latest
networks:
default: null
ports:
- mode: ingress
target: 80
published: "8019"
protocol: tcp
volumes:
- type: bind
source: /usr/share/nginx/html
target: /usr/share/nginx/html
bind:
create_host_path: true
networks:
default:
name: configtest_default
`,
envFileContent: `WEB_HOME=/usr/share/nginx/html`,
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
composeFilePath, err := createFile(dir, "docker-compose.yml", tc.composeFileContent)
if err != nil {
t.Fatal(err)
}
envFilePath := ""
if tc.envFileContent != "" {
envFilePath, err = createFile(dir, "stack.env", tc.envFileContent)
if err != nil {
t.Fatal(err)
}
}
w := setup(t)
actual, err := w.Config(ctx, []string{composeFilePath}, libstack.Options{
WorkingDir: dir,
ProjectName: projectName,
EnvFilePath: envFilePath,
ConfigOptions: []string{"--no-path-resolution"},
})
if err != nil {
t.Fatalf("failed to get config: %s. Error: %s", string(actual), err)
}
if string(actual) != tc.expectFileContent {
t.Fatalf("unexpected config output: %s(len=%d), expect: %s(len=%d)", actual, len(actual), tc.expectFileContent, len(tc.expectFileContent))
}
})
}
}

@ -14,6 +14,7 @@ type Deployer interface {
Pull(ctx context.Context, filePaths []string, options Options) error
Validate(ctx context.Context, filePaths []string, options Options) error
WaitForStatus(ctx context.Context, name string, status Status) <-chan WaitResult
Config(ctx context.Context, filePaths []string, options Options) ([]byte, error)
}
type Status string
@ -47,6 +48,8 @@ type Options struct {
// By default, it is an empty string, which means it corresponds to the path of the compose file itself.
// This is particularly helpful when mounting a relative path.
ProjectDir string
// ConfigOptions is a list of options to pass to the docker-compose config command
ConfigOptions []string
}
type DeployOptions struct {

Loading…
Cancel
Save