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:
Nicolas De Loof 2022-02-14 01:43:27 +05:30 committed by Nicolas De loof
parent 55b5f233c2
commit 83cafe2838
6 changed files with 51 additions and 2 deletions

View File

@ -19,8 +19,10 @@ package compose
import (
"context"
"fmt"
"os"
"strings"
"github.com/compose-spec/compose-go/v2/dotenv"
"github.com/compose-spec/compose-go/v2/format"
xprogress "github.com/moby/buildkit/util/progress/progressui"
"github.com/sirupsen/logrus"
@ -44,6 +46,7 @@ type runOptions struct {
Service string
Command []string
environment []string
envFiles []string
Detach bool
Remove bool
noTty bool
@ -116,6 +119,29 @@ func (options runOptions) apply(project *types.Project) (*types.Project, error)
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 {
options := runOptions{
composeOptions: &composeOptions{
@ -175,6 +201,7 @@ func runCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service) *
flags := cmd.Flags()
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.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.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)")
@ -264,6 +291,11 @@ func runRun(ctx context.Context, backend api.Service, project *types.Project, op
buildForRun = &bo
}
environment, err := options.getEnvironment()
if err != nil {
return err
}
// start container and attach to container streams
runOpts := api.RunOptions{
Build: buildForRun,
@ -278,7 +310,7 @@ func runRun(ctx context.Context, backend api.Service, project *types.Project, op
User: options.user,
CapAdd: options.capAdd.GetAll(),
CapDrop: options.capDrop.GetAll(),
Environment: options.environment,
Environment: environment.Values(),
Entrypoint: options.entrypointCmd,
Labels: labels,
UseNetworkAliases: options.useAliases,

View File

@ -66,6 +66,7 @@ specified in the service configuration.
| `--dry-run` | `bool` | | Execute command in dry run mode |
| `--entrypoint` | `string` | | Override the entrypoint of the image |
| `-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 |
| `-l`, `--label` | `stringArray` | | Add or override a label |
| `--name` | `string` | | Assign a name to the container |

View File

@ -117,6 +117,16 @@ options:
experimentalcli: false
kubernetes: 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
shorthand: i
value_type: bool

View File

@ -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 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"})
})
}

View File

@ -1,4 +1,3 @@
version: '3.8'
services:
back:
image: alpine

View File

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