Remove containerizedengine package dependency from docker/cli/command…
… this removes a whole lot of dependencies from people depending on docker/cli…
Signed-off-by: Vincent Demeester <vincent@sbr.pm>
(cherry picked from commit 2d344b2f61)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
package containerizedengine
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"syscall"
|
||||
|
||||
@@ -69,10 +68,6 @@ type (
|
||||
loadProcessFunc func(context.Context, string, cio.Attach) (containerd.Process, error)
|
||||
metricsFunc func(context.Context) (*containerdtypes.Metric, error)
|
||||
}
|
||||
|
||||
testOutStream struct {
|
||||
bytes.Buffer
|
||||
}
|
||||
)
|
||||
|
||||
func (w *fakeContainerdClient) Containers(ctx context.Context, filters ...string) ([]containerd.Container, error) {
|
||||
@@ -339,10 +334,3 @@ func (t *fakeTask) Metrics(ctx context.Context) (*containerdtypes.Metric, error)
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (o *testOutStream) FD() uintptr {
|
||||
return 0
|
||||
}
|
||||
func (o *testOutStream) IsTerminal() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"github.com/containerd/containerd"
|
||||
"github.com/containerd/containerd/images"
|
||||
"github.com/containerd/containerd/remotes/docker"
|
||||
clitypes "github.com/docker/cli/types"
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/pkg/jsonmessage"
|
||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
@@ -15,7 +16,7 @@ import (
|
||||
// NewClient returns a new containerizedengine client
|
||||
// This client can be used to manage the lifecycle of
|
||||
// dockerd running as a container on containerd.
|
||||
func NewClient(sockPath string) (Client, error) {
|
||||
func NewClient(sockPath string) (clitypes.ContainerizedClient, error) {
|
||||
if sockPath == "" {
|
||||
sockPath = containerdSockPath
|
||||
}
|
||||
@@ -23,17 +24,17 @@ func NewClient(sockPath string) (Client, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return baseClient{
|
||||
return &baseClient{
|
||||
cclient: cclient,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Close will close the underlying clients
|
||||
func (c baseClient) Close() error {
|
||||
func (c *baseClient) Close() error {
|
||||
return c.cclient.Close()
|
||||
}
|
||||
|
||||
func (c baseClient) pullWithAuth(ctx context.Context, imageName string, out OutStream,
|
||||
func (c *baseClient) pullWithAuth(ctx context.Context, imageName string, out clitypes.OutStream,
|
||||
authConfig *types.AuthConfig) (containerd.Image, error) {
|
||||
|
||||
resolver := docker.NewResolver(docker.ResolverOptions{
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
package containerizedengine
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/containerd/containerd"
|
||||
"github.com/docker/cli/cli/command"
|
||||
"github.com/docker/docker/api/types"
|
||||
"gotest.tools/assert"
|
||||
)
|
||||
@@ -22,7 +24,7 @@ func TestPullWithAuthPullFail(t *testing.T) {
|
||||
}
|
||||
imageName := "testnamegoeshere"
|
||||
|
||||
_, err := client.pullWithAuth(ctx, imageName, &testOutStream{}, &types.AuthConfig{})
|
||||
_, err := client.pullWithAuth(ctx, imageName, command.NewOutStream(&bytes.Buffer{}), &types.AuthConfig{})
|
||||
assert.ErrorContains(t, err, "pull failure")
|
||||
}
|
||||
|
||||
@@ -38,6 +40,6 @@ func TestPullWithAuthPullPass(t *testing.T) {
|
||||
}
|
||||
imageName := "testnamegoeshere"
|
||||
|
||||
_, err := client.pullWithAuth(ctx, imageName, &testOutStream{}, &types.AuthConfig{})
|
||||
_, err := client.pullWithAuth(ctx, imageName, command.NewOutStream(&bytes.Buffer{}), &types.AuthConfig{})
|
||||
assert.NilError(t, err)
|
||||
}
|
||||
|
||||
@@ -13,12 +13,15 @@ import (
|
||||
"github.com/containerd/containerd/namespaces"
|
||||
"github.com/containerd/containerd/runtime/restart"
|
||||
"github.com/docker/cli/internal/pkg/containerized"
|
||||
clitypes "github.com/docker/cli/types"
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
var _ clitypes.ContainerizedClient = &baseClient{}
|
||||
|
||||
// InitEngine is the main entrypoint for `docker engine init`
|
||||
func (c baseClient) InitEngine(ctx context.Context, opts EngineInitOptions, out OutStream,
|
||||
func (c *baseClient) InitEngine(ctx context.Context, opts clitypes.EngineInitOptions, out clitypes.OutStream,
|
||||
authConfig *types.AuthConfig, healthfn func(context.Context) error) error {
|
||||
|
||||
ctx = namespaces.WithNamespace(ctx, engineNamespace)
|
||||
@@ -67,7 +70,7 @@ func (c baseClient) InitEngine(ctx context.Context, opts EngineInitOptions, out
|
||||
}
|
||||
|
||||
// GetEngine will return the containerd container running the engine (or error)
|
||||
func (c baseClient) GetEngine(ctx context.Context) (containerd.Container, error) {
|
||||
func (c *baseClient) GetEngine(ctx context.Context) (containerd.Container, error) {
|
||||
ctx = namespaces.WithNamespace(ctx, engineNamespace)
|
||||
containers, err := c.cclient.Containers(ctx, "id=="+engineContainerName)
|
||||
if err != nil {
|
||||
@@ -80,7 +83,7 @@ func (c baseClient) GetEngine(ctx context.Context) (containerd.Container, error)
|
||||
}
|
||||
|
||||
// getEngineImage will return the current image used by the engine
|
||||
func (c baseClient) getEngineImage(engine containerd.Container) (string, error) {
|
||||
func (c *baseClient) getEngineImage(engine containerd.Container) (string, error) {
|
||||
ctx := namespaces.WithNamespace(context.Background(), engineNamespace)
|
||||
image, err := engine.Image(ctx)
|
||||
if err != nil {
|
||||
@@ -124,7 +127,7 @@ var (
|
||||
)
|
||||
|
||||
// waitForEngine will wait for the engine to start
|
||||
func (c baseClient) waitForEngine(ctx context.Context, out io.Writer, healthfn func(context.Context) error) error {
|
||||
func (c *baseClient) waitForEngine(ctx context.Context, out io.Writer, healthfn func(context.Context) error) error {
|
||||
ticker := time.NewTicker(engineWaitInterval)
|
||||
defer ticker.Stop()
|
||||
defer func() {
|
||||
@@ -150,7 +153,7 @@ func (c baseClient) waitForEngine(ctx context.Context, out io.Writer, healthfn f
|
||||
}
|
||||
}
|
||||
|
||||
func (c baseClient) waitForEngineContainer(ctx context.Context, ticker *time.Ticker) error {
|
||||
func (c *baseClient) waitForEngineContainer(ctx context.Context, ticker *time.Ticker) error {
|
||||
var ret error
|
||||
for {
|
||||
select {
|
||||
@@ -167,7 +170,15 @@ func (c baseClient) waitForEngineContainer(ctx context.Context, ticker *time.Tic
|
||||
}
|
||||
|
||||
// RemoveEngine gracefully unwinds the current engine
|
||||
func (c baseClient) RemoveEngine(ctx context.Context, engine containerd.Container) error {
|
||||
func (c *baseClient) RemoveEngine(ctx context.Context) error {
|
||||
engine, err := c.GetEngine(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return c.removeEngine(ctx, engine)
|
||||
}
|
||||
|
||||
func (c *baseClient) removeEngine(ctx context.Context, engine containerd.Container) error {
|
||||
ctx = namespaces.WithNamespace(ctx, engineNamespace)
|
||||
|
||||
// Make sure the container isn't being restarted while we unwind it
|
||||
@@ -220,7 +231,7 @@ func (c baseClient) RemoveEngine(ctx context.Context, engine containerd.Containe
|
||||
}
|
||||
|
||||
// startEngineOnContainerd creates a new docker engine running on containerd
|
||||
func (c baseClient) startEngineOnContainerd(ctx context.Context, imageName, configFile string) error {
|
||||
func (c *baseClient) startEngineOnContainerd(ctx context.Context, imageName, configFile string) error {
|
||||
ctx = namespaces.WithNamespace(ctx, engineNamespace)
|
||||
image, err := c.cclient.GetImage(ctx, imageName)
|
||||
if err != nil {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package containerizedengine
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"syscall"
|
||||
@@ -11,6 +12,8 @@ import (
|
||||
"github.com/containerd/containerd/cio"
|
||||
"github.com/containerd/containerd/errdefs"
|
||||
"github.com/containerd/containerd/oci"
|
||||
"github.com/docker/cli/cli/command"
|
||||
clitypes "github.com/docker/cli/types"
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/opencontainers/runtime-spec/specs-go"
|
||||
"gotest.tools/assert"
|
||||
@@ -25,11 +28,11 @@ func healthfnError(ctx context.Context) error {
|
||||
|
||||
func TestInitGetEngineFail(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
opts := EngineInitOptions{
|
||||
opts := clitypes.EngineInitOptions{
|
||||
EngineVersion: "engineversiongoeshere",
|
||||
RegistryPrefix: "registryprefixgoeshere",
|
||||
ConfigFile: "/tmp/configfilegoeshere",
|
||||
EngineImage: CommunityEngineImage,
|
||||
EngineImage: clitypes.CommunityEngineImage,
|
||||
}
|
||||
container := &fakeContainer{}
|
||||
client := baseClient{
|
||||
@@ -40,17 +43,17 @@ func TestInitGetEngineFail(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
err := client.InitEngine(ctx, opts, &testOutStream{}, &types.AuthConfig{}, healthfnHappy)
|
||||
err := client.InitEngine(ctx, opts, command.NewOutStream(&bytes.Buffer{}), &types.AuthConfig{}, healthfnHappy)
|
||||
assert.Assert(t, err == ErrEngineAlreadyPresent)
|
||||
}
|
||||
|
||||
func TestInitCheckImageFail(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
opts := EngineInitOptions{
|
||||
opts := clitypes.EngineInitOptions{
|
||||
EngineVersion: "engineversiongoeshere",
|
||||
RegistryPrefix: "registryprefixgoeshere",
|
||||
ConfigFile: "/tmp/configfilegoeshere",
|
||||
EngineImage: CommunityEngineImage,
|
||||
EngineImage: clitypes.CommunityEngineImage,
|
||||
}
|
||||
client := baseClient{
|
||||
cclient: &fakeContainerdClient{
|
||||
@@ -64,18 +67,18 @@ func TestInitCheckImageFail(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
err := client.InitEngine(ctx, opts, &testOutStream{}, &types.AuthConfig{}, healthfnHappy)
|
||||
err := client.InitEngine(ctx, opts, command.NewOutStream(&bytes.Buffer{}), &types.AuthConfig{}, healthfnHappy)
|
||||
assert.ErrorContains(t, err, "unable to check for image")
|
||||
assert.ErrorContains(t, err, "something went wrong")
|
||||
}
|
||||
|
||||
func TestInitPullFail(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
opts := EngineInitOptions{
|
||||
opts := clitypes.EngineInitOptions{
|
||||
EngineVersion: "engineversiongoeshere",
|
||||
RegistryPrefix: "registryprefixgoeshere",
|
||||
ConfigFile: "/tmp/configfilegoeshere",
|
||||
EngineImage: CommunityEngineImage,
|
||||
EngineImage: clitypes.CommunityEngineImage,
|
||||
}
|
||||
client := baseClient{
|
||||
cclient: &fakeContainerdClient{
|
||||
@@ -92,18 +95,18 @@ func TestInitPullFail(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
err := client.InitEngine(ctx, opts, &testOutStream{}, &types.AuthConfig{}, healthfnHappy)
|
||||
err := client.InitEngine(ctx, opts, command.NewOutStream(&bytes.Buffer{}), &types.AuthConfig{}, healthfnHappy)
|
||||
assert.ErrorContains(t, err, "unable to pull image")
|
||||
assert.ErrorContains(t, err, "pull failure")
|
||||
}
|
||||
|
||||
func TestInitStartFail(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
opts := EngineInitOptions{
|
||||
opts := clitypes.EngineInitOptions{
|
||||
EngineVersion: "engineversiongoeshere",
|
||||
RegistryPrefix: "registryprefixgoeshere",
|
||||
ConfigFile: "/tmp/configfilegoeshere",
|
||||
EngineImage: CommunityEngineImage,
|
||||
EngineImage: clitypes.CommunityEngineImage,
|
||||
}
|
||||
client := baseClient{
|
||||
cclient: &fakeContainerdClient{
|
||||
@@ -120,7 +123,7 @@ func TestInitStartFail(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
err := client.InitEngine(ctx, opts, &testOutStream{}, &types.AuthConfig{}, healthfnHappy)
|
||||
err := client.InitEngine(ctx, opts, command.NewOutStream(&bytes.Buffer{}), &types.AuthConfig{}, healthfnHappy)
|
||||
assert.ErrorContains(t, err, "failed to create docker daemon")
|
||||
}
|
||||
|
||||
@@ -210,7 +213,7 @@ func TestWaitForEngineNeverShowsUp(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
err := client.waitForEngine(ctx, &testOutStream{}, healthfnError)
|
||||
err := client.waitForEngine(ctx, command.NewOutStream(&bytes.Buffer{}), healthfnError)
|
||||
assert.ErrorContains(t, err, "timeout waiting")
|
||||
}
|
||||
|
||||
@@ -227,7 +230,7 @@ func TestWaitForEnginePingFail(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
err := client.waitForEngine(ctx, &testOutStream{}, healthfnError)
|
||||
err := client.waitForEngine(ctx, command.NewOutStream(&bytes.Buffer{}), healthfnError)
|
||||
assert.ErrorContains(t, err, "ping fail")
|
||||
}
|
||||
|
||||
@@ -244,7 +247,7 @@ func TestWaitForEngineHealthy(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
err := client.waitForEngine(ctx, &testOutStream{}, healthfnHappy)
|
||||
err := client.waitForEngine(ctx, command.NewOutStream(&bytes.Buffer{}), healthfnHappy)
|
||||
assert.NilError(t, err)
|
||||
}
|
||||
|
||||
@@ -260,7 +263,7 @@ func TestRemoveEngineBadTaskBadDelete(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
err := client.RemoveEngine(ctx, container)
|
||||
err := client.removeEngine(ctx, container)
|
||||
assert.ErrorContains(t, err, "failed to remove existing engine")
|
||||
assert.ErrorContains(t, err, "delete failure")
|
||||
}
|
||||
@@ -279,7 +282,7 @@ func TestRemoveEngineTaskNoStatus(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
err := client.RemoveEngine(ctx, container)
|
||||
err := client.removeEngine(ctx, container)
|
||||
assert.ErrorContains(t, err, "task status failure")
|
||||
}
|
||||
|
||||
@@ -300,7 +303,7 @@ func TestRemoveEngineTaskNotRunningDeleteFail(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
err := client.RemoveEngine(ctx, container)
|
||||
err := client.removeEngine(ctx, container)
|
||||
assert.ErrorContains(t, err, "task delete failure")
|
||||
}
|
||||
|
||||
@@ -321,7 +324,7 @@ func TestRemoveEngineTaskRunningKillFail(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
err := client.RemoveEngine(ctx, container)
|
||||
err := client.removeEngine(ctx, container)
|
||||
assert.ErrorContains(t, err, "task kill failure")
|
||||
}
|
||||
|
||||
@@ -342,7 +345,7 @@ func TestRemoveEngineTaskRunningWaitFail(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
err := client.RemoveEngine(ctx, container)
|
||||
err := client.removeEngine(ctx, container)
|
||||
assert.ErrorContains(t, err, "task wait failure")
|
||||
}
|
||||
|
||||
@@ -365,7 +368,7 @@ func TestRemoveEngineTaskRunningHappyPath(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
err := client.RemoveEngine(ctx, container)
|
||||
err := client.removeEngine(ctx, container)
|
||||
assert.NilError(t, err)
|
||||
}
|
||||
|
||||
@@ -389,7 +392,7 @@ func TestRemoveEngineTaskKillTimeout(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
err := client.RemoveEngine(ctx, container)
|
||||
err := client.removeEngine(ctx, container)
|
||||
assert.Assert(t, err == ErrEngineShutdownTimeout)
|
||||
}
|
||||
|
||||
|
||||
@@ -3,24 +3,14 @@ package containerizedengine
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"io"
|
||||
|
||||
"github.com/containerd/containerd"
|
||||
"github.com/containerd/containerd/containers"
|
||||
"github.com/containerd/containerd/content"
|
||||
registryclient "github.com/docker/cli/cli/registry/client"
|
||||
"github.com/docker/docker/api/types"
|
||||
ver "github.com/hashicorp/go-version"
|
||||
specs "github.com/opencontainers/runtime-spec/specs-go"
|
||||
)
|
||||
|
||||
const (
|
||||
// CommunityEngineImage is the repo name for the community engine
|
||||
CommunityEngineImage = "engine-community"
|
||||
|
||||
// EnterpriseEngineImage is the repo name for the enterprise engine
|
||||
EnterpriseEngineImage = "engine-enterprise"
|
||||
|
||||
containerdSockPath = "/run/containerd/containerd.sock"
|
||||
engineContainerName = "dockerd"
|
||||
engineNamespace = "docker"
|
||||
@@ -79,45 +69,10 @@ var (
|
||||
}
|
||||
)
|
||||
|
||||
// Client can be used to manage the lifecycle of
|
||||
// dockerd running as a container on containerd.
|
||||
type Client interface {
|
||||
Close() error
|
||||
ActivateEngine(ctx context.Context,
|
||||
opts EngineInitOptions,
|
||||
out OutStream,
|
||||
authConfig *types.AuthConfig,
|
||||
healthfn func(context.Context) error) error
|
||||
InitEngine(ctx context.Context,
|
||||
opts EngineInitOptions,
|
||||
out OutStream,
|
||||
authConfig *types.AuthConfig,
|
||||
healthfn func(context.Context) error) error
|
||||
DoUpdate(ctx context.Context,
|
||||
opts EngineInitOptions,
|
||||
out OutStream,
|
||||
authConfig *types.AuthConfig,
|
||||
healthfn func(context.Context) error) error
|
||||
GetEngineVersions(ctx context.Context, registryClient registryclient.RegistryClient, currentVersion, imageName string) (AvailableVersions, error)
|
||||
|
||||
GetEngine(ctx context.Context) (containerd.Container, error)
|
||||
RemoveEngine(ctx context.Context, engine containerd.Container) error
|
||||
GetCurrentEngineVersion(ctx context.Context) (EngineInitOptions, error)
|
||||
}
|
||||
type baseClient struct {
|
||||
cclient containerdClient
|
||||
}
|
||||
|
||||
// EngineInitOptions contains the configuration settings
|
||||
// use during initialization of a containerized docker engine
|
||||
type EngineInitOptions struct {
|
||||
RegistryPrefix string
|
||||
EngineImage string
|
||||
EngineVersion string
|
||||
ConfigFile string
|
||||
scope string
|
||||
}
|
||||
|
||||
// containerdClient abstracts the containerd client to aid in testability
|
||||
type containerdClient interface {
|
||||
Containers(ctx context.Context, filters ...string) ([]containerd.Container, error)
|
||||
@@ -128,32 +83,3 @@ type containerdClient interface {
|
||||
ContentStore() content.Store
|
||||
ContainerService() containers.Store
|
||||
}
|
||||
|
||||
// AvailableVersions groups the available versions which were discovered
|
||||
type AvailableVersions struct {
|
||||
Downgrades []DockerVersion
|
||||
Patches []DockerVersion
|
||||
Upgrades []DockerVersion
|
||||
}
|
||||
|
||||
// DockerVersion wraps a semantic version to retain the original tag
|
||||
// since the docker date based versions don't strictly follow semantic
|
||||
// versioning (leading zeros, etc.)
|
||||
type DockerVersion struct {
|
||||
ver.Version
|
||||
Tag string
|
||||
}
|
||||
|
||||
// Update stores available updates for rendering in a table
|
||||
type Update struct {
|
||||
Type string
|
||||
Version string
|
||||
Notes string
|
||||
}
|
||||
|
||||
// OutStream is an output stream used to write normal program output.
|
||||
type OutStream interface {
|
||||
io.Writer
|
||||
FD() uintptr
|
||||
IsTerminal() bool
|
||||
}
|
||||
|
||||
@@ -9,16 +9,17 @@ import (
|
||||
"github.com/containerd/containerd/errdefs"
|
||||
"github.com/containerd/containerd/namespaces"
|
||||
"github.com/docker/cli/internal/pkg/containerized"
|
||||
clitypes "github.com/docker/cli/types"
|
||||
"github.com/docker/distribution/reference"
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// GetCurrentEngineVersion determines the current type of engine (image) and version
|
||||
func (c baseClient) GetCurrentEngineVersion(ctx context.Context) (EngineInitOptions, error) {
|
||||
func (c *baseClient) GetCurrentEngineVersion(ctx context.Context) (clitypes.EngineInitOptions, error) {
|
||||
ctx = namespaces.WithNamespace(ctx, engineNamespace)
|
||||
ret := EngineInitOptions{}
|
||||
currentEngine := CommunityEngineImage
|
||||
ret := clitypes.EngineInitOptions{}
|
||||
currentEngine := clitypes.CommunityEngineImage
|
||||
engine, err := c.GetEngine(ctx)
|
||||
if err != nil {
|
||||
if err == ErrEngineNotPresent {
|
||||
@@ -35,8 +36,8 @@ func (c baseClient) GetCurrentEngineVersion(ctx context.Context) (EngineInitOpti
|
||||
return ret, errors.Wrapf(err, "failed to parse image name: %s", imageName)
|
||||
}
|
||||
|
||||
if strings.Contains(distributionRef.Name(), EnterpriseEngineImage) {
|
||||
currentEngine = EnterpriseEngineImage
|
||||
if strings.Contains(distributionRef.Name(), clitypes.EnterpriseEngineImage) {
|
||||
currentEngine = clitypes.EnterpriseEngineImage
|
||||
}
|
||||
taggedRef, ok := distributionRef.(reference.NamedTagged)
|
||||
if !ok {
|
||||
@@ -49,11 +50,11 @@ func (c baseClient) GetCurrentEngineVersion(ctx context.Context) (EngineInitOpti
|
||||
}
|
||||
|
||||
// ActivateEngine will switch the image from the CE to EE image
|
||||
func (c baseClient) ActivateEngine(ctx context.Context, opts EngineInitOptions, out OutStream,
|
||||
func (c *baseClient) ActivateEngine(ctx context.Context, opts clitypes.EngineInitOptions, out clitypes.OutStream,
|
||||
authConfig *types.AuthConfig, healthfn func(context.Context) error) error {
|
||||
|
||||
// set the proxy scope to "ee" for activate flows
|
||||
opts.scope = "ee"
|
||||
opts.Scope = "ee"
|
||||
|
||||
ctx = namespaces.WithNamespace(ctx, engineNamespace)
|
||||
|
||||
@@ -64,7 +65,7 @@ func (c baseClient) ActivateEngine(ctx context.Context, opts EngineInitOptions,
|
||||
return err
|
||||
}
|
||||
opts.EngineVersion = currentOpts.EngineVersion
|
||||
if currentOpts.EngineImage == EnterpriseEngineImage {
|
||||
if currentOpts.EngineImage == clitypes.EnterpriseEngineImage {
|
||||
// This is a "no-op" activation so the only change would be the license - don't update the engine itself
|
||||
return nil
|
||||
}
|
||||
@@ -73,7 +74,7 @@ func (c baseClient) ActivateEngine(ctx context.Context, opts EngineInitOptions,
|
||||
}
|
||||
|
||||
// DoUpdate performs the underlying engine update
|
||||
func (c baseClient) DoUpdate(ctx context.Context, opts EngineInitOptions, out OutStream,
|
||||
func (c *baseClient) DoUpdate(ctx context.Context, opts clitypes.EngineInitOptions, out clitypes.OutStream,
|
||||
authConfig *types.AuthConfig, healthfn func(context.Context) error) error {
|
||||
|
||||
ctx = namespaces.WithNamespace(ctx, engineNamespace)
|
||||
@@ -117,13 +118,13 @@ func (c baseClient) DoUpdate(ctx context.Context, opts EngineInitOptions, out Ou
|
||||
defer cancel()
|
||||
return c.waitForEngine(ctx, out, healthfn)
|
||||
})
|
||||
if err == nil && opts.scope != "" {
|
||||
if err == nil && opts.Scope != "" {
|
||||
var labels map[string]string
|
||||
labels, err = engine.Labels(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
labels[proxyLabel] = opts.scope
|
||||
labels[proxyLabel] = opts.Scope
|
||||
_, err = engine.SetLabels(ctx, labels)
|
||||
}
|
||||
return err
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package containerizedengine
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"testing"
|
||||
@@ -8,6 +9,8 @@ import (
|
||||
"github.com/containerd/containerd"
|
||||
"github.com/containerd/containerd/cio"
|
||||
"github.com/containerd/containerd/errdefs"
|
||||
"github.com/docker/cli/cli/command"
|
||||
clitypes "github.com/docker/cli/types"
|
||||
"github.com/docker/docker/api/types"
|
||||
"gotest.tools/assert"
|
||||
)
|
||||
@@ -16,7 +19,7 @@ func TestGetCurrentEngineVersionHappy(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
image := &fakeImage{
|
||||
nameFunc: func() string {
|
||||
return "acme.com/dockermirror/" + CommunityEngineImage + ":engineversion"
|
||||
return "acme.com/dockermirror/" + clitypes.CommunityEngineImage + ":engineversion"
|
||||
},
|
||||
}
|
||||
container := &fakeContainer{
|
||||
@@ -34,7 +37,7 @@ func TestGetCurrentEngineVersionHappy(t *testing.T) {
|
||||
|
||||
opts, err := client.GetCurrentEngineVersion(ctx)
|
||||
assert.NilError(t, err)
|
||||
assert.Equal(t, opts.EngineImage, CommunityEngineImage)
|
||||
assert.Equal(t, opts.EngineImage, clitypes.CommunityEngineImage)
|
||||
assert.Equal(t, opts.RegistryPrefix, "acme.com/dockermirror")
|
||||
assert.Equal(t, opts.EngineVersion, "engineversion")
|
||||
}
|
||||
@@ -43,7 +46,7 @@ func TestGetCurrentEngineVersionEnterpriseHappy(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
image := &fakeImage{
|
||||
nameFunc: func() string {
|
||||
return "docker.io/docker/" + EnterpriseEngineImage + ":engineversion"
|
||||
return "docker.io/docker/" + clitypes.EnterpriseEngineImage + ":engineversion"
|
||||
},
|
||||
}
|
||||
container := &fakeContainer{
|
||||
@@ -61,7 +64,7 @@ func TestGetCurrentEngineVersionEnterpriseHappy(t *testing.T) {
|
||||
|
||||
opts, err := client.GetCurrentEngineVersion(ctx)
|
||||
assert.NilError(t, err)
|
||||
assert.Equal(t, opts.EngineImage, EnterpriseEngineImage)
|
||||
assert.Equal(t, opts.EngineImage, clitypes.EnterpriseEngineImage)
|
||||
assert.Equal(t, opts.EngineVersion, "engineversion")
|
||||
assert.Equal(t, opts.RegistryPrefix, "docker.io/docker")
|
||||
}
|
||||
@@ -147,14 +150,14 @@ func TestActivateNoEngine(t *testing.T) {
|
||||
},
|
||||
},
|
||||
}
|
||||
opts := EngineInitOptions{
|
||||
opts := clitypes.EngineInitOptions{
|
||||
EngineVersion: "engineversiongoeshere",
|
||||
RegistryPrefix: "registryprefixgoeshere",
|
||||
ConfigFile: "/tmp/configfilegoeshere",
|
||||
EngineImage: EnterpriseEngineImage,
|
||||
EngineImage: clitypes.EnterpriseEngineImage,
|
||||
}
|
||||
|
||||
err := client.ActivateEngine(ctx, opts, &testOutStream{}, &types.AuthConfig{}, healthfnHappy)
|
||||
err := client.ActivateEngine(ctx, opts, command.NewOutStream(&bytes.Buffer{}), &types.AuthConfig{}, healthfnHappy)
|
||||
assert.ErrorContains(t, err, "unable to find")
|
||||
}
|
||||
|
||||
@@ -163,7 +166,7 @@ func TestActivateNoChange(t *testing.T) {
|
||||
registryPrefix := "registryprefixgoeshere"
|
||||
image := &fakeImage{
|
||||
nameFunc: func() string {
|
||||
return registryPrefix + "/" + EnterpriseEngineImage + ":engineversion"
|
||||
return registryPrefix + "/" + clitypes.EnterpriseEngineImage + ":engineversion"
|
||||
},
|
||||
}
|
||||
container := &fakeContainer{
|
||||
@@ -184,14 +187,14 @@ func TestActivateNoChange(t *testing.T) {
|
||||
},
|
||||
},
|
||||
}
|
||||
opts := EngineInitOptions{
|
||||
opts := clitypes.EngineInitOptions{
|
||||
EngineVersion: "engineversiongoeshere",
|
||||
RegistryPrefix: "registryprefixgoeshere",
|
||||
ConfigFile: "/tmp/configfilegoeshere",
|
||||
EngineImage: EnterpriseEngineImage,
|
||||
EngineImage: clitypes.EnterpriseEngineImage,
|
||||
}
|
||||
|
||||
err := client.ActivateEngine(ctx, opts, &testOutStream{}, &types.AuthConfig{}, healthfnHappy)
|
||||
err := client.ActivateEngine(ctx, opts, command.NewOutStream(&bytes.Buffer{}), &types.AuthConfig{}, healthfnHappy)
|
||||
assert.NilError(t, err)
|
||||
}
|
||||
|
||||
@@ -219,34 +222,34 @@ func TestActivateDoUpdateFail(t *testing.T) {
|
||||
},
|
||||
},
|
||||
}
|
||||
opts := EngineInitOptions{
|
||||
opts := clitypes.EngineInitOptions{
|
||||
EngineVersion: "engineversiongoeshere",
|
||||
RegistryPrefix: "registryprefixgoeshere",
|
||||
ConfigFile: "/tmp/configfilegoeshere",
|
||||
EngineImage: EnterpriseEngineImage,
|
||||
EngineImage: clitypes.EnterpriseEngineImage,
|
||||
}
|
||||
|
||||
err := client.ActivateEngine(ctx, opts, &testOutStream{}, &types.AuthConfig{}, healthfnHappy)
|
||||
err := client.ActivateEngine(ctx, opts, command.NewOutStream(&bytes.Buffer{}), &types.AuthConfig{}, healthfnHappy)
|
||||
assert.ErrorContains(t, err, "check for image")
|
||||
assert.ErrorContains(t, err, "something went wrong")
|
||||
}
|
||||
|
||||
func TestDoUpdateNoVersion(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
opts := EngineInitOptions{
|
||||
opts := clitypes.EngineInitOptions{
|
||||
EngineVersion: "",
|
||||
RegistryPrefix: "registryprefixgoeshere",
|
||||
ConfigFile: "/tmp/configfilegoeshere",
|
||||
EngineImage: EnterpriseEngineImage,
|
||||
EngineImage: clitypes.EnterpriseEngineImage,
|
||||
}
|
||||
client := baseClient{}
|
||||
err := client.DoUpdate(ctx, opts, &testOutStream{}, &types.AuthConfig{}, healthfnHappy)
|
||||
err := client.DoUpdate(ctx, opts, command.NewOutStream(&bytes.Buffer{}), &types.AuthConfig{}, healthfnHappy)
|
||||
assert.ErrorContains(t, err, "please pick the version you")
|
||||
}
|
||||
|
||||
func TestDoUpdateImageMiscError(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
opts := EngineInitOptions{
|
||||
opts := clitypes.EngineInitOptions{
|
||||
EngineVersion: "engineversiongoeshere",
|
||||
RegistryPrefix: "registryprefixgoeshere",
|
||||
ConfigFile: "/tmp/configfilegoeshere",
|
||||
@@ -260,14 +263,14 @@ func TestDoUpdateImageMiscError(t *testing.T) {
|
||||
},
|
||||
},
|
||||
}
|
||||
err := client.DoUpdate(ctx, opts, &testOutStream{}, &types.AuthConfig{}, healthfnHappy)
|
||||
err := client.DoUpdate(ctx, opts, command.NewOutStream(&bytes.Buffer{}), &types.AuthConfig{}, healthfnHappy)
|
||||
assert.ErrorContains(t, err, "check for image")
|
||||
assert.ErrorContains(t, err, "something went wrong")
|
||||
}
|
||||
|
||||
func TestDoUpdatePullFail(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
opts := EngineInitOptions{
|
||||
opts := clitypes.EngineInitOptions{
|
||||
EngineVersion: "engineversiongoeshere",
|
||||
RegistryPrefix: "registryprefixgoeshere",
|
||||
ConfigFile: "/tmp/configfilegoeshere",
|
||||
@@ -284,14 +287,14 @@ func TestDoUpdatePullFail(t *testing.T) {
|
||||
},
|
||||
},
|
||||
}
|
||||
err := client.DoUpdate(ctx, opts, &testOutStream{}, &types.AuthConfig{}, healthfnHappy)
|
||||
err := client.DoUpdate(ctx, opts, command.NewOutStream(&bytes.Buffer{}), &types.AuthConfig{}, healthfnHappy)
|
||||
assert.ErrorContains(t, err, "unable to pull")
|
||||
assert.ErrorContains(t, err, "pull failure")
|
||||
}
|
||||
|
||||
func TestDoUpdateEngineMissing(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
opts := EngineInitOptions{
|
||||
opts := clitypes.EngineInitOptions{
|
||||
EngineVersion: "engineversiongoeshere",
|
||||
RegistryPrefix: "registryprefixgoeshere",
|
||||
ConfigFile: "/tmp/configfilegoeshere",
|
||||
@@ -313,6 +316,6 @@ func TestDoUpdateEngineMissing(t *testing.T) {
|
||||
},
|
||||
},
|
||||
}
|
||||
err := client.DoUpdate(ctx, opts, &testOutStream{}, &types.AuthConfig{}, healthfnHappy)
|
||||
err := client.DoUpdate(ctx, opts, command.NewOutStream(&bytes.Buffer{}), &types.AuthConfig{}, healthfnHappy)
|
||||
assert.ErrorContains(t, err, "unable to find existing engine")
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"sort"
|
||||
|
||||
registryclient "github.com/docker/cli/cli/registry/client"
|
||||
clitypes "github.com/docker/cli/types"
|
||||
"github.com/docker/distribution/reference"
|
||||
ver "github.com/hashicorp/go-version"
|
||||
"github.com/pkg/errors"
|
||||
@@ -12,29 +13,29 @@ import (
|
||||
)
|
||||
|
||||
// GetEngineVersions reports the versions of the engine that are available
|
||||
func (c baseClient) GetEngineVersions(ctx context.Context, registryClient registryclient.RegistryClient, currentVersion, imageName string) (AvailableVersions, error) {
|
||||
func (c *baseClient) GetEngineVersions(ctx context.Context, registryClient registryclient.RegistryClient, currentVersion, imageName string) (clitypes.AvailableVersions, error) {
|
||||
imageRef, err := reference.ParseNormalizedNamed(imageName)
|
||||
if err != nil {
|
||||
return AvailableVersions{}, err
|
||||
return clitypes.AvailableVersions{}, err
|
||||
}
|
||||
|
||||
tags, err := registryClient.GetTags(ctx, imageRef)
|
||||
if err != nil {
|
||||
return AvailableVersions{}, err
|
||||
return clitypes.AvailableVersions{}, err
|
||||
}
|
||||
|
||||
return parseTags(tags, currentVersion)
|
||||
}
|
||||
|
||||
func parseTags(tags []string, currentVersion string) (AvailableVersions, error) {
|
||||
var ret AvailableVersions
|
||||
func parseTags(tags []string, currentVersion string) (clitypes.AvailableVersions, error) {
|
||||
var ret clitypes.AvailableVersions
|
||||
currentVer, err := ver.NewVersion(currentVersion)
|
||||
if err != nil {
|
||||
return ret, errors.Wrapf(err, "failed to parse existing version %s", currentVersion)
|
||||
}
|
||||
downgrades := []DockerVersion{}
|
||||
patches := []DockerVersion{}
|
||||
upgrades := []DockerVersion{}
|
||||
downgrades := []clitypes.DockerVersion{}
|
||||
patches := []clitypes.DockerVersion{}
|
||||
upgrades := []clitypes.DockerVersion{}
|
||||
currentSegments := currentVer.Segments()
|
||||
for _, tag := range tags {
|
||||
tmp, err := ver.NewVersion(tag)
|
||||
@@ -42,7 +43,7 @@ func parseTags(tags []string, currentVersion string) (AvailableVersions, error)
|
||||
logrus.Debugf("Unable to parse %s: %s", tag, err)
|
||||
continue
|
||||
}
|
||||
testVersion := DockerVersion{Version: *tmp, Tag: tag}
|
||||
testVersion := clitypes.DockerVersion{Version: *tmp, Tag: tag}
|
||||
if testVersion.LessThan(currentVer) {
|
||||
downgrades = append(downgrades, testVersion)
|
||||
continue
|
||||
|
||||
@@ -12,7 +12,7 @@ import (
|
||||
manifeststore "github.com/docker/cli/cli/manifest/store"
|
||||
registryclient "github.com/docker/cli/cli/registry/client"
|
||||
"github.com/docker/cli/cli/trust"
|
||||
"github.com/docker/cli/internal/containerizedengine"
|
||||
clitypes "github.com/docker/cli/types"
|
||||
"github.com/docker/docker/client"
|
||||
notaryclient "github.com/theupdateframework/notary/client"
|
||||
)
|
||||
@@ -20,7 +20,7 @@ import (
|
||||
// NotaryClientFuncType defines a function that returns a fake notary client
|
||||
type NotaryClientFuncType func(imgRefAndAuth trust.ImageRefAndAuth, actions []string) (notaryclient.Repository, error)
|
||||
type clientInfoFuncType func() command.ClientInfo
|
||||
type containerizedEngineFuncType func(string) (containerizedengine.Client, error)
|
||||
type containerizedEngineFuncType func(string) (clitypes.ContainerizedClient, error)
|
||||
|
||||
// FakeCli emulates the default DockerCli
|
||||
type FakeCli struct {
|
||||
@@ -172,7 +172,7 @@ func EnableContentTrust(c *FakeCli) {
|
||||
}
|
||||
|
||||
// NewContainerizedEngineClient returns a containerized engine client
|
||||
func (c *FakeCli) NewContainerizedEngineClient(sockPath string) (containerizedengine.Client, error) {
|
||||
func (c *FakeCli) NewContainerizedEngineClient(sockPath string) (clitypes.ContainerizedClient, error) {
|
||||
if c.containerizedEngineClientFunc != nil {
|
||||
return c.containerizedEngineClientFunc(sockPath)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user