Merge pull request #3721 from thaJeztah/context_optimisations

context use: don't create/update config file and directories if not needed
This commit is contained in:
Sebastiaan van Stijn 2022-07-29 14:46:28 +02:00 committed by GitHub
commit e198123693
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 50 additions and 12 deletions

View File

@ -25,20 +25,26 @@ func newUseCommand(dockerCli command.Cli) *cobra.Command {
// RunUse set the current Docker context
func RunUse(dockerCli command.Cli, name string) error {
if err := store.ValidateContextName(name); err != nil && name != "default" {
return err
}
if _, err := dockerCli.ContextStore().GetMetadata(name); err != nil && name != "default" {
return err
}
configValue := name
if configValue == "default" {
configValue = ""
// configValue uses an empty string for "default"
var configValue string
if name != command.DefaultContextName {
if err := store.ValidateContextName(name); err != nil {
return err
}
if _, err := dockerCli.ContextStore().GetMetadata(name); err != nil {
return err
}
configValue = name
}
dockerConfig := dockerCli.ConfigFile()
dockerConfig.CurrentContext = configValue
if err := dockerConfig.Save(); err != nil {
return err
// Avoid updating the config-file if nothing changed. This also prevents
// creating the file and config-directory if the default is used and
// no config-file existed yet.
if dockerConfig.CurrentContext != configValue {
dockerConfig.CurrentContext = configValue
if err := dockerConfig.Save(); err != nil {
return err
}
}
fmt.Fprintln(dockerCli.Out(), name)
fmt.Fprintf(dockerCli.Err(), "Current context is now %q\n", name)

View File

@ -2,6 +2,9 @@ package context
import (
"bytes"
"errors"
"io"
"os"
"path/filepath"
"testing"
@ -10,6 +13,7 @@ import (
"github.com/docker/cli/cli/config/configfile"
"github.com/docker/cli/cli/context/store"
"github.com/docker/cli/cli/flags"
"github.com/docker/docker/pkg/homedir"
"gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp"
)
@ -46,6 +50,34 @@ func TestUseNoExist(t *testing.T) {
assert.Check(t, store.IsErrContextDoesNotExist(err))
}
// TestUseDefaultWithoutConfigFile verifies that the CLI does not create
// the default config file and directory when using the default context.
func TestUseDefaultWithoutConfigFile(t *testing.T) {
// We must use a temporary home-directory, because this test covers
// the _default_ configuration file. If we specify a custom configuration
// file, the CLI produces an error if the file doesn't exist.
tmpHomeDir := t.TempDir()
t.Setenv(homedir.Key(), tmpHomeDir)
configDir := filepath.Join(tmpHomeDir, ".docker")
configFilePath := filepath.Join(configDir, "config.json")
// Verify config-dir and -file don't exist before
_, err := os.Stat(configDir)
assert.Check(t, errors.Is(err, os.ErrNotExist))
_, err = os.Stat(configFilePath)
assert.Check(t, errors.Is(err, os.ErrNotExist))
cli, err := command.NewDockerCli(command.WithCombinedStreams(io.Discard))
assert.NilError(t, err)
assert.NilError(t, newUseCommand(cli).RunE(nil, []string{"default"}))
// Verify config-dir and -file don't exist after
_, err = os.Stat(configDir)
assert.Check(t, errors.Is(err, os.ErrNotExist))
_, err = os.Stat(configFilePath)
assert.Check(t, errors.Is(err, os.ErrNotExist))
}
func TestUseHostOverride(t *testing.T) {
t.Setenv("DOCKER_HOST", "tcp://ed:2375/")