mirror of
https://github.com/docker/compose.git
synced 2026-08-04 14:47:40 +00:00
fix: tolerate missing env file on scale, watch and shell completion
Follow-up to #13603: scale, watch and shell completion loaded the project without any tolerance option, so a missing env_file on a service not involved in the operation aborted the command, while up/exec/ps already tolerate this since #13156 and #13603. Mirror the WithServices pattern: load with WithoutEnvironmentResolution and resolve the environment once the project has been reduced to the selected services, so targeted services still get their env_file validated. Completion only needs names and never resolves. This also aligns the config hash of scale-created containers with up-created ones. Signed-off-by: Guillaume Lours <glours@users.noreply.github.com>
This commit is contained in:
parent
7bdc31c5de
commit
d8370536f0
4 changed files with 46 additions and 6 deletions
|
|
@ -20,6 +20,7 @@ import (
|
|||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/compose-spec/compose-go/v2/cli"
|
||||
"github.com/docker/cli/cli/command"
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
|
|
@ -44,7 +45,9 @@ func completeServiceNames(dockerCli command.Cli, p *ProjectOptions) validArgsFn
|
|||
return nil, cobra.ShellCompDirectiveNoFileComp
|
||||
}
|
||||
|
||||
project, _, err := p.ToProject(cmd.Context(), dockerCli, backend, nil)
|
||||
// only service names are needed, so skip environment resolution: a missing
|
||||
// env_file must not prevent completion
|
||||
project, _, err := p.ToProject(cmd.Context(), dockerCli, backend, nil, cli.WithoutEnvironmentResolution)
|
||||
if err != nil {
|
||||
return nil, cobra.ShellCompDirectiveNoFileComp
|
||||
}
|
||||
|
|
@ -90,7 +93,9 @@ func completeProfileNames(dockerCli command.Cli, p *ProjectOptions) validArgsFn
|
|||
return nil, cobra.ShellCompDirectiveNoFileComp
|
||||
}
|
||||
|
||||
project, _, err := p.ToProject(cmd.Context(), dockerCli, backend, nil)
|
||||
// only profile names are needed, so skip environment resolution: a missing
|
||||
// env_file must not prevent completion
|
||||
project, _, err := p.ToProject(cmd.Context(), dockerCli, backend, nil, cli.WithoutEnvironmentResolution)
|
||||
if err != nil {
|
||||
return nil, cobra.ShellCompDirectiveNoFileComp
|
||||
}
|
||||
|
|
@ -108,9 +113,9 @@ func completeProfileNames(dockerCli command.Cli, p *ProjectOptions) validArgsFn
|
|||
}
|
||||
}
|
||||
|
||||
func completeScaleArgs(cli command.Cli, p *ProjectOptions) cobra.CompletionFunc {
|
||||
func completeScaleArgs(dockerCli command.Cli, p *ProjectOptions) cobra.CompletionFunc {
|
||||
return func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
||||
completions, directive := completeServiceNames(cli, p)(cmd, args, toComplete)
|
||||
completions, directive := completeServiceNames(dockerCli, p)(cmd, args, toComplete)
|
||||
for i, completion := range completions {
|
||||
completions[i] = completion + "="
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ import (
|
|||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/compose-spec/compose-go/v2/cli"
|
||||
"github.com/compose-spec/compose-go/v2/types"
|
||||
"github.com/docker/cli/cli/command"
|
||||
"github.com/spf13/cobra"
|
||||
|
|
@ -67,7 +68,14 @@ func runScale(ctx context.Context, dockerCli command.Cli, backendOptions *Backen
|
|||
}
|
||||
|
||||
services := slices.Sorted(maps.Keys(serviceReplicaTuples))
|
||||
project, _, err := opts.ToProject(ctx, dockerCli, backend, services)
|
||||
project, _, err := opts.ToProject(ctx, dockerCli, backend, services, cli.WithoutEnvironmentResolution)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// resolve environment after the project has been reduced to selected services,
|
||||
// so env_file declared by unrelated services doesn't need to exist
|
||||
project, err = project.WithServicesEnvironmentResolved(true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ import (
|
|||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/compose-spec/compose-go/v2/cli"
|
||||
"github.com/compose-spec/compose-go/v2/types"
|
||||
"github.com/docker/cli/cli/command"
|
||||
"github.com/sirupsen/logrus"
|
||||
|
|
@ -71,7 +72,14 @@ func runWatch(ctx context.Context, dockerCli command.Cli, backendOptions *Backen
|
|||
return err
|
||||
}
|
||||
|
||||
project, _, err := watchOpts.ToProject(ctx, dockerCli, backend, services)
|
||||
project, _, err := watchOpts.ToProject(ctx, dockerCli, backend, services, cli.WithoutEnvironmentResolution)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// resolve environment after the project has been reduced to selected services,
|
||||
// so env_file declared by unrelated services doesn't need to exist
|
||||
project, err = project.WithServicesEnvironmentResolved(true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,6 +42,25 @@ func TestUnusedMissingEnvFile(t *testing.T) {
|
|||
c.RunDockerComposeCmd(t, "-f", "./fixtures/env_file/compose.yaml", "ps")
|
||||
c.RunDockerComposeCmd(t, "-f", "./fixtures/env_file/compose.yaml", "logs")
|
||||
c.RunDockerComposeCmd(t, "-f", "./fixtures/env_file/compose.yaml", "exec", "serviceA", "echo", "hello")
|
||||
|
||||
// scale should work even with missing env file on a service not being scaled
|
||||
c.RunDockerComposeCmd(t, "-f", "./fixtures/env_file/compose.yaml", "scale", "serviceA=2")
|
||||
|
||||
// but scaling the service with the missing env file must still fail
|
||||
res := c.RunDockerComposeCmdNoCheck(t, "-f", "./fixtures/env_file/compose.yaml", "scale", "serviceB=1")
|
||||
res.Assert(t, icmd.Expected{ExitCode: 1, Err: "env file /doesnotexist/.env not found"})
|
||||
|
||||
// shell completion should list services even with missing env file.
|
||||
// ComposeStandalonePath fails the test outside standalone mode, so only the
|
||||
// plugin form can be the default here.
|
||||
completeCmd := []string{DockerExecutableName, "__complete", "compose"}
|
||||
if composeStandaloneMode {
|
||||
completeCmd = []string{ComposeStandalonePath(t), "__complete"}
|
||||
}
|
||||
res = c.RunCmd(t, append(completeCmd, "-f", "./fixtures/env_file/compose.yaml", "exec", "")...)
|
||||
res.Assert(t, icmd.Expected{Out: "serviceA"})
|
||||
res.Assert(t, icmd.Expected{Out: "serviceB"})
|
||||
|
||||
c.RunDockerComposeCmd(t, "-f", "./fixtures/env_file/compose.yaml", "down")
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue