These functions and types are shallow wrappers around the context store and were intended for internal use as implementation for the CLI itself. They were exported in3126920af1to be used by plugins and Docker Desktop. However, there's currently no public uses of this, and Docker Desktop does not use these functions. This patch deprecates the exported functions as they were meant to be implementation specific for the CLI. If there's a need to provide utilities for manipulating the context-store other than through the CLI itself, we can consider creating an SDK for that purpose. This deprecates: - `RunCreate` and `CreateOptions` - `RunExport` and `ExportOptions` - `RunImport` - `RunRemove` and `RemoveOptions` - `RunUpdate` and `UpdateOptions` - `RunUse` Signed-off-by: Sebastiaan van Stijn <github@gone.nl> (cherry picked from commit95eeafa551) Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
158 lines
4.9 KiB
Go
158 lines
4.9 KiB
Go
package context
|
|
|
|
import (
|
|
"bytes"
|
|
"errors"
|
|
"io"
|
|
"os"
|
|
"path/filepath"
|
|
"runtime"
|
|
"testing"
|
|
|
|
"github.com/containerd/errdefs"
|
|
"github.com/docker/cli/cli/command"
|
|
"github.com/docker/cli/cli/config"
|
|
"github.com/docker/cli/cli/config/configfile"
|
|
"github.com/docker/cli/cli/flags"
|
|
"gotest.tools/v3/assert"
|
|
is "gotest.tools/v3/assert/cmp"
|
|
)
|
|
|
|
func TestUse(t *testing.T) {
|
|
configDir := t.TempDir()
|
|
configFilePath := filepath.Join(configDir, "config.json")
|
|
testCfg := configfile.New(configFilePath)
|
|
cli := makeFakeCli(t, withCliConfig(testCfg))
|
|
err := runCreate(cli, &createOptions{
|
|
name: "test",
|
|
endpoint: map[string]string{},
|
|
})
|
|
assert.NilError(t, err)
|
|
assert.NilError(t, newUseCommand(cli).RunE(nil, []string{"test"}))
|
|
reloadedConfig, err := config.Load(configDir)
|
|
assert.NilError(t, err)
|
|
assert.Equal(t, "test", reloadedConfig.CurrentContext)
|
|
|
|
// switch back to default
|
|
cli.OutBuffer().Reset()
|
|
cli.ErrBuffer().Reset()
|
|
assert.NilError(t, newUseCommand(cli).RunE(nil, []string{"default"}))
|
|
reloadedConfig, err = config.Load(configDir)
|
|
assert.NilError(t, err)
|
|
assert.Equal(t, "", reloadedConfig.CurrentContext)
|
|
assert.Equal(t, "default\n", cli.OutBuffer().String())
|
|
assert.Equal(t, "Current context is now \"default\"\n", cli.ErrBuffer().String())
|
|
}
|
|
|
|
func TestUseNoExist(t *testing.T) {
|
|
cli := makeFakeCli(t)
|
|
err := newUseCommand(cli).RunE(nil, []string{"test"})
|
|
assert.Check(t, is.ErrorType(err, errdefs.IsNotFound))
|
|
}
|
|
|
|
// 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()
|
|
if runtime.GOOS == "windows" {
|
|
t.Setenv("USERPROFILE", tmpHomeDir)
|
|
} else {
|
|
t.Setenv("HOME", 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/")
|
|
|
|
configDir := t.TempDir()
|
|
configFilePath := filepath.Join(configDir, "config.json")
|
|
testCfg := configfile.New(configFilePath)
|
|
cli := makeFakeCli(t, withCliConfig(testCfg))
|
|
err := runCreate(cli, &createOptions{
|
|
name: "test",
|
|
endpoint: map[string]string{},
|
|
})
|
|
assert.NilError(t, err)
|
|
|
|
cli.ResetOutputBuffers()
|
|
err = newUseCommand(cli).RunE(nil, []string{"test"})
|
|
assert.NilError(t, err)
|
|
assert.Assert(t, is.Contains(
|
|
cli.ErrBuffer().String(),
|
|
`Warning: DOCKER_HOST environment variable overrides the active context.`,
|
|
))
|
|
assert.Assert(t, is.Contains(cli.ErrBuffer().String(), `Current context is now "test"`))
|
|
assert.Equal(t, cli.OutBuffer().String(), "test\n")
|
|
|
|
// setting DOCKER_HOST with the default context should not print a warning
|
|
cli.ResetOutputBuffers()
|
|
err = newUseCommand(cli).RunE(nil, []string{"default"})
|
|
assert.NilError(t, err)
|
|
assert.Assert(t, is.Contains(cli.ErrBuffer().String(), `Current context is now "default"`))
|
|
assert.Equal(t, cli.OutBuffer().String(), "default\n")
|
|
}
|
|
|
|
// An empty DOCKER_HOST used to break the 'context use' flow.
|
|
// So we have a test with fewer fakes that tests this flow holistically.
|
|
// https://github.com/docker/cli/issues/3667
|
|
func TestUseHostOverrideEmpty(t *testing.T) {
|
|
t.Setenv("DOCKER_HOST", "")
|
|
|
|
configDir := t.TempDir()
|
|
config.SetDir(configDir)
|
|
|
|
socketPath := "unix://" + filepath.Join(configDir, "docker.sock")
|
|
|
|
var out *bytes.Buffer
|
|
var cli *command.DockerCli
|
|
|
|
loadCli := func() {
|
|
out = bytes.NewBuffer(nil)
|
|
|
|
var err error
|
|
cli, err = command.NewDockerCli(command.WithCombinedStreams(out))
|
|
assert.NilError(t, err)
|
|
assert.NilError(t, cli.Initialize(flags.NewClientOptions()))
|
|
}
|
|
loadCli()
|
|
err := runCreate(cli, &createOptions{
|
|
name: "test",
|
|
endpoint: map[string]string{"host": socketPath},
|
|
})
|
|
assert.NilError(t, err)
|
|
|
|
err = newUseCommand(cli).RunE(nil, []string{"test"})
|
|
assert.NilError(t, err)
|
|
assert.Assert(t, !is.Contains(out.String(), "Warning")().Success())
|
|
assert.Assert(t, is.Contains(out.String(), `Current context is now "test"`))
|
|
|
|
loadCli()
|
|
err = newShowCommand(cli).RunE(nil, nil)
|
|
assert.NilError(t, err)
|
|
assert.Assert(t, is.Contains(out.String(), "test"))
|
|
|
|
apiclient := cli.Client()
|
|
assert.Equal(t, apiclient.DaemonHost(), socketPath)
|
|
}
|