mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Merge pull request #40725 from cpuguy83/check_img_platform
Accept platform spec on container create
This commit is contained in:
commit
5c10ea6ae8
28 changed files with 188 additions and 62 deletions
|
@ -9,6 +9,7 @@ import (
|
|||
"strconv"
|
||||
"syscall"
|
||||
|
||||
"github.com/containerd/containerd/platforms"
|
||||
"github.com/docker/docker/api/server/httputils"
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/backend"
|
||||
|
@ -19,6 +20,7 @@ import (
|
|||
"github.com/docker/docker/errdefs"
|
||||
"github.com/docker/docker/pkg/ioutils"
|
||||
"github.com/docker/docker/pkg/signal"
|
||||
specs "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
"golang.org/x/net/websocket"
|
||||
|
@ -502,6 +504,28 @@ func (s *containerRouter) postContainersCreate(ctx context.Context, w http.Respo
|
|||
}
|
||||
}
|
||||
|
||||
var platform *specs.Platform
|
||||
if versions.GreaterThanOrEqualTo(version, "1.41") {
|
||||
if v := r.Form.Get("platform"); v != "" {
|
||||
p, err := platforms.Parse(v)
|
||||
if err != nil {
|
||||
return errdefs.InvalidParameter(err)
|
||||
}
|
||||
platform = &p
|
||||
}
|
||||
defaultPlatform := platforms.DefaultSpec()
|
||||
if platform == nil {
|
||||
platform = &defaultPlatform
|
||||
}
|
||||
if platform.OS == "" {
|
||||
platform.OS = defaultPlatform.OS
|
||||
}
|
||||
if platform.Architecture == "" {
|
||||
platform.Architecture = defaultPlatform.Architecture
|
||||
platform.Variant = defaultPlatform.Variant
|
||||
}
|
||||
}
|
||||
|
||||
if hostConfig != nil && hostConfig.PidsLimit != nil && *hostConfig.PidsLimit <= 0 {
|
||||
// Don't set a limit if either no limit was specified, or "unlimited" was
|
||||
// explicitly set.
|
||||
|
@ -516,6 +540,7 @@ func (s *containerRouter) postContainersCreate(ctx context.Context, w http.Respo
|
|||
HostConfig: hostConfig,
|
||||
NetworkingConfig: networkingConfig,
|
||||
AdjustCPUShares: adjustCPUShares,
|
||||
Platform: platform,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
@ -3,6 +3,7 @@ package types // import "github.com/docker/docker/api/types"
|
|||
import (
|
||||
"github.com/docker/docker/api/types/container"
|
||||
"github.com/docker/docker/api/types/network"
|
||||
specs "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
)
|
||||
|
||||
// configs holds structs used for internal communication between the
|
||||
|
@ -15,6 +16,7 @@ type ContainerCreateConfig struct {
|
|||
Config *container.Config
|
||||
HostConfig *container.HostConfig
|
||||
NetworkingConfig *network.NetworkingConfig
|
||||
Platform *specs.Platform
|
||||
AdjustCPUShares bool
|
||||
}
|
||||
|
||||
|
|
|
@ -5,20 +5,23 @@ import (
|
|||
"encoding/json"
|
||||
"net/url"
|
||||
|
||||
"github.com/containerd/containerd/platforms"
|
||||
"github.com/docker/docker/api/types/container"
|
||||
"github.com/docker/docker/api/types/network"
|
||||
"github.com/docker/docker/api/types/versions"
|
||||
specs "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
)
|
||||
|
||||
type configWrapper struct {
|
||||
*container.Config
|
||||
HostConfig *container.HostConfig
|
||||
NetworkingConfig *network.NetworkingConfig
|
||||
Platform *specs.Platform
|
||||
}
|
||||
|
||||
// ContainerCreate creates a new container based in the given configuration.
|
||||
// It can be associated with a name, but it's not mandatory.
|
||||
func (cli *Client) ContainerCreate(ctx context.Context, config *container.Config, hostConfig *container.HostConfig, networkingConfig *network.NetworkingConfig, containerName string) (container.ContainerCreateCreatedBody, error) {
|
||||
func (cli *Client) ContainerCreate(ctx context.Context, config *container.Config, hostConfig *container.HostConfig, networkingConfig *network.NetworkingConfig, platform *specs.Platform, containerName string) (container.ContainerCreateCreatedBody, error) {
|
||||
var response container.ContainerCreateCreatedBody
|
||||
|
||||
if err := cli.NewVersionError("1.25", "stop timeout"); config != nil && config.StopTimeout != nil && err != nil {
|
||||
|
@ -30,7 +33,15 @@ func (cli *Client) ContainerCreate(ctx context.Context, config *container.Config
|
|||
hostConfig.AutoRemove = false
|
||||
}
|
||||
|
||||
if err := cli.NewVersionError("1.41", "specify container image platform"); platform != nil && err != nil {
|
||||
return response, err
|
||||
}
|
||||
|
||||
query := url.Values{}
|
||||
if platform != nil {
|
||||
query.Set("platform", platforms.Format(*platform))
|
||||
}
|
||||
|
||||
if containerName != "" {
|
||||
query.Set("name", containerName)
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ func TestContainerCreateError(t *testing.T) {
|
|||
client := &Client{
|
||||
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
|
||||
}
|
||||
_, err := client.ContainerCreate(context.Background(), nil, nil, nil, "nothing")
|
||||
_, err := client.ContainerCreate(context.Background(), nil, nil, nil, nil, "nothing")
|
||||
if !errdefs.IsSystem(err) {
|
||||
t.Fatalf("expected a Server Error while testing StatusInternalServerError, got %T", err)
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ func TestContainerCreateError(t *testing.T) {
|
|||
client = &Client{
|
||||
client: newMockClient(errorMock(http.StatusNotFound, "Server error")),
|
||||
}
|
||||
_, err = client.ContainerCreate(context.Background(), nil, nil, nil, "nothing")
|
||||
_, err = client.ContainerCreate(context.Background(), nil, nil, nil, nil, "nothing")
|
||||
if err == nil || !IsErrNotFound(err) {
|
||||
t.Fatalf("expected a Server Error while testing StatusNotFound, got %T", err)
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ func TestContainerCreateImageNotFound(t *testing.T) {
|
|||
client := &Client{
|
||||
client: newMockClient(errorMock(http.StatusNotFound, "No such image")),
|
||||
}
|
||||
_, err := client.ContainerCreate(context.Background(), &container.Config{Image: "unknown_image"}, nil, nil, "unknown")
|
||||
_, err := client.ContainerCreate(context.Background(), &container.Config{Image: "unknown_image"}, nil, nil, nil, "unknown")
|
||||
if err == nil || !IsErrNotFound(err) {
|
||||
t.Fatalf("expected an imageNotFound error, got %v, %T", err, err)
|
||||
}
|
||||
|
@ -67,7 +67,7 @@ func TestContainerCreateWithName(t *testing.T) {
|
|||
}),
|
||||
}
|
||||
|
||||
r, err := client.ContainerCreate(context.Background(), nil, nil, nil, "container_name")
|
||||
r, err := client.ContainerCreate(context.Background(), nil, nil, nil, nil, "container_name")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -106,14 +106,14 @@ func TestContainerCreateAutoRemove(t *testing.T) {
|
|||
client: newMockClient(autoRemoveValidator(false)),
|
||||
version: "1.24",
|
||||
}
|
||||
if _, err := client.ContainerCreate(context.Background(), nil, &container.HostConfig{AutoRemove: true}, nil, ""); err != nil {
|
||||
if _, err := client.ContainerCreate(context.Background(), nil, &container.HostConfig{AutoRemove: true}, nil, nil, ""); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
client = &Client{
|
||||
client: newMockClient(autoRemoveValidator(true)),
|
||||
version: "1.25",
|
||||
}
|
||||
if _, err := client.ContainerCreate(context.Background(), nil, &container.HostConfig{AutoRemove: true}, nil, ""); err != nil {
|
||||
if _, err := client.ContainerCreate(context.Background(), nil, &container.HostConfig{AutoRemove: true}, nil, nil, ""); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ import (
|
|||
"github.com/docker/docker/api/types/registry"
|
||||
"github.com/docker/docker/api/types/swarm"
|
||||
volumetypes "github.com/docker/docker/api/types/volume"
|
||||
specs "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
)
|
||||
|
||||
// CommonAPIClient is the common methods between stable and experimental versions of APIClient.
|
||||
|
@ -47,7 +48,7 @@ type CommonAPIClient interface {
|
|||
type ContainerAPIClient interface {
|
||||
ContainerAttach(ctx context.Context, container string, options types.ContainerAttachOptions) (types.HijackedResponse, error)
|
||||
ContainerCommit(ctx context.Context, container string, options types.ContainerCommitOptions) (types.IDResponse, error)
|
||||
ContainerCreate(ctx context.Context, config *containertypes.Config, hostConfig *containertypes.HostConfig, networkingConfig *networktypes.NetworkingConfig, containerName string) (containertypes.ContainerCreateCreatedBody, error)
|
||||
ContainerCreate(ctx context.Context, config *containertypes.Config, hostConfig *containertypes.HostConfig, networkingConfig *networktypes.NetworkingConfig, platform *specs.Platform, containerName string) (containertypes.ContainerCreateCreatedBody, error)
|
||||
ContainerDiff(ctx context.Context, container string) ([]containertypes.ContainerChangeResponseItem, error)
|
||||
ContainerExecAttach(ctx context.Context, execID string, config types.ExecStartCheck) (types.HijackedResponse, error)
|
||||
ContainerExecCreate(ctx context.Context, container string, config types.ExecConfig) (types.IDResponse, error)
|
||||
|
|
|
@ -60,7 +60,7 @@ func (daemon *Daemon) containerCreate(opts createOpts) (containertypes.Container
|
|||
|
||||
os := runtime.GOOS
|
||||
if opts.params.Config.Image != "" {
|
||||
img, err := daemon.imageService.GetImage(opts.params.Config.Image)
|
||||
img, err := daemon.imageService.GetImage(opts.params.Config.Image, opts.params.Platform)
|
||||
if err == nil {
|
||||
os = img.OS
|
||||
}
|
||||
|
@ -114,7 +114,7 @@ func (daemon *Daemon) create(opts createOpts) (retC *container.Container, retErr
|
|||
|
||||
os := runtime.GOOS
|
||||
if opts.params.Config.Image != "" {
|
||||
img, err = daemon.imageService.GetImage(opts.params.Config.Image)
|
||||
img, err = daemon.imageService.GetImage(opts.params.Config.Image, opts.params.Platform)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ func (i *ImageService) MakeImageCache(sourceRefs []string) builder.ImageCache {
|
|||
cache := cache.New(i.imageStore)
|
||||
|
||||
for _, ref := range sourceRefs {
|
||||
img, err := i.GetImage(ref)
|
||||
img, err := i.GetImage(ref, nil)
|
||||
if err != nil {
|
||||
logrus.Warnf("Could not look up %s for cache resolution, skipping: %+v", ref, err)
|
||||
continue
|
||||
|
|
|
@ -3,9 +3,12 @@ package images // import "github.com/docker/docker/daemon/images"
|
|||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/docker/distribution/reference"
|
||||
"github.com/docker/docker/errdefs"
|
||||
"github.com/docker/docker/image"
|
||||
specs "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
)
|
||||
|
||||
// ErrImageDoesNotExist is error returned when no image can be found for a reference.
|
||||
|
@ -25,7 +28,39 @@ func (e ErrImageDoesNotExist) Error() string {
|
|||
func (e ErrImageDoesNotExist) NotFound() {}
|
||||
|
||||
// GetImage returns an image corresponding to the image referred to by refOrID.
|
||||
func (i *ImageService) GetImage(refOrID string) (*image.Image, error) {
|
||||
func (i *ImageService) GetImage(refOrID string, platform *specs.Platform) (retImg *image.Image, retErr error) {
|
||||
defer func() {
|
||||
if retErr != nil || retImg == nil || platform == nil {
|
||||
return
|
||||
}
|
||||
|
||||
// This allows us to tell clients that we don't have the image they asked for
|
||||
// Where this gets hairy is the image store does not currently support multi-arch images, e.g.:
|
||||
// An image `foo` may have a multi-arch manifest, but the image store only fetches the image for a specific platform
|
||||
// The image store does not store the manifest list and image tags are assigned to architecture specific images.
|
||||
// So we can have a `foo` image that is amd64 but the user requested armv7. If the user looks at the list of images.
|
||||
// This may be confusing.
|
||||
// The alternative to this is to return a errdefs.Conflict error with a helpful message, but clients will not be
|
||||
// able to automatically tell what causes the conflict.
|
||||
if retImg.OS != platform.OS {
|
||||
retErr = errdefs.NotFound(errors.Errorf("image with reference %s was found but does not match the specified OS platform: wanted: %s, actual: %s", refOrID, platform.OS, retImg.OS))
|
||||
retImg = nil
|
||||
return
|
||||
}
|
||||
if retImg.Architecture != platform.Architecture {
|
||||
retErr = errdefs.NotFound(errors.Errorf("image with reference %s was found but does not match the specified platform cpu architecture: wanted: %s, actual: %s", refOrID, platform.Architecture, retImg.Architecture))
|
||||
retImg = nil
|
||||
return
|
||||
}
|
||||
|
||||
// Only validate variant if retImg has a variant set.
|
||||
// The image variant may not be set since it's a newer field.
|
||||
if platform.Variant != "" && retImg.Variant != "" && retImg.Variant != platform.Variant {
|
||||
retErr = errdefs.NotFound(errors.Errorf("image with reference %s was found but does not match the specified platform cpu architecture variant: wanted: %s, actual: %s", refOrID, platform.Variant, retImg.Variant))
|
||||
retImg = nil
|
||||
return
|
||||
}
|
||||
}()
|
||||
ref, err := reference.ParseAnyReference(refOrID)
|
||||
if err != nil {
|
||||
return nil, errdefs.InvalidParameter(err)
|
||||
|
|
|
@ -161,7 +161,7 @@ func (i *ImageService) pullForBuilder(ctx context.Context, name string, authConf
|
|||
if err := i.pullImageWithReference(ctx, ref, platform, nil, pullRegistryAuth, output); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return i.GetImage(name)
|
||||
return i.GetImage(name, platform)
|
||||
}
|
||||
|
||||
// GetImageAndReleasableLayer returns an image and releaseable layer for a reference or ID.
|
||||
|
@ -184,7 +184,7 @@ func (i *ImageService) GetImageAndReleasableLayer(ctx context.Context, refOrID s
|
|||
}
|
||||
|
||||
if opts.PullOption != backend.PullOptionForcePull {
|
||||
image, err := i.GetImage(refOrID)
|
||||
image, err := i.GetImage(refOrID, opts.Platform)
|
||||
if err != nil && opts.PullOption == backend.PullOptionNoPull {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
|
|
@ -64,7 +64,7 @@ func (i *ImageService) ImageDelete(imageRef string, force, prune bool) ([]types.
|
|||
start := time.Now()
|
||||
records := []types.ImageDeleteResponseItem{}
|
||||
|
||||
img, err := i.GetImage(imageRef)
|
||||
img, err := i.GetImage(imageRef, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ func (i *ImageService) LogImageEvent(imageID, refName, action string) {
|
|||
|
||||
// LogImageEventWithAttributes generates an event related to an image with specific given attributes.
|
||||
func (i *ImageService) LogImageEventWithAttributes(imageID, refName, action string, attributes map[string]string) {
|
||||
img, err := i.GetImage(imageID)
|
||||
img, err := i.GetImage(imageID, nil)
|
||||
if err == nil && img.Config != nil {
|
||||
// image has not been removed yet.
|
||||
// it could be missing if the event is `delete`.
|
||||
|
|
|
@ -14,7 +14,7 @@ import (
|
|||
// name by walking the image lineage.
|
||||
func (i *ImageService) ImageHistory(name string) ([]*image.HistoryResponseItem, error) {
|
||||
start := time.Now()
|
||||
img, err := i.GetImage(name)
|
||||
img, err := i.GetImage(name, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -77,7 +77,7 @@ func (i *ImageService) ImageHistory(name string) ([]*image.HistoryResponseItem,
|
|||
if id == "" {
|
||||
break
|
||||
}
|
||||
histImg, err = i.GetImage(id.String())
|
||||
histImg, err = i.GetImage(id.String(), nil)
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ import (
|
|||
// LookupImage looks up an image by name and returns it as an ImageInspect
|
||||
// structure.
|
||||
func (i *ImageService) LookupImage(name string) (*types.ImageInspect, error) {
|
||||
img, err := i.GetImage(name)
|
||||
img, err := i.GetImage(name, nil)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "no such image: %s", name)
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ import (
|
|||
// TagImage creates the tag specified by newTag, pointing to the image named
|
||||
// imageName (alternatively, imageName can also be an image ID).
|
||||
func (i *ImageService) TagImage(imageName, repository, tag string) (string, error) {
|
||||
img, err := i.GetImage(imageName)
|
||||
img, err := i.GetImage(imageName, nil)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
|
|
@ -69,7 +69,7 @@ func (i *ImageService) Images(imageFilters filters.Args, all bool, withExtraAttr
|
|||
|
||||
var beforeFilter, sinceFilter *image.Image
|
||||
err = imageFilters.WalkValues("before", func(value string) error {
|
||||
beforeFilter, err = i.GetImage(value)
|
||||
beforeFilter, err = i.GetImage(value, nil)
|
||||
return err
|
||||
})
|
||||
if err != nil {
|
||||
|
@ -77,7 +77,7 @@ func (i *ImageService) Images(imageFilters filters.Args, all bool, withExtraAttr
|
|||
}
|
||||
|
||||
err = imageFilters.WalkValues("since", func(value string) error {
|
||||
sinceFilter, err = i.GetImage(value)
|
||||
sinceFilter, err = i.GetImage(value, nil)
|
||||
return err
|
||||
})
|
||||
if err != nil {
|
||||
|
|
|
@ -317,7 +317,7 @@ func (daemon *Daemon) foldFilter(view container.View, config *types.ContainerLis
|
|||
if psFilters.Contains("ancestor") {
|
||||
ancestorFilter = true
|
||||
psFilters.WalkValues("ancestor", func(ancestor string) error {
|
||||
img, err := daemon.imageService.GetImage(ancestor)
|
||||
img, err := daemon.imageService.GetImage(ancestor, nil)
|
||||
if err != nil {
|
||||
logrus.Warnf("Error while looking up for image %v", ancestor)
|
||||
return nil
|
||||
|
@ -581,7 +581,7 @@ func (daemon *Daemon) refreshImage(s *container.Snapshot, ctx *listContext) (*ty
|
|||
c := s.Container
|
||||
image := s.Image // keep the original ref if still valid (hasn't changed)
|
||||
if image != s.ImageID {
|
||||
img, err := daemon.imageService.GetImage(image)
|
||||
img, err := daemon.imageService.GetImage(image, nil)
|
||||
if _, isDNE := err.(images.ErrImageDoesNotExist); err != nil && !isDNE {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ const (
|
|||
|
||||
func (daemon *Daemon) createSpec(c *container.Container) (*specs.Spec, error) {
|
||||
|
||||
img, err := daemon.imageService.GetImage(string(c.ImageID))
|
||||
img, err := daemon.imageService.GetImage(string(c.ImageID), nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -523,7 +523,7 @@ func (s *DockerSuite) TestContainerAPIBadPort(c *testing.T) {
|
|||
assert.NilError(c, err)
|
||||
defer cli.Close()
|
||||
|
||||
_, err = cli.ContainerCreate(context.Background(), &config, &hostConfig, &networktypes.NetworkingConfig{}, "")
|
||||
_, err = cli.ContainerCreate(context.Background(), &config, &hostConfig, &networktypes.NetworkingConfig{}, nil, "")
|
||||
assert.ErrorContains(c, err, `invalid port specification: "aa80"`)
|
||||
}
|
||||
|
||||
|
@ -537,7 +537,7 @@ func (s *DockerSuite) TestContainerAPICreate(c *testing.T) {
|
|||
assert.NilError(c, err)
|
||||
defer cli.Close()
|
||||
|
||||
container, err := cli.ContainerCreate(context.Background(), &config, &containertypes.HostConfig{}, &networktypes.NetworkingConfig{}, "")
|
||||
container, err := cli.ContainerCreate(context.Background(), &config, &containertypes.HostConfig{}, &networktypes.NetworkingConfig{}, nil, "")
|
||||
assert.NilError(c, err)
|
||||
|
||||
out, _ := dockerCmd(c, "start", "-a", container.ID)
|
||||
|
@ -550,7 +550,7 @@ func (s *DockerSuite) TestContainerAPICreateEmptyConfig(c *testing.T) {
|
|||
assert.NilError(c, err)
|
||||
defer cli.Close()
|
||||
|
||||
_, err = cli.ContainerCreate(context.Background(), &containertypes.Config{}, &containertypes.HostConfig{}, &networktypes.NetworkingConfig{}, "")
|
||||
_, err = cli.ContainerCreate(context.Background(), &containertypes.Config{}, &containertypes.HostConfig{}, &networktypes.NetworkingConfig{}, nil, "")
|
||||
|
||||
expected := "No command specified"
|
||||
assert.ErrorContains(c, err, expected)
|
||||
|
@ -574,7 +574,7 @@ func (s *DockerSuite) TestContainerAPICreateMultipleNetworksConfig(c *testing.T)
|
|||
assert.NilError(c, err)
|
||||
defer cli.Close()
|
||||
|
||||
_, err = cli.ContainerCreate(context.Background(), &config, &containertypes.HostConfig{}, &networkingConfig, "")
|
||||
_, err = cli.ContainerCreate(context.Background(), &config, &containertypes.HostConfig{}, &networkingConfig, nil, "")
|
||||
msg := err.Error()
|
||||
// network name order in error message is not deterministic
|
||||
assert.Assert(c, strings.Contains(msg, "Container cannot be connected to network endpoints"))
|
||||
|
@ -609,7 +609,7 @@ func UtilCreateNetworkMode(c *testing.T, networkMode containertypes.NetworkMode)
|
|||
assert.NilError(c, err)
|
||||
defer cli.Close()
|
||||
|
||||
container, err := cli.ContainerCreate(context.Background(), &config, &hostConfig, &networktypes.NetworkingConfig{}, "")
|
||||
container, err := cli.ContainerCreate(context.Background(), &config, &hostConfig, &networktypes.NetworkingConfig{}, nil, "")
|
||||
assert.NilError(c, err)
|
||||
|
||||
containerJSON, err := cli.ContainerInspect(context.Background(), container.ID)
|
||||
|
@ -636,7 +636,7 @@ func (s *DockerSuite) TestContainerAPICreateWithCpuSharesCpuset(c *testing.T) {
|
|||
assert.NilError(c, err)
|
||||
defer cli.Close()
|
||||
|
||||
container, err := cli.ContainerCreate(context.Background(), &config, &hostConfig, &networktypes.NetworkingConfig{}, "")
|
||||
container, err := cli.ContainerCreate(context.Background(), &config, &hostConfig, &networktypes.NetworkingConfig{}, nil, "")
|
||||
assert.NilError(c, err)
|
||||
|
||||
containerJSON, err := cli.ContainerInspect(context.Background(), container.ID)
|
||||
|
@ -948,7 +948,7 @@ func (s *DockerSuite) TestContainerAPIStart(c *testing.T) {
|
|||
assert.NilError(c, err)
|
||||
defer cli.Close()
|
||||
|
||||
_, err = cli.ContainerCreate(context.Background(), &config, &containertypes.HostConfig{}, &networktypes.NetworkingConfig{}, name)
|
||||
_, err = cli.ContainerCreate(context.Background(), &config, &containertypes.HostConfig{}, &networktypes.NetworkingConfig{}, nil, name)
|
||||
assert.NilError(c, err)
|
||||
|
||||
err = cli.ContainerStart(context.Background(), name, types.ContainerStartOptions{})
|
||||
|
@ -1272,7 +1272,7 @@ func (s *DockerSuite) TestPostContainerAPICreateWithStringOrSliceEntrypoint(c *t
|
|||
assert.NilError(c, err)
|
||||
defer cli.Close()
|
||||
|
||||
_, err = cli.ContainerCreate(context.Background(), &config, &containertypes.HostConfig{}, &networktypes.NetworkingConfig{}, "echotest")
|
||||
_, err = cli.ContainerCreate(context.Background(), &config, &containertypes.HostConfig{}, &networktypes.NetworkingConfig{}, nil, "echotest")
|
||||
assert.NilError(c, err)
|
||||
out, _ := dockerCmd(c, "start", "-a", "echotest")
|
||||
assert.Equal(c, strings.TrimSpace(out), "hello world")
|
||||
|
@ -1299,7 +1299,7 @@ func (s *DockerSuite) TestPostContainersCreateWithStringOrSliceCmd(c *testing.T)
|
|||
assert.NilError(c, err)
|
||||
defer cli.Close()
|
||||
|
||||
_, err = cli.ContainerCreate(context.Background(), &config, &containertypes.HostConfig{}, &networktypes.NetworkingConfig{}, "echotest")
|
||||
_, err = cli.ContainerCreate(context.Background(), &config, &containertypes.HostConfig{}, &networktypes.NetworkingConfig{}, nil, "echotest")
|
||||
assert.NilError(c, err)
|
||||
out, _ := dockerCmd(c, "start", "-a", "echotest")
|
||||
assert.Equal(c, strings.TrimSpace(out), "hello world")
|
||||
|
@ -1342,7 +1342,7 @@ func (s *DockerSuite) TestPostContainersCreateWithStringOrSliceCapAddDrop(c *tes
|
|||
assert.NilError(c, err)
|
||||
defer cli.Close()
|
||||
|
||||
_, err = cli.ContainerCreate(context.Background(), &config2, &hostConfig, &networktypes.NetworkingConfig{}, "capaddtest1")
|
||||
_, err = cli.ContainerCreate(context.Background(), &config2, &hostConfig, &networktypes.NetworkingConfig{}, nil, "capaddtest1")
|
||||
assert.NilError(c, err)
|
||||
}
|
||||
|
||||
|
@ -1356,7 +1356,7 @@ func (s *DockerSuite) TestContainerAPICreateNoHostConfig118(c *testing.T) {
|
|||
cli, err := client.NewClientWithOpts(client.FromEnv, client.WithVersion("v1.18"))
|
||||
assert.NilError(c, err)
|
||||
|
||||
_, err = cli.ContainerCreate(context.Background(), &config, &containertypes.HostConfig{}, &networktypes.NetworkingConfig{}, "")
|
||||
_, err = cli.ContainerCreate(context.Background(), &config, &containertypes.HostConfig{}, &networktypes.NetworkingConfig{}, nil, "")
|
||||
assert.NilError(c, err)
|
||||
}
|
||||
|
||||
|
@ -1407,7 +1407,7 @@ func (s *DockerSuite) TestPostContainersCreateWithWrongCpusetValues(c *testing.T
|
|||
}
|
||||
name := "wrong-cpuset-cpus"
|
||||
|
||||
_, err = cli.ContainerCreate(context.Background(), &config, &hostConfig1, &networktypes.NetworkingConfig{}, name)
|
||||
_, err = cli.ContainerCreate(context.Background(), &config, &hostConfig1, &networktypes.NetworkingConfig{}, nil, name)
|
||||
expected := "Invalid value 1-42,, for cpuset cpus"
|
||||
assert.ErrorContains(c, err, expected)
|
||||
|
||||
|
@ -1417,7 +1417,7 @@ func (s *DockerSuite) TestPostContainersCreateWithWrongCpusetValues(c *testing.T
|
|||
},
|
||||
}
|
||||
name = "wrong-cpuset-mems"
|
||||
_, err = cli.ContainerCreate(context.Background(), &config, &hostConfig2, &networktypes.NetworkingConfig{}, name)
|
||||
_, err = cli.ContainerCreate(context.Background(), &config, &hostConfig2, &networktypes.NetworkingConfig{}, nil, name)
|
||||
expected = "Invalid value 42-3,1-- for cpuset mems"
|
||||
assert.ErrorContains(c, err, expected)
|
||||
}
|
||||
|
@ -1436,7 +1436,7 @@ func (s *DockerSuite) TestPostContainersCreateShmSizeNegative(c *testing.T) {
|
|||
assert.NilError(c, err)
|
||||
defer cli.Close()
|
||||
|
||||
_, err = cli.ContainerCreate(context.Background(), &config, &hostConfig, &networktypes.NetworkingConfig{}, "")
|
||||
_, err = cli.ContainerCreate(context.Background(), &config, &hostConfig, &networktypes.NetworkingConfig{}, nil, "")
|
||||
assert.ErrorContains(c, err, "SHM size can not be less than 0")
|
||||
}
|
||||
|
||||
|
@ -1453,7 +1453,7 @@ func (s *DockerSuite) TestPostContainersCreateShmSizeHostConfigOmitted(c *testin
|
|||
assert.NilError(c, err)
|
||||
defer cli.Close()
|
||||
|
||||
container, err := cli.ContainerCreate(context.Background(), &config, &containertypes.HostConfig{}, &networktypes.NetworkingConfig{}, "")
|
||||
container, err := cli.ContainerCreate(context.Background(), &config, &containertypes.HostConfig{}, &networktypes.NetworkingConfig{}, nil, "")
|
||||
assert.NilError(c, err)
|
||||
|
||||
containerJSON, err := cli.ContainerInspect(context.Background(), container.ID)
|
||||
|
@ -1480,7 +1480,7 @@ func (s *DockerSuite) TestPostContainersCreateShmSizeOmitted(c *testing.T) {
|
|||
assert.NilError(c, err)
|
||||
defer cli.Close()
|
||||
|
||||
container, err := cli.ContainerCreate(context.Background(), &config, &containertypes.HostConfig{}, &networktypes.NetworkingConfig{}, "")
|
||||
container, err := cli.ContainerCreate(context.Background(), &config, &containertypes.HostConfig{}, &networktypes.NetworkingConfig{}, nil, "")
|
||||
assert.NilError(c, err)
|
||||
|
||||
containerJSON, err := cli.ContainerInspect(context.Background(), container.ID)
|
||||
|
@ -1511,7 +1511,7 @@ func (s *DockerSuite) TestPostContainersCreateWithShmSize(c *testing.T) {
|
|||
assert.NilError(c, err)
|
||||
defer cli.Close()
|
||||
|
||||
container, err := cli.ContainerCreate(context.Background(), &config, &hostConfig, &networktypes.NetworkingConfig{}, "")
|
||||
container, err := cli.ContainerCreate(context.Background(), &config, &hostConfig, &networktypes.NetworkingConfig{}, nil, "")
|
||||
assert.NilError(c, err)
|
||||
|
||||
containerJSON, err := cli.ContainerInspect(context.Background(), container.ID)
|
||||
|
@ -1537,7 +1537,7 @@ func (s *DockerSuite) TestPostContainersCreateMemorySwappinessHostConfigOmitted(
|
|||
assert.NilError(c, err)
|
||||
defer cli.Close()
|
||||
|
||||
container, err := cli.ContainerCreate(context.Background(), &config, &containertypes.HostConfig{}, &networktypes.NetworkingConfig{}, "")
|
||||
container, err := cli.ContainerCreate(context.Background(), &config, &containertypes.HostConfig{}, &networktypes.NetworkingConfig{}, nil, "")
|
||||
assert.NilError(c, err)
|
||||
|
||||
containerJSON, err := cli.ContainerInspect(context.Background(), container.ID)
|
||||
|
@ -1568,7 +1568,7 @@ func (s *DockerSuite) TestPostContainersCreateWithOomScoreAdjInvalidRange(c *tes
|
|||
defer cli.Close()
|
||||
|
||||
name := "oomscoreadj-over"
|
||||
_, err = cli.ContainerCreate(context.Background(), &config, &hostConfig, &networktypes.NetworkingConfig{}, name)
|
||||
_, err = cli.ContainerCreate(context.Background(), &config, &hostConfig, &networktypes.NetworkingConfig{}, nil, name)
|
||||
|
||||
expected := "Invalid value 1001, range for oom score adj is [-1000, 1000]"
|
||||
assert.ErrorContains(c, err, expected)
|
||||
|
@ -1578,7 +1578,7 @@ func (s *DockerSuite) TestPostContainersCreateWithOomScoreAdjInvalidRange(c *tes
|
|||
}
|
||||
|
||||
name = "oomscoreadj-low"
|
||||
_, err = cli.ContainerCreate(context.Background(), &config, &hostConfig, &networktypes.NetworkingConfig{}, name)
|
||||
_, err = cli.ContainerCreate(context.Background(), &config, &hostConfig, &networktypes.NetworkingConfig{}, nil, name)
|
||||
|
||||
expected = "Invalid value -1001, range for oom score adj is [-1000, 1000]"
|
||||
assert.ErrorContains(c, err, expected)
|
||||
|
@ -1610,7 +1610,7 @@ func (s *DockerSuite) TestContainerAPIStatsWithNetworkDisabled(c *testing.T) {
|
|||
assert.NilError(c, err)
|
||||
defer cli.Close()
|
||||
|
||||
_, err = cli.ContainerCreate(context.Background(), &config, &containertypes.HostConfig{}, &networktypes.NetworkingConfig{}, name)
|
||||
_, err = cli.ContainerCreate(context.Background(), &config, &containertypes.HostConfig{}, &networktypes.NetworkingConfig{}, nil, name)
|
||||
assert.NilError(c, err)
|
||||
|
||||
err = cli.ContainerStart(context.Background(), name, types.ContainerStartOptions{})
|
||||
|
@ -1926,7 +1926,7 @@ func (s *DockerSuite) TestContainersAPICreateMountsValidation(c *testing.T) {
|
|||
for i, x := range cases {
|
||||
x := x
|
||||
c.Run(fmt.Sprintf("case %d", i), func(c *testing.T) {
|
||||
_, err = apiClient.ContainerCreate(context.Background(), &x.config, &x.hostConfig, &networktypes.NetworkingConfig{}, "")
|
||||
_, err = apiClient.ContainerCreate(context.Background(), &x.config, &x.hostConfig, &networktypes.NetworkingConfig{}, nil, "")
|
||||
if len(x.msg) > 0 {
|
||||
assert.ErrorContains(c, err, x.msg, "%v", cases[i].config)
|
||||
} else {
|
||||
|
@ -1959,7 +1959,7 @@ func (s *DockerSuite) TestContainerAPICreateMountsBindRead(c *testing.T) {
|
|||
assert.NilError(c, err)
|
||||
defer cli.Close()
|
||||
|
||||
_, err = cli.ContainerCreate(context.Background(), &config, &hostConfig, &networktypes.NetworkingConfig{}, "test")
|
||||
_, err = cli.ContainerCreate(context.Background(), &config, &hostConfig, &networktypes.NetworkingConfig{}, nil, "test")
|
||||
assert.NilError(c, err)
|
||||
|
||||
out, _ := dockerCmd(c, "start", "-a", "test")
|
||||
|
@ -2106,6 +2106,7 @@ func (s *DockerSuite) TestContainersAPICreateMountsCreate(c *testing.T) {
|
|||
&containertypes.Config{Image: testImg},
|
||||
&containertypes.HostConfig{Mounts: []mounttypes.Mount{x.spec}},
|
||||
&networktypes.NetworkingConfig{},
|
||||
nil,
|
||||
"")
|
||||
assert.NilError(c, err)
|
||||
|
||||
|
@ -2213,7 +2214,7 @@ func (s *DockerSuite) TestContainersAPICreateMountsTmpfs(c *testing.T) {
|
|||
Mounts: []mounttypes.Mount{x.cfg},
|
||||
}
|
||||
|
||||
_, err = cli.ContainerCreate(context.Background(), &config, &hostConfig, &networktypes.NetworkingConfig{}, cName)
|
||||
_, err = cli.ContainerCreate(context.Background(), &config, &hostConfig, &networktypes.NetworkingConfig{}, nil, cName)
|
||||
assert.NilError(c, err)
|
||||
out, _ := dockerCmd(c, "start", "-a", cName)
|
||||
for _, option := range x.expectedOptions {
|
||||
|
|
|
@ -65,7 +65,7 @@ func (s *DockerSuite) TestContainersAPICreateMountsBindNamedPipe(c *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
nil, name)
|
||||
nil, nil, name)
|
||||
assert.NilError(c, err)
|
||||
|
||||
err = client.ContainerStart(ctx, name, types.ContainerStartOptions{})
|
||||
|
|
|
@ -578,7 +578,7 @@ func (s *DockerSuite) TestDuplicateMountpointsForVolumesFromAndMounts(c *testing
|
|||
},
|
||||
},
|
||||
}
|
||||
_, err = cli.ContainerCreate(context.Background(), &config, &hostConfig, &network.NetworkingConfig{}, "app")
|
||||
_, err = cli.ContainerCreate(context.Background(), &config, &hostConfig, &network.NetworkingConfig{}, nil, "app")
|
||||
|
||||
assert.NilError(c, err)
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ import (
|
|||
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/container"
|
||||
containertypes "github.com/docker/docker/api/types/container"
|
||||
"github.com/docker/docker/api/types/network"
|
||||
"github.com/docker/docker/api/types/versions"
|
||||
"github.com/docker/docker/client"
|
||||
|
@ -17,6 +18,7 @@ import (
|
|||
ctr "github.com/docker/docker/integration/internal/container"
|
||||
"github.com/docker/docker/oci"
|
||||
"github.com/docker/docker/testutil/request"
|
||||
specs "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
"gotest.tools/v3/assert"
|
||||
is "gotest.tools/v3/assert/cmp"
|
||||
"gotest.tools/v3/poll"
|
||||
|
@ -57,6 +59,7 @@ func TestCreateFailsWhenIdentifierDoesNotExist(t *testing.T) {
|
|||
&container.Config{Image: tc.image},
|
||||
&container.HostConfig{},
|
||||
&network.NetworkingConfig{},
|
||||
nil,
|
||||
"",
|
||||
)
|
||||
assert.Check(t, is.ErrorContains(err, tc.expectedError))
|
||||
|
@ -81,6 +84,7 @@ func TestCreateLinkToNonExistingContainer(t *testing.T) {
|
|||
Links: []string{"no-such-container"},
|
||||
},
|
||||
&network.NetworkingConfig{},
|
||||
nil,
|
||||
"",
|
||||
)
|
||||
assert.Check(t, is.ErrorContains(err, "could not get container for no-such-container"))
|
||||
|
@ -120,6 +124,7 @@ func TestCreateWithInvalidEnv(t *testing.T) {
|
|||
},
|
||||
&container.HostConfig{},
|
||||
&network.NetworkingConfig{},
|
||||
nil,
|
||||
"",
|
||||
)
|
||||
assert.Check(t, is.ErrorContains(err, tc.expectedError))
|
||||
|
@ -166,6 +171,7 @@ func TestCreateTmpfsMountsTarget(t *testing.T) {
|
|||
Tmpfs: map[string]string{tc.target: ""},
|
||||
},
|
||||
&network.NetworkingConfig{},
|
||||
nil,
|
||||
"",
|
||||
)
|
||||
assert.Check(t, is.ErrorContains(err, tc.expectedError))
|
||||
|
@ -235,6 +241,7 @@ func TestCreateWithCustomMaskedPaths(t *testing.T) {
|
|||
&config,
|
||||
&hc,
|
||||
&network.NetworkingConfig{},
|
||||
nil,
|
||||
name,
|
||||
)
|
||||
assert.NilError(t, err)
|
||||
|
@ -361,6 +368,7 @@ func TestCreateWithCapabilities(t *testing.T) {
|
|||
&container.Config{Image: "busybox"},
|
||||
&tc.hostConfig,
|
||||
&network.NetworkingConfig{},
|
||||
nil,
|
||||
"",
|
||||
)
|
||||
if tc.expectedError == "" {
|
||||
|
@ -439,6 +447,7 @@ func TestCreateWithCustomReadonlyPaths(t *testing.T) {
|
|||
&config,
|
||||
&hc,
|
||||
&network.NetworkingConfig{},
|
||||
nil,
|
||||
name,
|
||||
)
|
||||
assert.NilError(t, err)
|
||||
|
@ -522,7 +531,7 @@ func TestCreateWithInvalidHealthcheckParams(t *testing.T) {
|
|||
cfg.Healthcheck.StartPeriod = tc.startPeriod
|
||||
}
|
||||
|
||||
resp, err := client.ContainerCreate(ctx, &cfg, &container.HostConfig{}, nil, "")
|
||||
resp, err := client.ContainerCreate(ctx, &cfg, &container.HostConfig{}, nil, nil, "")
|
||||
assert.Check(t, is.Equal(len(resp.Warnings), 0))
|
||||
|
||||
if versions.LessThan(testEnv.DaemonAPIVersion(), "1.32") {
|
||||
|
@ -581,3 +590,34 @@ func TestCreateTmpfsOverrideAnonymousVolume(t *testing.T) {
|
|||
assert.NilError(t, err)
|
||||
}
|
||||
}
|
||||
|
||||
// Test that if the referenced image platform does not match the requested platform on container create that we get an
|
||||
// error.
|
||||
func TestCreateDifferentPlatform(t *testing.T) {
|
||||
defer setupTest(t)()
|
||||
c := testEnv.APIClient()
|
||||
ctx := context.Background()
|
||||
|
||||
img, _, err := c.ImageInspectWithRaw(ctx, "busybox:latest")
|
||||
assert.NilError(t, err)
|
||||
assert.Assert(t, img.Architecture != "")
|
||||
|
||||
t.Run("different os", func(t *testing.T) {
|
||||
p := specs.Platform{
|
||||
OS: img.Os + "DifferentOS",
|
||||
Architecture: img.Architecture,
|
||||
Variant: img.Variant,
|
||||
}
|
||||
_, err := c.ContainerCreate(ctx, &containertypes.Config{Image: "busybox:latest"}, &containertypes.HostConfig{}, nil, &p, "")
|
||||
assert.Assert(t, client.IsErrNotFound(err), err)
|
||||
})
|
||||
t.Run("different cpu arch", func(t *testing.T) {
|
||||
p := specs.Platform{
|
||||
OS: img.Os,
|
||||
Architecture: img.Architecture + "DifferentArch",
|
||||
Variant: img.Variant,
|
||||
}
|
||||
_, err := c.ContainerCreate(ctx, &containertypes.Config{Image: "busybox:latest"}, &containertypes.HostConfig{}, nil, &p, "")
|
||||
assert.Assert(t, client.IsErrNotFound(err), err)
|
||||
})
|
||||
}
|
||||
|
|
|
@ -66,7 +66,7 @@ func testIpcNonePrivateShareable(t *testing.T, mode string, mustBeMounted bool,
|
|||
client := testEnv.APIClient()
|
||||
ctx := context.Background()
|
||||
|
||||
resp, err := client.ContainerCreate(ctx, &cfg, &hostCfg, nil, "")
|
||||
resp, err := client.ContainerCreate(ctx, &cfg, &hostCfg, nil, nil, "")
|
||||
assert.NilError(t, err)
|
||||
assert.Check(t, is.Equal(len(resp.Warnings), 0))
|
||||
|
||||
|
@ -138,7 +138,7 @@ func testIpcContainer(t *testing.T, donorMode string, mustWork bool) {
|
|||
client := testEnv.APIClient()
|
||||
|
||||
// create and start the "donor" container
|
||||
resp, err := client.ContainerCreate(ctx, &cfg, &hostCfg, nil, "")
|
||||
resp, err := client.ContainerCreate(ctx, &cfg, &hostCfg, nil, nil, "")
|
||||
assert.NilError(t, err)
|
||||
assert.Check(t, is.Equal(len(resp.Warnings), 0))
|
||||
name1 := resp.ID
|
||||
|
@ -148,7 +148,7 @@ func testIpcContainer(t *testing.T, donorMode string, mustWork bool) {
|
|||
|
||||
// create and start the second container
|
||||
hostCfg.IpcMode = containertypes.IpcMode("container:" + name1)
|
||||
resp, err = client.ContainerCreate(ctx, &cfg, &hostCfg, nil, "")
|
||||
resp, err = client.ContainerCreate(ctx, &cfg, &hostCfg, nil, nil, "")
|
||||
assert.NilError(t, err)
|
||||
assert.Check(t, is.Equal(len(resp.Warnings), 0))
|
||||
name2 := resp.ID
|
||||
|
@ -204,7 +204,7 @@ func TestAPIIpcModeHost(t *testing.T) {
|
|||
ctx := context.Background()
|
||||
|
||||
client := testEnv.APIClient()
|
||||
resp, err := client.ContainerCreate(ctx, &cfg, &hostCfg, nil, "")
|
||||
resp, err := client.ContainerCreate(ctx, &cfg, &hostCfg, nil, nil, "")
|
||||
assert.NilError(t, err)
|
||||
assert.Check(t, is.Equal(len(resp.Warnings), 0))
|
||||
name := resp.ID
|
||||
|
@ -241,7 +241,7 @@ func testDaemonIpcPrivateShareable(t *testing.T, mustBeShared bool, arg ...strin
|
|||
}
|
||||
ctx := context.Background()
|
||||
|
||||
resp, err := c.ContainerCreate(ctx, &cfg, &containertypes.HostConfig{}, nil, "")
|
||||
resp, err := c.ContainerCreate(ctx, &cfg, &containertypes.HostConfig{}, nil, nil, "")
|
||||
assert.NilError(t, err)
|
||||
assert.Check(t, is.Equal(len(resp.Warnings), 0))
|
||||
|
||||
|
|
|
@ -63,7 +63,7 @@ func TestContainerNetworkMountsNoChown(t *testing.T) {
|
|||
assert.NilError(t, err)
|
||||
defer cli.Close()
|
||||
|
||||
ctrCreate, err := cli.ContainerCreate(ctx, &config, &hostConfig, &network.NetworkingConfig{}, "")
|
||||
ctrCreate, err := cli.ContainerCreate(ctx, &config, &hostConfig, &network.NetworkingConfig{}, nil, "")
|
||||
assert.NilError(t, err)
|
||||
// container will exit immediately because of no tty, but we only need the start sequence to test the condition
|
||||
err = cli.ContainerStart(ctx, ctrCreate.ID, types.ContainerStartOptions{})
|
||||
|
@ -174,7 +174,7 @@ func TestMountDaemonRoot(t *testing.T) {
|
|||
c, err := client.ContainerCreate(ctx, &containertypes.Config{
|
||||
Image: "busybox",
|
||||
Cmd: []string{"true"},
|
||||
}, hc, nil, "")
|
||||
}, hc, nil, nil, "")
|
||||
|
||||
if err != nil {
|
||||
if test.expected != "" {
|
||||
|
|
|
@ -77,7 +77,7 @@ func TestDaemonRestartKillContainers(t *testing.T) {
|
|||
defer d.Stop(t)
|
||||
ctx := context.Background()
|
||||
|
||||
resp, err := client.ContainerCreate(ctx, c.config, c.hostConfig, nil, "")
|
||||
resp, err := client.ContainerCreate(ctx, c.config, c.hostConfig, nil, nil, "")
|
||||
assert.NilError(t, err)
|
||||
defer client.ContainerRemove(ctx, resp.ID, types.ContainerRemoveOptions{Force: true})
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ import (
|
|||
"github.com/docker/docker/api/types/container"
|
||||
"github.com/docker/docker/api/types/network"
|
||||
"github.com/docker/docker/client"
|
||||
specs "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
"gotest.tools/v3/assert"
|
||||
)
|
||||
|
||||
|
@ -19,6 +20,7 @@ type TestContainerConfig struct {
|
|||
Config *container.Config
|
||||
HostConfig *container.HostConfig
|
||||
NetworkingConfig *network.NetworkingConfig
|
||||
Platform *specs.Platform
|
||||
}
|
||||
|
||||
// create creates a container with the specified options
|
||||
|
@ -41,7 +43,7 @@ func create(ctx context.Context, t *testing.T, client client.APIClient, ops ...f
|
|||
op(config)
|
||||
}
|
||||
|
||||
return client.ContainerCreate(ctx, config.Config, config.HostConfig, config.NetworkingConfig, config.Name)
|
||||
return client.ContainerCreate(ctx, config.Config, config.HostConfig, config.NetworkingConfig, config.Platform, config.Name)
|
||||
}
|
||||
|
||||
// Create creates a container with the specified options, asserting that there was no error
|
||||
|
|
|
@ -9,6 +9,7 @@ import (
|
|||
networktypes "github.com/docker/docker/api/types/network"
|
||||
"github.com/docker/docker/api/types/strslice"
|
||||
"github.com/docker/go-connections/nat"
|
||||
specs "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
)
|
||||
|
||||
// WithName sets the name of the container
|
||||
|
@ -205,3 +206,10 @@ func WithExtraHost(extraHost string) func(*TestContainerConfig) {
|
|||
c.HostConfig.ExtraHosts = append(c.HostConfig.ExtraHosts, extraHost)
|
||||
}
|
||||
}
|
||||
|
||||
// WithPlatform specifies the desired platform the image should have.
|
||||
func WithPlatform(p *specs.Platform) func(*TestContainerConfig) {
|
||||
return func(c *TestContainerConfig) {
|
||||
c.Platform = p
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,6 +54,7 @@ func TestReadPluginNoRead(t *testing.T) {
|
|||
cfg,
|
||||
&container.HostConfig{LogConfig: container.LogConfig{Type: "test"}},
|
||||
nil,
|
||||
nil,
|
||||
"",
|
||||
)
|
||||
assert.Assert(t, err)
|
||||
|
|
|
@ -155,7 +155,7 @@ COPY . /static`); err != nil {
|
|||
// Start the container
|
||||
b, err := c.ContainerCreate(context.Background(), &containertypes.Config{
|
||||
Image: image,
|
||||
}, &containertypes.HostConfig{}, nil, container)
|
||||
}, &containertypes.HostConfig{}, nil, nil, container)
|
||||
assert.NilError(t, err)
|
||||
err = c.ContainerStart(context.Background(), b.ID, types.ContainerStartOptions{})
|
||||
assert.NilError(t, err)
|
||||
|
|
Loading…
Add table
Reference in a new issue