Add support to pass env-from-file to docker compose run
Signed-off-by: Vedant Koditkar <vedant.koditkar@outlook.com> Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
This commit is contained in:
parent
55b5f233c2
commit
83cafe2838
@ -19,8 +19,10 @@ package compose
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/compose-spec/compose-go/v2/dotenv"
|
||||||
"github.com/compose-spec/compose-go/v2/format"
|
"github.com/compose-spec/compose-go/v2/format"
|
||||||
xprogress "github.com/moby/buildkit/util/progress/progressui"
|
xprogress "github.com/moby/buildkit/util/progress/progressui"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
@ -44,6 +46,7 @@ type runOptions struct {
|
|||||||
Service string
|
Service string
|
||||||
Command []string
|
Command []string
|
||||||
environment []string
|
environment []string
|
||||||
|
envFiles []string
|
||||||
Detach bool
|
Detach bool
|
||||||
Remove bool
|
Remove bool
|
||||||
noTty bool
|
noTty bool
|
||||||
@ -116,6 +119,29 @@ func (options runOptions) apply(project *types.Project) (*types.Project, error)
|
|||||||
return project, nil
|
return project, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (options runOptions) getEnvironment() (types.Mapping, error) {
|
||||||
|
environment := types.NewMappingWithEquals(options.environment).Resolve(os.LookupEnv).ToMapping()
|
||||||
|
for _, file := range options.envFiles {
|
||||||
|
f, err := os.Open(file)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
vars, err := dotenv.ParseWithLookup(f, func(k string) (string, bool) {
|
||||||
|
value, ok := environment[k]
|
||||||
|
return value, ok
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
for k, v := range vars {
|
||||||
|
if _, ok := environment[k]; !ok {
|
||||||
|
environment[k] = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return environment, nil
|
||||||
|
}
|
||||||
|
|
||||||
func runCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service) *cobra.Command {
|
func runCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service) *cobra.Command {
|
||||||
options := runOptions{
|
options := runOptions{
|
||||||
composeOptions: &composeOptions{
|
composeOptions: &composeOptions{
|
||||||
@ -175,6 +201,7 @@ func runCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service) *
|
|||||||
flags := cmd.Flags()
|
flags := cmd.Flags()
|
||||||
flags.BoolVarP(&options.Detach, "detach", "d", false, "Run container in background and print container ID")
|
flags.BoolVarP(&options.Detach, "detach", "d", false, "Run container in background and print container ID")
|
||||||
flags.StringArrayVarP(&options.environment, "env", "e", []string{}, "Set environment variables")
|
flags.StringArrayVarP(&options.environment, "env", "e", []string{}, "Set environment variables")
|
||||||
|
flags.StringArrayVar(&options.envFiles, "env-from-file", []string{}, "Set environment variables from file")
|
||||||
flags.StringArrayVarP(&options.labels, "label", "l", []string{}, "Add or override a label")
|
flags.StringArrayVarP(&options.labels, "label", "l", []string{}, "Add or override a label")
|
||||||
flags.BoolVar(&options.Remove, "rm", false, "Automatically remove the container when it exits")
|
flags.BoolVar(&options.Remove, "rm", false, "Automatically remove the container when it exits")
|
||||||
flags.BoolVarP(&options.noTty, "no-TTY", "T", !dockerCli.Out().IsTerminal(), "Disable pseudo-TTY allocation (default: auto-detected)")
|
flags.BoolVarP(&options.noTty, "no-TTY", "T", !dockerCli.Out().IsTerminal(), "Disable pseudo-TTY allocation (default: auto-detected)")
|
||||||
@ -264,6 +291,11 @@ func runRun(ctx context.Context, backend api.Service, project *types.Project, op
|
|||||||
buildForRun = &bo
|
buildForRun = &bo
|
||||||
}
|
}
|
||||||
|
|
||||||
|
environment, err := options.getEnvironment()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
// start container and attach to container streams
|
// start container and attach to container streams
|
||||||
runOpts := api.RunOptions{
|
runOpts := api.RunOptions{
|
||||||
Build: buildForRun,
|
Build: buildForRun,
|
||||||
@ -278,7 +310,7 @@ func runRun(ctx context.Context, backend api.Service, project *types.Project, op
|
|||||||
User: options.user,
|
User: options.user,
|
||||||
CapAdd: options.capAdd.GetAll(),
|
CapAdd: options.capAdd.GetAll(),
|
||||||
CapDrop: options.capDrop.GetAll(),
|
CapDrop: options.capDrop.GetAll(),
|
||||||
Environment: options.environment,
|
Environment: environment.Values(),
|
||||||
Entrypoint: options.entrypointCmd,
|
Entrypoint: options.entrypointCmd,
|
||||||
Labels: labels,
|
Labels: labels,
|
||||||
UseNetworkAliases: options.useAliases,
|
UseNetworkAliases: options.useAliases,
|
||||||
|
@ -66,6 +66,7 @@ specified in the service configuration.
|
|||||||
| `--dry-run` | `bool` | | Execute command in dry run mode |
|
| `--dry-run` | `bool` | | Execute command in dry run mode |
|
||||||
| `--entrypoint` | `string` | | Override the entrypoint of the image |
|
| `--entrypoint` | `string` | | Override the entrypoint of the image |
|
||||||
| `-e`, `--env` | `stringArray` | | Set environment variables |
|
| `-e`, `--env` | `stringArray` | | Set environment variables |
|
||||||
|
| `--env-from-file` | `stringArray` | | Set environment variables from file |
|
||||||
| `-i`, `--interactive` | `bool` | `true` | Keep STDIN open even if not attached |
|
| `-i`, `--interactive` | `bool` | `true` | Keep STDIN open even if not attached |
|
||||||
| `-l`, `--label` | `stringArray` | | Add or override a label |
|
| `-l`, `--label` | `stringArray` | | Add or override a label |
|
||||||
| `--name` | `string` | | Assign a name to the container |
|
| `--name` | `string` | | Assign a name to the container |
|
||||||
|
@ -117,6 +117,16 @@ options:
|
|||||||
experimentalcli: false
|
experimentalcli: false
|
||||||
kubernetes: false
|
kubernetes: false
|
||||||
swarm: false
|
swarm: false
|
||||||
|
- option: env-from-file
|
||||||
|
value_type: stringArray
|
||||||
|
default_value: '[]'
|
||||||
|
description: Set environment variables from file
|
||||||
|
deprecated: false
|
||||||
|
hidden: false
|
||||||
|
experimental: false
|
||||||
|
experimentalcli: false
|
||||||
|
kubernetes: false
|
||||||
|
swarm: false
|
||||||
- option: interactive
|
- option: interactive
|
||||||
shorthand: i
|
shorthand: i
|
||||||
value_type: bool
|
value_type: bool
|
||||||
|
@ -178,4 +178,10 @@ func TestLocalComposeRun(t *testing.T) {
|
|||||||
assert.Assert(t, strings.Contains(res.Combined(), "backend Pulling"), res.Combined())
|
assert.Assert(t, strings.Contains(res.Combined(), "backend Pulling"), res.Combined())
|
||||||
assert.Assert(t, strings.Contains(res.Combined(), "backend Pulled"), res.Combined())
|
assert.Assert(t, strings.Contains(res.Combined(), "backend Pulled"), res.Combined())
|
||||||
})
|
})
|
||||||
|
|
||||||
|
t.Run("compose run --env-from-file", func(t *testing.T) {
|
||||||
|
res := c.RunDockerComposeCmd(t, "-f", "./fixtures/run-test/compose.yaml", "run", "--env-from-file", "./fixtures/run-test/run.env",
|
||||||
|
"front", "env")
|
||||||
|
res.Assert(t, icmd.Expected{Out: "FOO=BAR"})
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
version: '3.8'
|
|
||||||
services:
|
services:
|
||||||
back:
|
back:
|
||||||
image: alpine
|
image: alpine
|
||||||
|
1
pkg/e2e/fixtures/run-test/run.env
Normal file
1
pkg/e2e/fixtures/run-test/run.env
Normal file
@ -0,0 +1 @@
|
|||||||
|
FOO=BAR
|
Loading…
x
Reference in New Issue
Block a user