api/types: move ContainerCreateConfig, ContainerRmConfig to api/types/backend

The `ContainerCreateConfig` and `ContainerRmConfig` structs are used for
options to be passed to the backend, and are not used in client code.

Thess struct currently is intended for internal use only (for example, the
`AdjustCPUShares` is an internal implementation details to adjust the container's
config when older API versions are used).

Somewhat ironically, the signature of the Backend has a nicer UX than that
of the client's `ContainerCreate` signature (which expects all options to
be passed as separate arguments), so we may want to update that signature
to be closer to what the backend is using, but that can be left as a future
exercise.

This patch moves the `ContainerCreateConfig` and `ContainerRmConfig` structs
to the backend package to prevent it being imported in the client, and to make
it more clear that this is part of internal APIs, and not public-facing.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
Sebastiaan van Stijn 2023-12-05 15:58:22 +01:00
parent 2a38569337
commit 484e6b784c
No known key found for this signature in database
GPG key ID: 76698F39D527CE8C
18 changed files with 64 additions and 68 deletions

View file

@ -32,13 +32,13 @@ type copyBackend interface {
// stateBackend includes functions to implement to provide container state lifecycle functionality.
type stateBackend interface {
ContainerCreate(ctx context.Context, config types.ContainerCreateConfig) (container.CreateResponse, error)
ContainerCreate(ctx context.Context, config backend.ContainerCreateConfig) (container.CreateResponse, error)
ContainerKill(name string, signal string) error
ContainerPause(name string) error
ContainerRename(oldName, newName string) error
ContainerResize(name string, height, width int) error
ContainerRestart(ctx context.Context, name string, options container.StopOptions) error
ContainerRm(name string, config *types.ContainerRmConfig) error
ContainerRm(name string, config *backend.ContainerRmConfig) error
ContainerStart(ctx context.Context, name string, hostConfig *container.HostConfig, checkpoint string, checkpointDir string) error
ContainerStop(ctx context.Context, name string, options container.StopOptions) error
ContainerUnpause(name string) error

View file

@ -643,7 +643,7 @@ func (s *containerRouter) postContainersCreate(ctx context.Context, w http.Respo
hostConfig.PidsLimit = nil
}
ccr, err := s.backend.ContainerCreate(ctx, types.ContainerCreateConfig{
ccr, err := s.backend.ContainerCreate(ctx, backend.ContainerCreateConfig{
Name: name,
Config: config,
HostConfig: hostConfig,
@ -712,7 +712,7 @@ func (s *containerRouter) deleteContainers(ctx context.Context, w http.ResponseW
}
name := vars["name"]
config := &types.ContainerRmConfig{
config := &backend.ContainerRmConfig{
ForceRemove: httputils.BoolValue(r, "force"),
RemoveVolume: httputils.BoolValue(r, "v"),
RemoveLink: httputils.BoolValue(r, "link"),

View file

@ -7,8 +7,27 @@ import (
"github.com/distribution/reference"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/network"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
)
// ContainerCreateConfig is the parameter set to ContainerCreate()
type ContainerCreateConfig struct {
Name string
Config *container.Config
HostConfig *container.HostConfig
NetworkingConfig *network.NetworkingConfig
Platform *ocispec.Platform
AdjustCPUShares bool
}
// ContainerRmConfig holds arguments for the container remove
// operation. This struct is used to tell the backend what operations
// to perform.
type ContainerRmConfig struct {
ForceRemove, RemoveVolume, RemoveLink bool
}
// ContainerAttachConfig holds the streams to use when connecting to a container to view logs.
type ContainerAttachConfig struct {
GetStreams func(multiplexed bool) (io.ReadCloser, io.Writer, io.Writer, error)

View file

@ -1,32 +1,9 @@
package types // import "github.com/docker/docker/api/types"
import (
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/network"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
)
// configs holds structs used for internal communication between the
// frontend (such as an http server) and the backend (such as the
// docker daemon).
// ContainerCreateConfig is the parameter set to ContainerCreate()
type ContainerCreateConfig struct {
Name string
Config *container.Config
HostConfig *container.HostConfig
NetworkingConfig *network.NetworkingConfig
Platform *ocispec.Platform
AdjustCPUShares bool
}
// ContainerRmConfig holds arguments for the container remove
// operation. This struct is used to tell the backend what operations
// to perform.
type ContainerRmConfig struct {
ForceRemove, RemoveVolume, RemoveLink bool
}
// ExecConfig is a small subset of the Config struct that holds the configuration
// for the exec feature of docker.
type ExecConfig struct {

View file

@ -8,7 +8,6 @@ import (
"context"
"io"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/backend"
"github.com/docker/docker/api/types/container"
containerpkg "github.com/docker/docker/container"
@ -60,9 +59,9 @@ type ExecBackend interface {
// ContainerAttachRaw attaches to container.
ContainerAttachRaw(cID string, stdin io.ReadCloser, stdout, stderr io.Writer, stream bool, attached chan struct{}) error
// ContainerCreateIgnoreImagesArgsEscaped creates a new Docker container and returns potential warnings
ContainerCreateIgnoreImagesArgsEscaped(ctx context.Context, config types.ContainerCreateConfig) (container.CreateResponse, error)
ContainerCreateIgnoreImagesArgsEscaped(ctx context.Context, config backend.ContainerCreateConfig) (container.CreateResponse, error)
// ContainerRm removes a container specified by `id`.
ContainerRm(name string, config *types.ContainerRmConfig) error
ContainerRm(name string, config *backend.ContainerRmConfig) error
// ContainerKill stops the container execution abruptly.
ContainerKill(containerID string, sig string) error
// ContainerStart starts a new container

View file

@ -6,7 +6,7 @@ import (
"io"
"github.com/containerd/log"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/backend"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/builder"
containerpkg "github.com/docker/docker/container"
@ -29,15 +29,15 @@ func newContainerManager(docker builder.ExecBackend) *containerManager {
// Create a container
func (c *containerManager) Create(ctx context.Context, runConfig *container.Config, hostConfig *container.HostConfig) (container.CreateResponse, error) {
container, err := c.backend.ContainerCreateIgnoreImagesArgsEscaped(ctx, types.ContainerCreateConfig{
ctr, err := c.backend.ContainerCreateIgnoreImagesArgsEscaped(ctx, backend.ContainerCreateConfig{
Config: runConfig,
HostConfig: hostConfig,
})
if err != nil {
return container, err
return ctr, err
}
c.tmpContainers[container.ID] = struct{}{}
return container, nil
c.tmpContainers[ctr.ID] = struct{}{}
return ctr, nil
}
var errCancelled = errors.New("build cancelled")
@ -123,7 +123,7 @@ func (e *statusCodeError) StatusCode() int {
}
func (c *containerManager) removeContainer(containerID string, stdout io.Writer) error {
rmConfig := &types.ContainerRmConfig{
rmConfig := &backend.ContainerRmConfig{
ForceRemove: true,
RemoveVolume: true,
}

View file

@ -479,7 +479,7 @@ func TestRunWithBuildArgs(t *testing.T) {
config: &container.Config{Cmd: origCmd},
}, nil, nil
}
mockBackend.containerCreateFunc = func(config types.ContainerCreateConfig) (container.CreateResponse, error) {
mockBackend.containerCreateFunc = func(config backend.ContainerCreateConfig) (container.CreateResponse, error) {
// Check the runConfig.Cmd sent to create()
assert.Check(t, is.DeepEqual(cmdWithShell, config.Config.Cmd))
assert.Check(t, is.Contains(config.Config.Env, "one=two"))
@ -548,7 +548,7 @@ func TestRunIgnoresHealthcheck(t *testing.T) {
config: &container.Config{Cmd: origCmd},
}, nil, nil
}
mockBackend.containerCreateFunc = func(config types.ContainerCreateConfig) (container.CreateResponse, error) {
mockBackend.containerCreateFunc = func(config backend.ContainerCreateConfig) (container.CreateResponse, error) {
return container.CreateResponse{ID: "12345"}, nil
}
mockBackend.commitFunc = func(cfg backend.CommitConfig) (image.ID, error) {
@ -575,7 +575,7 @@ func TestRunIgnoresHealthcheck(t *testing.T) {
assert.NilError(t, dispatch(context.TODO(), sb, cmd))
assert.Assert(t, sb.state.runConfig.Healthcheck != nil)
mockBackend.containerCreateFunc = func(config types.ContainerCreateConfig) (container.CreateResponse, error) {
mockBackend.containerCreateFunc = func(config backend.ContainerCreateConfig) (container.CreateResponse, error) {
// Check the Healthcheck is disabled.
assert.Check(t, is.DeepEqual([]string{"NONE"}, config.Config.Healthcheck.Test))
return container.CreateResponse{ID: "123456"}, nil

View file

@ -6,7 +6,6 @@ import (
"io"
"runtime"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/backend"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/builder"
@ -18,7 +17,7 @@ import (
// MockBackend implements the builder.Backend interface for unit testing
type MockBackend struct {
containerCreateFunc func(config types.ContainerCreateConfig) (container.CreateResponse, error)
containerCreateFunc func(config backend.ContainerCreateConfig) (container.CreateResponse, error)
commitFunc func(backend.CommitConfig) (image.ID, error)
getImageFunc func(string) (builder.Image, builder.ROLayer, error)
makeImageCacheFunc func(cacheFrom []string) builder.ImageCache
@ -28,14 +27,14 @@ func (m *MockBackend) ContainerAttachRaw(cID string, stdin io.ReadCloser, stdout
return nil
}
func (m *MockBackend) ContainerCreateIgnoreImagesArgsEscaped(ctx context.Context, config types.ContainerCreateConfig) (container.CreateResponse, error) {
func (m *MockBackend) ContainerCreateIgnoreImagesArgsEscaped(ctx context.Context, config backend.ContainerCreateConfig) (container.CreateResponse, error) {
if m.containerCreateFunc != nil {
return m.containerCreateFunc(config)
}
return container.CreateResponse{}, nil
}
func (m *MockBackend) ContainerRm(name string, config *types.ContainerRmConfig) error {
func (m *MockBackend) ContainerRm(name string, config *backend.ContainerRmConfig) error {
return nil
}

View file

@ -38,7 +38,7 @@ type Backend interface {
FindNetwork(idName string) (*libnetwork.Network, error)
SetupIngress(clustertypes.NetworkCreateRequest, string) (<-chan struct{}, error)
ReleaseIngress() (<-chan struct{}, error)
CreateManagedContainer(ctx context.Context, config types.ContainerCreateConfig) (container.CreateResponse, error)
CreateManagedContainer(ctx context.Context, config backend.ContainerCreateConfig) (container.CreateResponse, error)
ContainerStart(ctx context.Context, name string, hostConfig *container.HostConfig, checkpoint string, checkpointDir string) error
ContainerStop(ctx context.Context, name string, config container.StopOptions) error
ContainerLogs(ctx context.Context, name string, config *container.LogsOptions) (msgs <-chan *backend.LogMessage, tty bool, err error)
@ -48,7 +48,7 @@ type Backend interface {
UpdateContainerServiceConfig(containerName string, serviceConfig *clustertypes.ServiceConfig) error
ContainerInspectCurrent(ctx context.Context, name string, size bool) (*types.ContainerJSON, error)
ContainerWait(ctx context.Context, name string, condition containerpkg.WaitCondition) (<-chan containerpkg.StateStatus, error)
ContainerRm(name string, config *types.ContainerRmConfig) error
ContainerRm(name string, config *backend.ContainerRmConfig) error
ContainerKill(name string, sig string) error
SetContainerDependencyStore(name string, store exec.DependencyGetter) error
SetContainerSecretReferences(name string, refs []*swarm.SecretReference) error

View file

@ -293,7 +293,7 @@ func (c *containerAdapter) waitForDetach(ctx context.Context) error {
func (c *containerAdapter) create(ctx context.Context) error {
var cr containertypes.CreateResponse
var err error
if cr, err = c.backend.CreateManagedContainer(ctx, types.ContainerCreateConfig{
if cr, err = c.backend.CreateManagedContainer(ctx, backend.ContainerCreateConfig{
Name: c.container.name(),
Config: c.container.config(),
HostConfig: c.container.hostConfig(c.dependencies.Volumes()),
@ -417,7 +417,7 @@ func (c *containerAdapter) terminate(ctx context.Context) error {
}
func (c *containerAdapter) remove(ctx context.Context) error {
return c.backend.ContainerRm(c.container.name(), &types.ContainerRmConfig{
return c.backend.ContainerRm(c.container.name(), &backend.ContainerRmConfig{
RemoveVolume: true,
ForceRemove: true,
})

View file

@ -8,7 +8,7 @@ import (
"time"
"github.com/containerd/log"
apitypes "github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/backend"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/filters"
types "github.com/docker/docker/api/types/swarm"
@ -414,7 +414,7 @@ func (c *Cluster) Leave(ctx context.Context, force bool) error {
return err
}
for _, id := range nodeContainers {
if err := c.config.Backend.ContainerRm(id, &apitypes.ContainerRmConfig{ForceRemove: true}); err != nil {
if err := c.config.Backend.ContainerRm(id, &backend.ContainerRmConfig{ForceRemove: true}); err != nil {
log.G(ctx).Errorf("error removing %v: %v", id, err)
}
}

View file

@ -9,7 +9,7 @@ import (
"github.com/containerd/containerd/platforms"
"github.com/containerd/log"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/backend"
containertypes "github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/events"
imagetypes "github.com/docker/docker/api/types/image"
@ -28,13 +28,13 @@ import (
)
type createOpts struct {
params types.ContainerCreateConfig
params backend.ContainerCreateConfig
managed bool
ignoreImagesArgsEscaped bool
}
// CreateManagedContainer creates a container that is managed by a Service
func (daemon *Daemon) CreateManagedContainer(ctx context.Context, params types.ContainerCreateConfig) (containertypes.CreateResponse, error) {
func (daemon *Daemon) CreateManagedContainer(ctx context.Context, params backend.ContainerCreateConfig) (containertypes.CreateResponse, error) {
return daemon.containerCreate(ctx, daemon.config(), createOpts{
params: params,
managed: true,
@ -42,7 +42,7 @@ func (daemon *Daemon) CreateManagedContainer(ctx context.Context, params types.C
}
// ContainerCreate creates a regular container
func (daemon *Daemon) ContainerCreate(ctx context.Context, params types.ContainerCreateConfig) (containertypes.CreateResponse, error) {
func (daemon *Daemon) ContainerCreate(ctx context.Context, params backend.ContainerCreateConfig) (containertypes.CreateResponse, error) {
return daemon.containerCreate(ctx, daemon.config(), createOpts{
params: params,
})
@ -50,7 +50,7 @@ func (daemon *Daemon) ContainerCreate(ctx context.Context, params types.Containe
// ContainerCreateIgnoreImagesArgsEscaped creates a regular container. This is called from the builder RUN case
// and ensures that we do not take the images ArgsEscaped
func (daemon *Daemon) ContainerCreateIgnoreImagesArgsEscaped(ctx context.Context, params types.ContainerCreateConfig) (containertypes.CreateResponse, error) {
func (daemon *Daemon) ContainerCreateIgnoreImagesArgsEscaped(ctx context.Context, params backend.ContainerCreateConfig) (containertypes.CreateResponse, error) {
return daemon.containerCreate(ctx, daemon.config(), createOpts{
params: params,
ignoreImagesArgsEscaped: true,
@ -176,7 +176,7 @@ func (daemon *Daemon) create(ctx context.Context, daemonCfg *config.Config, opts
}
defer func() {
if retErr != nil {
err = daemon.cleanupContainer(ctr, types.ContainerRmConfig{
err = daemon.cleanupContainer(ctr, backend.ContainerRmConfig{
ForceRemove: true,
RemoveVolume: true,
})

View file

@ -26,6 +26,7 @@ import (
"github.com/distribution/reference"
dist "github.com/docker/distribution"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/backend"
containertypes "github.com/docker/docker/api/types/container"
imagetypes "github.com/docker/docker/api/types/image"
registrytypes "github.com/docker/docker/api/types/registry"
@ -594,7 +595,7 @@ func (daemon *Daemon) restore(cfg *configStore) error {
go func(cid string) {
_ = sem.Acquire(context.Background(), 1)
if err := daemon.containerRm(&cfg.Config, cid, &types.ContainerRmConfig{ForceRemove: true, RemoveVolume: true}); err != nil {
if err := daemon.containerRm(&cfg.Config, cid, &backend.ContainerRmConfig{ForceRemove: true, RemoveVolume: true}); err != nil {
log.G(context.TODO()).WithField("container", cid).WithError(err).Error("failed to remove container")
}

View file

@ -11,7 +11,7 @@ import (
cerrdefs "github.com/containerd/containerd/errdefs"
"github.com/containerd/containerd/leases"
"github.com/containerd/log"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/backend"
containertypes "github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/events"
"github.com/docker/docker/container"
@ -26,11 +26,11 @@ import (
// is returned if the container is not found, or if the remove
// fails. If the remove succeeds, the container name is released, and
// network links are removed.
func (daemon *Daemon) ContainerRm(name string, config *types.ContainerRmConfig) error {
func (daemon *Daemon) ContainerRm(name string, config *backend.ContainerRmConfig) error {
return daemon.containerRm(&daemon.config().Config, name, config)
}
func (daemon *Daemon) containerRm(cfg *config.Config, name string, opts *types.ContainerRmConfig) error {
func (daemon *Daemon) containerRm(cfg *config.Config, name string, opts *backend.ContainerRmConfig) error {
start := time.Now()
ctr, err := daemon.GetContainer(name)
if err != nil {
@ -87,7 +87,7 @@ func (daemon *Daemon) rmLink(cfg *config.Config, container *container.Container,
// cleanupContainer unregisters a container from the daemon, stops stats
// collection and cleanly removes contents and metadata from the filesystem.
func (daemon *Daemon) cleanupContainer(container *container.Container, config types.ContainerRmConfig) error {
func (daemon *Daemon) cleanupContainer(container *container.Container, config backend.ContainerRmConfig) error {
if container.IsRunning() {
if !config.ForceRemove {
if state := container.StateString(); state == "paused" {

View file

@ -5,7 +5,7 @@ import (
"os"
"testing"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/backend"
containertypes "github.com/docker/docker/api/types/container"
"github.com/docker/docker/container"
"github.com/docker/docker/errdefs"
@ -74,7 +74,7 @@ func TestContainerDelete(t *testing.T) {
defer cleanup()
d.containers.Add(c.ID, c)
err := d.ContainerRm(c.ID, &types.ContainerRmConfig{ForceRemove: false})
err := d.ContainerRm(c.ID, &backend.ContainerRmConfig{ForceRemove: false})
assert.Check(t, is.ErrorType(err, errdefs.IsConflict))
assert.Check(t, is.ErrorContains(err, tc.errMsg))
})
@ -93,6 +93,6 @@ func TestContainerDoubleDelete(t *testing.T) {
// Try to remove the container when its state is removalInProgress.
// It should return an error indicating it is under removal progress.
err := d.ContainerRm(c.ID, &types.ContainerRmConfig{ForceRemove: true})
err := d.ContainerRm(c.ID, &backend.ContainerRmConfig{ForceRemove: true})
assert.Check(t, is.ErrorContains(err, fmt.Sprintf("removal of container %s is already in progress", c.ID)))
}

View file

@ -6,7 +6,7 @@ import (
"time"
"github.com/containerd/log"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/backend"
"github.com/docker/docker/api/types/events"
"github.com/docker/docker/container"
"github.com/docker/docker/daemon/config"
@ -306,7 +306,7 @@ func (daemon *Daemon) autoRemove(cfg *config.Config, c *container.Container) {
return
}
err := daemon.containerRm(cfg, c.ID, &types.ContainerRmConfig{ForceRemove: true, RemoveVolume: true})
err := daemon.containerRm(cfg, c.ID, &backend.ContainerRmConfig{ForceRemove: true, RemoveVolume: true})
if err == nil {
return
}

View file

@ -9,6 +9,7 @@ import (
"github.com/containerd/log"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/backend"
"github.com/docker/docker/api/types/events"
"github.com/docker/docker/api/types/filters"
timetypes "github.com/docker/docker/api/types/time"
@ -78,7 +79,7 @@ func (daemon *Daemon) ContainersPrune(ctx context.Context, pruneFilters filters.
return nil, err
}
// TODO: sets RmLink to true?
err = daemon.containerRm(cfg, c.ID, &types.ContainerRmConfig{})
err = daemon.containerRm(cfg, c.ID, &backend.ContainerRmConfig{})
if err != nil {
log.G(ctx).Warnf("failed to prune container %s: %v", c.ID, err)
continue

View file

@ -6,7 +6,7 @@ import (
"time"
"github.com/containerd/log"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/backend"
containertypes "github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/events"
"github.com/docker/docker/container"
@ -142,7 +142,7 @@ func (daemon *Daemon) containerStart(ctx context.Context, daemonCfg *configStore
// if containers AutoRemove flag is set, remove it after clean up
if container.HostConfig.AutoRemove {
container.Unlock()
if err := daemon.containerRm(&daemonCfg.Config, container.ID, &types.ContainerRmConfig{ForceRemove: true, RemoveVolume: true}); err != nil {
if err := daemon.containerRm(&daemonCfg.Config, container.ID, &backend.ContainerRmConfig{ForceRemove: true, RemoveVolume: true}); err != nil {
log.G(ctx).Errorf("can't remove container %s: %v", container.ID, err)
}
container.Lock()