mirror of
https://github.com/moby/moby.git
synced 2026-01-11 02:31:44 +00:00
client_(attach,commit,create,diff): Wrap result and options
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
This commit is contained in:
@@ -12,7 +12,6 @@ import (
|
||||
"github.com/moby/moby/api/types/registry"
|
||||
"github.com/moby/moby/api/types/swarm"
|
||||
"github.com/moby/moby/api/types/system"
|
||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
)
|
||||
|
||||
// APIClient is an interface that clients that talk with a docker server must implement.
|
||||
@@ -58,10 +57,10 @@ type HijackDialer interface {
|
||||
|
||||
// ContainerAPIClient defines API client methods for the containers
|
||||
type ContainerAPIClient interface {
|
||||
ContainerAttach(ctx context.Context, container string, options ContainerAttachOptions) (HijackedResponse, error)
|
||||
ContainerCommit(ctx context.Context, container string, options ContainerCommitOptions) (container.CommitResponse, error)
|
||||
ContainerCreate(ctx context.Context, config *container.Config, hostConfig *container.HostConfig, networkingConfig *network.NetworkingConfig, platform *ocispec.Platform, containerName string) (container.CreateResponse, error)
|
||||
ContainerDiff(ctx context.Context, container string) ([]container.FilesystemChange, error)
|
||||
ContainerAttach(ctx context.Context, container string, options ContainerAttachOptions) (ContainerAttachResult, error)
|
||||
ContainerCommit(ctx context.Context, container string, options ContainerCommitOptions) (ContainerCommitResult, error)
|
||||
ContainerCreate(ctx context.Context, options ContainerCreateOptions) (ContainerCreateResult, error)
|
||||
ContainerDiff(ctx context.Context, container string, options ContainerDiffOptions) (ContainerDiffResult, error)
|
||||
ExecAPIClient
|
||||
ContainerExport(ctx context.Context, container string) (io.ReadCloser, error)
|
||||
ContainerInspect(ctx context.Context, container string) (container.InspectResponse, error)
|
||||
|
||||
@@ -16,6 +16,11 @@ type ContainerAttachOptions struct {
|
||||
Logs bool
|
||||
}
|
||||
|
||||
// ContainerAttachResult is the result from attaching to a container.
|
||||
type ContainerAttachResult struct {
|
||||
HijackedResponse
|
||||
}
|
||||
|
||||
// ContainerAttach attaches a connection to a container in the server.
|
||||
// It returns a [HijackedResponse] with the hijacked connection
|
||||
// and a reader to get output. It's up to the called to close
|
||||
@@ -44,10 +49,10 @@ type ContainerAttachOptions struct {
|
||||
// [stdcopy.StdType]: https://pkg.go.dev/github.com/moby/moby/api/pkg/stdcopy#StdType
|
||||
// [Stdout]: https://pkg.go.dev/github.com/moby/moby/api/pkg/stdcopy#Stdout
|
||||
// [Stderr]: https://pkg.go.dev/github.com/moby/moby/api/pkg/stdcopy#Stderr
|
||||
func (cli *Client) ContainerAttach(ctx context.Context, containerID string, options ContainerAttachOptions) (HijackedResponse, error) {
|
||||
func (cli *Client) ContainerAttach(ctx context.Context, containerID string, options ContainerAttachOptions) (ContainerAttachResult, error) {
|
||||
containerID, err := trimID("container", containerID)
|
||||
if err != nil {
|
||||
return HijackedResponse{}, err
|
||||
return ContainerAttachResult{}, err
|
||||
}
|
||||
|
||||
query := url.Values{}
|
||||
@@ -70,7 +75,12 @@ func (cli *Client) ContainerAttach(ctx context.Context, containerID string, opti
|
||||
query.Set("logs", "1")
|
||||
}
|
||||
|
||||
return cli.postHijacked(ctx, "/containers/"+containerID+"/attach", query, nil, http.Header{
|
||||
hijacked, err := cli.postHijacked(ctx, "/containers/"+containerID+"/attach", query, nil, http.Header{
|
||||
"Content-Type": {"text/plain"},
|
||||
})
|
||||
if err != nil {
|
||||
return ContainerAttachResult{}, err
|
||||
}
|
||||
|
||||
return ContainerAttachResult{HijackedResponse: hijacked}, nil
|
||||
}
|
||||
|
||||
@@ -20,22 +20,27 @@ type ContainerCommitOptions struct {
|
||||
Config *container.Config
|
||||
}
|
||||
|
||||
// ContainerCommitResult is the result from committing a container.
|
||||
type ContainerCommitResult struct {
|
||||
ID string
|
||||
}
|
||||
|
||||
// ContainerCommit applies changes to a container and creates a new tagged image.
|
||||
func (cli *Client) ContainerCommit(ctx context.Context, containerID string, options ContainerCommitOptions) (container.CommitResponse, error) {
|
||||
func (cli *Client) ContainerCommit(ctx context.Context, containerID string, options ContainerCommitOptions) (ContainerCommitResult, error) {
|
||||
containerID, err := trimID("container", containerID)
|
||||
if err != nil {
|
||||
return container.CommitResponse{}, err
|
||||
return ContainerCommitResult{}, err
|
||||
}
|
||||
|
||||
var repository, tag string
|
||||
if options.Reference != "" {
|
||||
ref, err := reference.ParseNormalizedNamed(options.Reference)
|
||||
if err != nil {
|
||||
return container.CommitResponse{}, err
|
||||
return ContainerCommitResult{}, err
|
||||
}
|
||||
|
||||
if _, ok := ref.(reference.Digested); ok {
|
||||
return container.CommitResponse{}, errors.New("refusing to create a tag with a digest reference")
|
||||
return ContainerCommitResult{}, errors.New("refusing to create a tag with a digest reference")
|
||||
}
|
||||
ref = reference.TagNameOnly(ref)
|
||||
|
||||
@@ -62,9 +67,9 @@ func (cli *Client) ContainerCommit(ctx context.Context, containerID string, opti
|
||||
resp, err := cli.post(ctx, "/commit", query, options.Config, nil)
|
||||
defer ensureReaderClosed(resp)
|
||||
if err != nil {
|
||||
return response, err
|
||||
return ContainerCommitResult{}, err
|
||||
}
|
||||
|
||||
err = json.NewDecoder(resp.Body).Decode(&response)
|
||||
return response, err
|
||||
return ContainerCommitResult{ID: response.ID}, err
|
||||
}
|
||||
|
||||
@@ -10,49 +10,48 @@ import (
|
||||
|
||||
cerrdefs "github.com/containerd/errdefs"
|
||||
"github.com/moby/moby/api/types/container"
|
||||
"github.com/moby/moby/api/types/network"
|
||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
)
|
||||
|
||||
// ContainerCreate creates a new container based on 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, platform *ocispec.Platform, containerName string) (container.CreateResponse, error) {
|
||||
if config == nil {
|
||||
return container.CreateResponse{}, cerrdefs.ErrInvalidArgument.WithMessage("config is nil")
|
||||
func (cli *Client) ContainerCreate(ctx context.Context, options ContainerCreateOptions) (ContainerCreateResult, error) {
|
||||
if options.Config == nil {
|
||||
return ContainerCreateResult{}, cerrdefs.ErrInvalidArgument.WithMessage("config is nil")
|
||||
}
|
||||
|
||||
var response container.CreateResponse
|
||||
|
||||
if hostConfig != nil {
|
||||
hostConfig.CapAdd = normalizeCapabilities(hostConfig.CapAdd)
|
||||
hostConfig.CapDrop = normalizeCapabilities(hostConfig.CapDrop)
|
||||
if options.HostConfig != nil {
|
||||
options.HostConfig.CapAdd = normalizeCapabilities(options.HostConfig.CapAdd)
|
||||
options.HostConfig.CapDrop = normalizeCapabilities(options.HostConfig.CapDrop)
|
||||
}
|
||||
|
||||
query := url.Values{}
|
||||
if platform != nil {
|
||||
if p := formatPlatform(*platform); p != "unknown" {
|
||||
if options.Platform != nil {
|
||||
if p := formatPlatform(*options.Platform); p != "unknown" {
|
||||
query.Set("platform", p)
|
||||
}
|
||||
}
|
||||
|
||||
if containerName != "" {
|
||||
query.Set("name", containerName)
|
||||
if options.ContainerName != "" {
|
||||
query.Set("name", options.ContainerName)
|
||||
}
|
||||
|
||||
body := container.CreateRequest{
|
||||
Config: config,
|
||||
HostConfig: hostConfig,
|
||||
NetworkingConfig: networkingConfig,
|
||||
Config: options.Config,
|
||||
HostConfig: options.HostConfig,
|
||||
NetworkingConfig: options.NetworkingConfig,
|
||||
}
|
||||
|
||||
resp, err := cli.post(ctx, "/containers/create", query, body, nil)
|
||||
defer ensureReaderClosed(resp)
|
||||
if err != nil {
|
||||
return response, err
|
||||
return ContainerCreateResult{}, err
|
||||
}
|
||||
|
||||
err = json.NewDecoder(resp.Body).Decode(&response)
|
||||
return response, err
|
||||
return ContainerCreateResult{ID: response.ID, Warnings: response.Warnings}, err
|
||||
}
|
||||
|
||||
// formatPlatform returns a formatted string representing platform (e.g., "linux/arm/v7").
|
||||
|
||||
22
client/container_create_opts.go
Normal file
22
client/container_create_opts.go
Normal file
@@ -0,0 +1,22 @@
|
||||
package client
|
||||
|
||||
import (
|
||||
"github.com/moby/moby/api/types/container"
|
||||
"github.com/moby/moby/api/types/network"
|
||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
)
|
||||
|
||||
// ContainerCreateOptions holds parameters to create a container.
|
||||
type ContainerCreateOptions struct {
|
||||
Config *container.Config
|
||||
HostConfig *container.HostConfig
|
||||
NetworkingConfig *network.NetworkingConfig
|
||||
Platform *ocispec.Platform
|
||||
ContainerName string
|
||||
}
|
||||
|
||||
// ContainerCreateResult is the result from creating a container.
|
||||
type ContainerCreateResult struct {
|
||||
ID string
|
||||
Warnings []string
|
||||
}
|
||||
@@ -22,11 +22,11 @@ func TestContainerCreateError(t *testing.T) {
|
||||
)
|
||||
assert.NilError(t, err)
|
||||
|
||||
_, err = client.ContainerCreate(context.Background(), nil, nil, nil, nil, "nothing")
|
||||
_, err = client.ContainerCreate(context.Background(), ContainerCreateOptions{Config: nil, ContainerName: "nothing"})
|
||||
assert.Error(t, err, "config is nil")
|
||||
assert.Check(t, is.ErrorType(err, cerrdefs.IsInvalidArgument))
|
||||
|
||||
_, err = client.ContainerCreate(context.Background(), &container.Config{}, nil, nil, nil, "nothing")
|
||||
_, err = client.ContainerCreate(context.Background(), ContainerCreateOptions{Config: &container.Config{}, ContainerName: "nothing"})
|
||||
assert.Check(t, is.ErrorType(err, cerrdefs.IsInternal))
|
||||
|
||||
// 404 doesn't automatically means an unknown image
|
||||
@@ -35,7 +35,7 @@ func TestContainerCreateError(t *testing.T) {
|
||||
)
|
||||
assert.NilError(t, err)
|
||||
|
||||
_, err = client.ContainerCreate(context.Background(), &container.Config{}, nil, nil, nil, "nothing")
|
||||
_, err = client.ContainerCreate(context.Background(), ContainerCreateOptions{Config: &container.Config{}, ContainerName: "nothing"})
|
||||
assert.Check(t, is.ErrorType(err, cerrdefs.IsNotFound))
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ func TestContainerCreateImageNotFound(t *testing.T) {
|
||||
)
|
||||
assert.NilError(t, err)
|
||||
|
||||
_, err = client.ContainerCreate(context.Background(), &container.Config{Image: "unknown_image"}, nil, nil, nil, "unknown")
|
||||
_, err = client.ContainerCreate(context.Background(), ContainerCreateOptions{Config: &container.Config{Image: "unknown_image"}, ContainerName: "unknown"})
|
||||
assert.Check(t, is.ErrorType(err, cerrdefs.IsNotFound))
|
||||
}
|
||||
|
||||
@@ -74,7 +74,7 @@ func TestContainerCreateWithName(t *testing.T) {
|
||||
)
|
||||
assert.NilError(t, err)
|
||||
|
||||
r, err := client.ContainerCreate(context.Background(), &container.Config{}, nil, nil, nil, "container_name")
|
||||
r, err := client.ContainerCreate(context.Background(), ContainerCreateOptions{Config: &container.Config{}, ContainerName: "container_name"})
|
||||
assert.NilError(t, err)
|
||||
assert.Check(t, is.Equal(r.ID, "container_id"))
|
||||
}
|
||||
@@ -103,7 +103,7 @@ func TestContainerCreateAutoRemove(t *testing.T) {
|
||||
)
|
||||
assert.NilError(t, err)
|
||||
|
||||
resp, err := client.ContainerCreate(context.Background(), &container.Config{}, &container.HostConfig{AutoRemove: true}, nil, nil, "")
|
||||
resp, err := client.ContainerCreate(context.Background(), ContainerCreateOptions{Config: &container.Config{}, HostConfig: &container.HostConfig{AutoRemove: true}})
|
||||
assert.NilError(t, err)
|
||||
assert.Check(t, is.Equal(resp.ID, "container_id"))
|
||||
}
|
||||
@@ -116,7 +116,7 @@ func TestContainerCreateConnectionError(t *testing.T) {
|
||||
client, err := NewClientWithOpts(WithAPIVersionNegotiation(), WithHost("tcp://no-such-host.invalid"))
|
||||
assert.NilError(t, err)
|
||||
|
||||
_, err = client.ContainerCreate(context.Background(), &container.Config{}, nil, nil, nil, "")
|
||||
_, err = client.ContainerCreate(context.Background(), ContainerCreateOptions{Config: &container.Config{}})
|
||||
assert.Check(t, is.ErrorType(err, IsErrConnectionFailed))
|
||||
}
|
||||
|
||||
@@ -165,6 +165,6 @@ func TestContainerCreateCapabilities(t *testing.T) {
|
||||
)
|
||||
assert.NilError(t, err)
|
||||
|
||||
_, err = client.ContainerCreate(context.Background(), &container.Config{}, &container.HostConfig{CapAdd: inputCaps, CapDrop: inputCaps}, nil, nil, "")
|
||||
_, err = client.ContainerCreate(context.Background(), ContainerCreateOptions{Config: &container.Config{}, HostConfig: &container.HostConfig{CapAdd: inputCaps, CapDrop: inputCaps}})
|
||||
assert.NilError(t, err)
|
||||
}
|
||||
|
||||
@@ -9,22 +9,22 @@ import (
|
||||
)
|
||||
|
||||
// ContainerDiff shows differences in a container filesystem since it was started.
|
||||
func (cli *Client) ContainerDiff(ctx context.Context, containerID string) ([]container.FilesystemChange, error) {
|
||||
func (cli *Client) ContainerDiff(ctx context.Context, containerID string, options ContainerDiffOptions) (ContainerDiffResult, error) {
|
||||
containerID, err := trimID("container", containerID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return ContainerDiffResult{}, err
|
||||
}
|
||||
|
||||
resp, err := cli.get(ctx, "/containers/"+containerID+"/changes", url.Values{}, nil)
|
||||
defer ensureReaderClosed(resp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return ContainerDiffResult{}, err
|
||||
}
|
||||
|
||||
var changes []container.FilesystemChange
|
||||
err = json.NewDecoder(resp.Body).Decode(&changes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return ContainerDiffResult{}, err
|
||||
}
|
||||
return changes, err
|
||||
return ContainerDiffResult{Changes: changes}, err
|
||||
}
|
||||
|
||||
13
client/container_diff_opts.go
Normal file
13
client/container_diff_opts.go
Normal file
@@ -0,0 +1,13 @@
|
||||
package client
|
||||
|
||||
import "github.com/moby/moby/api/types/container"
|
||||
|
||||
// ContainerDiffOptions holds parameters to show differences in a container filesystem.
|
||||
type ContainerDiffOptions struct {
|
||||
// Currently no options, but this allows for future extensibility
|
||||
}
|
||||
|
||||
// ContainerDiffResult is the result from showing differences in a container filesystem.
|
||||
type ContainerDiffResult struct {
|
||||
Changes []container.FilesystemChange
|
||||
}
|
||||
@@ -20,14 +20,14 @@ func TestContainerDiffError(t *testing.T) {
|
||||
)
|
||||
assert.NilError(t, err)
|
||||
|
||||
_, err = client.ContainerDiff(context.Background(), "nothing")
|
||||
_, err = client.ContainerDiff(context.Background(), "nothing", ContainerDiffOptions{})
|
||||
assert.Check(t, is.ErrorType(err, cerrdefs.IsInternal))
|
||||
|
||||
_, err = client.ContainerDiff(context.Background(), "")
|
||||
_, err = client.ContainerDiff(context.Background(), "", ContainerDiffOptions{})
|
||||
assert.Check(t, is.ErrorType(err, cerrdefs.IsInvalidArgument))
|
||||
assert.Check(t, is.ErrorContains(err, "value is empty"))
|
||||
|
||||
_, err = client.ContainerDiff(context.Background(), " ")
|
||||
_, err = client.ContainerDiff(context.Background(), " ", ContainerDiffOptions{})
|
||||
assert.Check(t, is.ErrorType(err, cerrdefs.IsInvalidArgument))
|
||||
assert.Check(t, is.ErrorContains(err, "value is empty"))
|
||||
}
|
||||
@@ -67,7 +67,7 @@ func TestContainerDiff(t *testing.T) {
|
||||
)
|
||||
assert.NilError(t, err)
|
||||
|
||||
changes, err := client.ContainerDiff(context.Background(), "container_id")
|
||||
result, err := client.ContainerDiff(context.Background(), "container_id", ContainerDiffOptions{})
|
||||
assert.NilError(t, err)
|
||||
assert.Check(t, is.DeepEqual(changes, expected))
|
||||
assert.Check(t, is.DeepEqual(result.Changes, expected))
|
||||
}
|
||||
|
||||
@@ -130,12 +130,12 @@ func (s *DockerAPISuite) TestContainerAPIGetChanges(c *testing.T) {
|
||||
assert.NilError(c, err)
|
||||
defer apiClient.Close()
|
||||
|
||||
changes, err := apiClient.ContainerDiff(testutil.GetContext(c), name)
|
||||
result, err := apiClient.ContainerDiff(testutil.GetContext(c), name, client.ContainerDiffOptions{})
|
||||
assert.NilError(c, err)
|
||||
|
||||
// Check the changelog for removal of /etc/passwd
|
||||
success := false
|
||||
for _, elem := range changes {
|
||||
for _, elem := range result.Changes {
|
||||
if elem.Path == "/etc/passwd" && elem.Kind == 2 {
|
||||
success = true
|
||||
}
|
||||
@@ -517,7 +517,11 @@ func (s *DockerAPISuite) TestContainerAPIBadPort(c *testing.T) {
|
||||
assert.NilError(c, err)
|
||||
defer apiClient.Close()
|
||||
|
||||
_, err = apiClient.ContainerCreate(testutil.GetContext(c), &config, &hostConfig, &network.NetworkingConfig{}, nil, "")
|
||||
_, err = apiClient.ContainerCreate(testutil.GetContext(c), client.ContainerCreateOptions{
|
||||
Config: &config,
|
||||
HostConfig: &hostConfig,
|
||||
NetworkingConfig: &network.NetworkingConfig{},
|
||||
})
|
||||
assert.ErrorContains(c, err, `invalid port specification: "aa80"`)
|
||||
}
|
||||
|
||||
@@ -531,7 +535,11 @@ func (s *DockerAPISuite) TestContainerAPICreate(c *testing.T) {
|
||||
assert.NilError(c, err)
|
||||
defer apiClient.Close()
|
||||
|
||||
ctr, err := apiClient.ContainerCreate(testutil.GetContext(c), &config, &container.HostConfig{}, &network.NetworkingConfig{}, nil, "")
|
||||
ctr, err := apiClient.ContainerCreate(testutil.GetContext(c), client.ContainerCreateOptions{
|
||||
Config: &config,
|
||||
HostConfig: &container.HostConfig{},
|
||||
NetworkingConfig: &network.NetworkingConfig{},
|
||||
})
|
||||
assert.NilError(c, err)
|
||||
|
||||
out := cli.DockerCmd(c, "start", "-a", ctr.ID).Stdout()
|
||||
@@ -543,7 +551,11 @@ func (s *DockerAPISuite) TestContainerAPICreateEmptyConfig(c *testing.T) {
|
||||
assert.NilError(c, err)
|
||||
defer apiClient.Close()
|
||||
|
||||
_, err = apiClient.ContainerCreate(testutil.GetContext(c), &container.Config{}, &container.HostConfig{}, &network.NetworkingConfig{}, nil, "")
|
||||
_, err = apiClient.ContainerCreate(testutil.GetContext(c), client.ContainerCreateOptions{
|
||||
Config: &container.Config{},
|
||||
HostConfig: &container.HostConfig{},
|
||||
NetworkingConfig: &network.NetworkingConfig{},
|
||||
})
|
||||
|
||||
assert.ErrorContains(c, err, "no command specified")
|
||||
}
|
||||
@@ -574,7 +586,11 @@ func UtilCreateNetworkMode(t *testing.T, networkMode container.NetworkMode) {
|
||||
assert.NilError(t, err)
|
||||
defer apiClient.Close()
|
||||
|
||||
ctr, err := apiClient.ContainerCreate(testutil.GetContext(t), &config, &hostConfig, &network.NetworkingConfig{}, nil, "")
|
||||
ctr, err := apiClient.ContainerCreate(testutil.GetContext(t), client.ContainerCreateOptions{
|
||||
Config: &config,
|
||||
HostConfig: &hostConfig,
|
||||
NetworkingConfig: &network.NetworkingConfig{},
|
||||
})
|
||||
assert.NilError(t, err)
|
||||
|
||||
containerJSON, err := apiClient.ContainerInspect(testutil.GetContext(t), ctr.ID)
|
||||
@@ -601,7 +617,11 @@ func (s *DockerAPISuite) TestContainerAPICreateWithCpuSharesCpuset(c *testing.T)
|
||||
assert.NilError(c, err)
|
||||
defer apiClient.Close()
|
||||
|
||||
ctr, err := apiClient.ContainerCreate(testutil.GetContext(c), &config, &hostConfig, &network.NetworkingConfig{}, nil, "")
|
||||
ctr, err := apiClient.ContainerCreate(testutil.GetContext(c), client.ContainerCreateOptions{
|
||||
Config: &config,
|
||||
HostConfig: &hostConfig,
|
||||
NetworkingConfig: &network.NetworkingConfig{},
|
||||
})
|
||||
assert.NilError(c, err)
|
||||
|
||||
containerJSON, err := apiClient.ContainerInspect(testutil.GetContext(c), ctr.ID)
|
||||
@@ -746,7 +766,12 @@ func (s *DockerAPISuite) TestContainerAPIStart(c *testing.T) {
|
||||
assert.NilError(c, err)
|
||||
defer apiClient.Close()
|
||||
|
||||
_, err = apiClient.ContainerCreate(testutil.GetContext(c), &config, &container.HostConfig{}, &network.NetworkingConfig{}, nil, name)
|
||||
_, err = apiClient.ContainerCreate(testutil.GetContext(c), client.ContainerCreateOptions{
|
||||
Config: &config,
|
||||
HostConfig: &container.HostConfig{},
|
||||
NetworkingConfig: &network.NetworkingConfig{},
|
||||
ContainerName: name,
|
||||
})
|
||||
assert.NilError(c, err)
|
||||
|
||||
err = apiClient.ContainerStart(testutil.GetContext(c), name, client.ContainerStartOptions{})
|
||||
@@ -989,7 +1014,12 @@ func (s *DockerAPISuite) TestPostContainersCreateWithWrongCpusetValues(c *testin
|
||||
}
|
||||
const name = "wrong-cpuset-cpus"
|
||||
|
||||
_, err = apiClient.ContainerCreate(testutil.GetContext(c), &config, &hostConfig1, &network.NetworkingConfig{}, nil, name)
|
||||
_, err = apiClient.ContainerCreate(testutil.GetContext(c), client.ContainerCreateOptions{
|
||||
Config: &config,
|
||||
HostConfig: &hostConfig1,
|
||||
NetworkingConfig: &network.NetworkingConfig{},
|
||||
ContainerName: name,
|
||||
})
|
||||
expected := "Invalid value 1-42,, for cpuset cpus"
|
||||
assert.ErrorContains(c, err, expected)
|
||||
|
||||
@@ -999,7 +1029,12 @@ func (s *DockerAPISuite) TestPostContainersCreateWithWrongCpusetValues(c *testin
|
||||
},
|
||||
}
|
||||
const name2 = "wrong-cpuset-mems"
|
||||
_, err = apiClient.ContainerCreate(testutil.GetContext(c), &config, &hostConfig2, &network.NetworkingConfig{}, nil, name2)
|
||||
_, err = apiClient.ContainerCreate(testutil.GetContext(c), client.ContainerCreateOptions{
|
||||
Config: &config,
|
||||
HostConfig: &hostConfig2,
|
||||
NetworkingConfig: &network.NetworkingConfig{},
|
||||
ContainerName: name2,
|
||||
})
|
||||
expected = "Invalid value 42-3,1-- for cpuset mems"
|
||||
assert.ErrorContains(c, err, expected)
|
||||
}
|
||||
@@ -1015,7 +1050,11 @@ func (s *DockerAPISuite) TestPostContainersCreateMemorySwappinessHostConfigOmitt
|
||||
assert.NilError(c, err)
|
||||
defer apiClient.Close()
|
||||
|
||||
ctr, err := apiClient.ContainerCreate(testutil.GetContext(c), &config, &container.HostConfig{}, &network.NetworkingConfig{}, nil, "")
|
||||
ctr, err := apiClient.ContainerCreate(testutil.GetContext(c), client.ContainerCreateOptions{
|
||||
Config: &config,
|
||||
HostConfig: &container.HostConfig{},
|
||||
NetworkingConfig: &network.NetworkingConfig{},
|
||||
})
|
||||
assert.NilError(c, err)
|
||||
|
||||
containerJSON, err := apiClient.ContainerInspect(testutil.GetContext(c), ctr.ID)
|
||||
@@ -1042,7 +1081,12 @@ func (s *DockerAPISuite) TestPostContainersCreateWithOomScoreAdjInvalidRange(c *
|
||||
defer apiClient.Close()
|
||||
|
||||
const name = "oomscoreadj-over"
|
||||
_, err = apiClient.ContainerCreate(testutil.GetContext(c), &config, &hostConfig, &network.NetworkingConfig{}, nil, name)
|
||||
_, err = apiClient.ContainerCreate(testutil.GetContext(c), client.ContainerCreateOptions{
|
||||
Config: &config,
|
||||
HostConfig: &hostConfig,
|
||||
NetworkingConfig: &network.NetworkingConfig{},
|
||||
ContainerName: name,
|
||||
})
|
||||
|
||||
expected := "Invalid value 1001, range for oom score adj is [-1000, 1000]"
|
||||
assert.ErrorContains(c, err, expected)
|
||||
@@ -1052,7 +1096,12 @@ func (s *DockerAPISuite) TestPostContainersCreateWithOomScoreAdjInvalidRange(c *
|
||||
}
|
||||
|
||||
const name2 = "oomscoreadj-low"
|
||||
_, err = apiClient.ContainerCreate(testutil.GetContext(c), &config, &hostConfig, &network.NetworkingConfig{}, nil, name2)
|
||||
_, err = apiClient.ContainerCreate(testutil.GetContext(c), client.ContainerCreateOptions{
|
||||
Config: &config,
|
||||
HostConfig: &hostConfig,
|
||||
NetworkingConfig: &network.NetworkingConfig{},
|
||||
ContainerName: name2,
|
||||
})
|
||||
|
||||
expected = "Invalid value -1001, range for oom score adj is [-1000, 1000]"
|
||||
assert.ErrorContains(c, err, expected)
|
||||
@@ -1085,7 +1134,12 @@ func (s *DockerAPISuite) TestContainerAPIStatsWithNetworkDisabled(c *testing.T)
|
||||
assert.NilError(c, err)
|
||||
defer apiClient.Close()
|
||||
|
||||
_, err = apiClient.ContainerCreate(testutil.GetContext(c), &config, &container.HostConfig{}, &network.NetworkingConfig{}, nil, name)
|
||||
_, err = apiClient.ContainerCreate(testutil.GetContext(c), client.ContainerCreateOptions{
|
||||
Config: &config,
|
||||
HostConfig: &container.HostConfig{},
|
||||
NetworkingConfig: &network.NetworkingConfig{},
|
||||
ContainerName: name,
|
||||
})
|
||||
assert.NilError(c, err)
|
||||
|
||||
err = apiClient.ContainerStart(testutil.GetContext(c), name, client.ContainerStartOptions{})
|
||||
@@ -1421,7 +1475,11 @@ func (s *DockerAPISuite) TestContainersAPICreateMountsValidation(c *testing.T) {
|
||||
// TODO add checks for statuscode returned by API
|
||||
for i, tc := range tests {
|
||||
c.Run(fmt.Sprintf("case %d", i), func(c *testing.T) {
|
||||
_, err = apiClient.ContainerCreate(testutil.GetContext(c), &tc.config, &tc.hostConfig, &network.NetworkingConfig{}, nil, "")
|
||||
_, err = apiClient.ContainerCreate(testutil.GetContext(c), client.ContainerCreateOptions{
|
||||
Config: &tc.config,
|
||||
HostConfig: &tc.hostConfig,
|
||||
NetworkingConfig: &network.NetworkingConfig{},
|
||||
})
|
||||
if tc.msg != "" {
|
||||
assert.ErrorContains(c, err, tc.msg, "%v", tests[i].config)
|
||||
} else {
|
||||
@@ -1454,7 +1512,12 @@ func (s *DockerAPISuite) TestContainerAPICreateMountsBindRead(c *testing.T) {
|
||||
assert.NilError(c, err)
|
||||
defer apiClient.Close()
|
||||
|
||||
_, err = apiClient.ContainerCreate(testutil.GetContext(c), &config, &hostConfig, &network.NetworkingConfig{}, nil, "test")
|
||||
_, err = apiClient.ContainerCreate(testutil.GetContext(c), client.ContainerCreateOptions{
|
||||
Config: &config,
|
||||
HostConfig: &hostConfig,
|
||||
NetworkingConfig: &network.NetworkingConfig{},
|
||||
ContainerName: "test",
|
||||
})
|
||||
assert.NilError(c, err)
|
||||
|
||||
out := cli.DockerCmd(c, "start", "-a", "test").Combined()
|
||||
@@ -1590,11 +1653,11 @@ func (s *DockerAPISuite) TestContainersAPICreateMountsCreate(c *testing.T) {
|
||||
c.Run(fmt.Sprintf("%d config: %v", i, tc.spec), func(c *testing.T) {
|
||||
ctr, err := apiclient.ContainerCreate(
|
||||
ctx,
|
||||
&container.Config{Image: testImg},
|
||||
&container.HostConfig{Mounts: []mount.Mount{tc.spec}},
|
||||
&network.NetworkingConfig{},
|
||||
nil,
|
||||
"")
|
||||
client.ContainerCreateOptions{
|
||||
Config: &container.Config{Image: testImg},
|
||||
HostConfig: &container.HostConfig{Mounts: []mount.Mount{tc.spec}},
|
||||
NetworkingConfig: &network.NetworkingConfig{},
|
||||
})
|
||||
assert.NilError(c, err)
|
||||
|
||||
containerInspect, err := apiclient.ContainerInspect(ctx, ctr.ID)
|
||||
@@ -1705,7 +1768,12 @@ func (s *DockerAPISuite) TestContainersAPICreateMountsTmpfs(c *testing.T) {
|
||||
Mounts: []mount.Mount{x.cfg},
|
||||
}
|
||||
|
||||
_, err = apiClient.ContainerCreate(testutil.GetContext(c), &config, &hostConfig, &network.NetworkingConfig{}, nil, cName)
|
||||
_, err = apiClient.ContainerCreate(testutil.GetContext(c), client.ContainerCreateOptions{
|
||||
Config: &config,
|
||||
HostConfig: &hostConfig,
|
||||
NetworkingConfig: &network.NetworkingConfig{},
|
||||
ContainerName: cName,
|
||||
})
|
||||
assert.NilError(c, err)
|
||||
out := cli.DockerCmd(c, "start", "-a", cName).Combined()
|
||||
for _, option := range x.expectedOptions {
|
||||
|
||||
@@ -12,6 +12,7 @@ import (
|
||||
"github.com/Microsoft/go-winio"
|
||||
"github.com/moby/moby/api/types/container"
|
||||
"github.com/moby/moby/api/types/mount"
|
||||
"github.com/moby/moby/api/types/network"
|
||||
"github.com/moby/moby/client"
|
||||
"github.com/moby/moby/v2/internal/testutil"
|
||||
"github.com/pkg/errors"
|
||||
@@ -51,19 +52,23 @@ func (s *DockerAPISuite) TestContainersAPICreateMountsBindNamedPipe(c *testing.T
|
||||
ctx := testutil.GetContext(c)
|
||||
apiClient := testEnv.APIClient()
|
||||
_, err = apiClient.ContainerCreate(ctx,
|
||||
&container.Config{
|
||||
Image: testEnv.PlatformDefaults.BaseImage,
|
||||
Cmd: []string{"cmd", "/c", cmd},
|
||||
}, &container.HostConfig{
|
||||
Mounts: []mount.Mount{
|
||||
{
|
||||
Type: "npipe",
|
||||
Source: hostPipeName,
|
||||
Target: containerPipeName,
|
||||
client.ContainerCreateOptions{
|
||||
Config: &container.Config{
|
||||
Image: testEnv.PlatformDefaults.BaseImage,
|
||||
Cmd: []string{"cmd", "/c", cmd},
|
||||
},
|
||||
HostConfig: &container.HostConfig{
|
||||
Mounts: []mount.Mount{
|
||||
{
|
||||
Type: "npipe",
|
||||
Source: hostPipeName,
|
||||
Target: containerPipeName,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
nil, nil, name)
|
||||
NetworkingConfig: &network.NetworkingConfig{},
|
||||
ContainerName: name,
|
||||
})
|
||||
assert.NilError(c, err)
|
||||
|
||||
err = apiClient.ContainerStart(ctx, name, client.ContainerStartOptions{})
|
||||
|
||||
@@ -596,7 +596,12 @@ func (s *DockerCLIVolumeSuite) TestDuplicateMountpointsForVolumesFromAndMounts(c
|
||||
},
|
||||
},
|
||||
}
|
||||
_, err = apiClient.ContainerCreate(testutil.GetContext(c), &config, &hostConfig, &network.NetworkingConfig{}, nil, "app")
|
||||
_, err = apiClient.ContainerCreate(testutil.GetContext(c), client.ContainerCreateOptions{
|
||||
Config: &config,
|
||||
HostConfig: &hostConfig,
|
||||
NetworkingConfig: &network.NetworkingConfig{},
|
||||
ContainerName: "app",
|
||||
})
|
||||
|
||||
assert.NilError(c, err)
|
||||
|
||||
|
||||
@@ -41,17 +41,15 @@ func TestAttach(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
ctx := testutil.StartSpan(ctx, t)
|
||||
resp, err := apiClient.ContainerCreate(ctx,
|
||||
&container.Config{
|
||||
resp, err := apiClient.ContainerCreate(ctx, client.ContainerCreateOptions{
|
||||
Config: &container.Config{
|
||||
Image: "busybox",
|
||||
Cmd: []string{"echo", "hello"},
|
||||
Tty: tc.tty,
|
||||
},
|
||||
&container.HostConfig{},
|
||||
&network.NetworkingConfig{},
|
||||
nil,
|
||||
"",
|
||||
)
|
||||
HostConfig: &container.HostConfig{},
|
||||
NetworkingConfig: &network.NetworkingConfig{},
|
||||
})
|
||||
assert.NilError(t, err)
|
||||
attach, err := apiClient.ContainerAttach(ctx, resp.ID, client.ContainerAttachOptions{
|
||||
Stdout: true,
|
||||
@@ -81,16 +79,14 @@ func TestAttachDisconnectLeak(t *testing.T) {
|
||||
|
||||
apiClient := d.NewClientT(t)
|
||||
|
||||
resp, err := apiClient.ContainerCreate(ctx,
|
||||
&container.Config{
|
||||
resp, err := apiClient.ContainerCreate(ctx, client.ContainerCreateOptions{
|
||||
Config: &container.Config{
|
||||
Image: "busybox",
|
||||
Cmd: []string{"/bin/sh", "-c", "while true; usleep 100000; done"},
|
||||
},
|
||||
&container.HostConfig{},
|
||||
&network.NetworkingConfig{},
|
||||
nil,
|
||||
"",
|
||||
)
|
||||
HostConfig: &container.HostConfig{},
|
||||
NetworkingConfig: &network.NetworkingConfig{},
|
||||
})
|
||||
assert.NilError(t, err)
|
||||
cID := resp.ID
|
||||
defer apiClient.ContainerRemove(ctx, cID, client.ContainerRemoveOptions{
|
||||
|
||||
@@ -59,13 +59,11 @@ func TestCreateFailsWhenIdentifierDoesNotExist(t *testing.T) {
|
||||
t.Run(tc.doc, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
ctx := testutil.StartSpan(ctx, t)
|
||||
_, err := apiClient.ContainerCreate(ctx,
|
||||
&container.Config{Image: tc.image},
|
||||
&container.HostConfig{},
|
||||
&network.NetworkingConfig{},
|
||||
nil,
|
||||
"",
|
||||
)
|
||||
_, err := apiClient.ContainerCreate(ctx, client.ContainerCreateOptions{
|
||||
Config: &container.Config{Image: tc.image},
|
||||
HostConfig: &container.HostConfig{},
|
||||
NetworkingConfig: &network.NetworkingConfig{},
|
||||
})
|
||||
assert.Check(t, is.ErrorContains(err, tc.expectedError))
|
||||
assert.Check(t, is.ErrorType(err, cerrdefs.IsNotFound))
|
||||
})
|
||||
@@ -125,15 +123,11 @@ func TestCreateByImageID(t *testing.T) {
|
||||
t.Run(tc.doc, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
ctx := testutil.StartSpan(ctx, t)
|
||||
resp, err := apiClient.ContainerCreate(ctx,
|
||||
&container.Config{Image: tc.image},
|
||||
&container.HostConfig{},
|
||||
&network.NetworkingConfig{},
|
||||
nil,
|
||||
"",
|
||||
)
|
||||
resp, err := apiClient.ContainerCreate(ctx, client.ContainerCreateOptions{
|
||||
Config: &container.Config{Image: tc.image},
|
||||
})
|
||||
if tc.expectedErr != "" {
|
||||
assert.Check(t, is.DeepEqual(resp, container.CreateResponse{}))
|
||||
assert.Check(t, is.DeepEqual(resp, client.ContainerCreateResult{}))
|
||||
assert.Check(t, is.Error(err, tc.expectedErr))
|
||||
assert.Check(t, is.ErrorType(err, tc.expectedErrType))
|
||||
} else {
|
||||
@@ -154,17 +148,14 @@ func TestCreateLinkToNonExistingContainer(t *testing.T) {
|
||||
ctx := setupTest(t)
|
||||
apiClient := testEnv.APIClient()
|
||||
|
||||
_, err := apiClient.ContainerCreate(ctx,
|
||||
&container.Config{
|
||||
_, err := apiClient.ContainerCreate(ctx, client.ContainerCreateOptions{
|
||||
Config: &container.Config{
|
||||
Image: "busybox",
|
||||
},
|
||||
&container.HostConfig{
|
||||
HostConfig: &container.HostConfig{
|
||||
Links: []string{"no-such-container"},
|
||||
},
|
||||
&network.NetworkingConfig{},
|
||||
nil,
|
||||
"",
|
||||
)
|
||||
})
|
||||
assert.Check(t, is.ErrorContains(err, "could not get container for no-such-container"))
|
||||
assert.Check(t, is.ErrorType(err, cerrdefs.IsInvalidArgument))
|
||||
}
|
||||
@@ -195,16 +186,12 @@ func TestCreateWithInvalidEnv(t *testing.T) {
|
||||
t.Run(strconv.Itoa(index), func(t *testing.T) {
|
||||
t.Parallel()
|
||||
ctx := testutil.StartSpan(ctx, t)
|
||||
_, err := apiClient.ContainerCreate(ctx,
|
||||
&container.Config{
|
||||
_, err := apiClient.ContainerCreate(ctx, client.ContainerCreateOptions{
|
||||
Config: &container.Config{
|
||||
Image: "busybox",
|
||||
Env: []string{tc.env},
|
||||
},
|
||||
&container.HostConfig{},
|
||||
&network.NetworkingConfig{},
|
||||
nil,
|
||||
"",
|
||||
)
|
||||
})
|
||||
assert.Check(t, is.ErrorContains(err, tc.expectedError))
|
||||
assert.Check(t, is.ErrorType(err, cerrdefs.IsInvalidArgument))
|
||||
})
|
||||
@@ -241,17 +228,14 @@ func TestCreateTmpfsMountsTarget(t *testing.T) {
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
_, err := apiClient.ContainerCreate(ctx,
|
||||
&container.Config{
|
||||
_, err := apiClient.ContainerCreate(ctx, client.ContainerCreateOptions{
|
||||
Config: &container.Config{
|
||||
Image: "busybox",
|
||||
},
|
||||
&container.HostConfig{
|
||||
HostConfig: &container.HostConfig{
|
||||
Tmpfs: map[string]string{tc.target: ""},
|
||||
},
|
||||
&network.NetworkingConfig{},
|
||||
nil,
|
||||
"",
|
||||
)
|
||||
})
|
||||
assert.Check(t, is.ErrorContains(err, tc.expectedError))
|
||||
assert.Check(t, is.ErrorType(err, cerrdefs.IsInvalidArgument))
|
||||
}
|
||||
@@ -298,19 +282,17 @@ func TestCreateWithCustomMaskedPaths(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
// Create the container.
|
||||
ctr, err := apiClient.ContainerCreate(ctx,
|
||||
&container.Config{
|
||||
ctr, err := apiClient.ContainerCreate(ctx, client.ContainerCreateOptions{
|
||||
Config: &container.Config{
|
||||
Image: "busybox",
|
||||
Cmd: []string{"true"},
|
||||
},
|
||||
&container.HostConfig{
|
||||
HostConfig: &container.HostConfig{
|
||||
Privileged: tc.privileged,
|
||||
MaskedPaths: tc.maskedPaths,
|
||||
},
|
||||
nil,
|
||||
nil,
|
||||
fmt.Sprintf("create-masked-paths-%d", i),
|
||||
)
|
||||
ContainerName: fmt.Sprintf("create-masked-paths-%d", i),
|
||||
})
|
||||
assert.NilError(t, err)
|
||||
|
||||
ctrInspect, err := apiClient.ContainerInspect(ctx, ctr.ID)
|
||||
@@ -371,19 +353,17 @@ func TestCreateWithCustomReadonlyPaths(t *testing.T) {
|
||||
for i, tc := range testCases {
|
||||
t.Run(tc.doc, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
ctr, err := apiClient.ContainerCreate(ctx,
|
||||
&container.Config{
|
||||
ctr, err := apiClient.ContainerCreate(ctx, client.ContainerCreateOptions{
|
||||
Config: &container.Config{
|
||||
Image: "busybox",
|
||||
Cmd: []string{"true"},
|
||||
},
|
||||
&container.HostConfig{
|
||||
HostConfig: &container.HostConfig{
|
||||
Privileged: tc.privileged,
|
||||
ReadonlyPaths: tc.readonlyPaths,
|
||||
},
|
||||
nil,
|
||||
nil,
|
||||
fmt.Sprintf("create-readonly-paths-%d", i),
|
||||
)
|
||||
ContainerName: fmt.Sprintf("create-readonly-paths-%d", i),
|
||||
})
|
||||
assert.NilError(t, err)
|
||||
|
||||
ctrInspect, err := apiClient.ContainerInspect(ctx, ctr.ID)
|
||||
@@ -482,7 +462,9 @@ func TestCreateWithInvalidHealthcheckParams(t *testing.T) {
|
||||
cfg.Healthcheck.StartPeriod = tc.startPeriod
|
||||
}
|
||||
|
||||
resp, err := apiClient.ContainerCreate(ctx, &cfg, &container.HostConfig{}, nil, nil, "")
|
||||
resp, err := apiClient.ContainerCreate(ctx, client.ContainerCreateOptions{
|
||||
Config: &cfg,
|
||||
})
|
||||
assert.Check(t, is.Equal(len(resp.Warnings), 0))
|
||||
assert.Check(t, is.ErrorType(err, cerrdefs.IsInvalidArgument))
|
||||
assert.ErrorContains(t, err, tc.expectedErr)
|
||||
@@ -553,7 +535,10 @@ func TestCreateDifferentPlatform(t *testing.T) {
|
||||
Architecture: img.Architecture,
|
||||
Variant: img.Variant,
|
||||
}
|
||||
_, err := apiClient.ContainerCreate(ctx, &container.Config{Image: "busybox:latest"}, &container.HostConfig{}, nil, &p, "")
|
||||
_, err := apiClient.ContainerCreate(ctx, client.ContainerCreateOptions{
|
||||
Config: &container.Config{Image: "busybox:latest"},
|
||||
Platform: &p,
|
||||
})
|
||||
assert.Check(t, is.ErrorType(err, cerrdefs.IsNotFound))
|
||||
})
|
||||
t.Run("different cpu arch", func(t *testing.T) {
|
||||
@@ -563,7 +548,10 @@ func TestCreateDifferentPlatform(t *testing.T) {
|
||||
Architecture: img.Architecture + "DifferentArch",
|
||||
Variant: img.Variant,
|
||||
}
|
||||
_, err := apiClient.ContainerCreate(ctx, &container.Config{Image: "busybox:latest"}, &container.HostConfig{}, nil, &p, "")
|
||||
_, err := apiClient.ContainerCreate(ctx, client.ContainerCreateOptions{
|
||||
Config: &container.Config{Image: "busybox:latest"},
|
||||
Platform: &p,
|
||||
})
|
||||
assert.Check(t, is.ErrorType(err, cerrdefs.IsNotFound))
|
||||
})
|
||||
}
|
||||
@@ -574,12 +562,10 @@ func TestCreateVolumesFromNonExistingContainer(t *testing.T) {
|
||||
|
||||
_, err := apiClient.ContainerCreate(
|
||||
ctx,
|
||||
&container.Config{Image: "busybox"},
|
||||
&container.HostConfig{VolumesFrom: []string{"nosuchcontainer"}},
|
||||
nil,
|
||||
nil,
|
||||
"",
|
||||
)
|
||||
client.ContainerCreateOptions{
|
||||
Config: &container.Config{Image: "busybox"},
|
||||
HostConfig: &container.HostConfig{VolumesFrom: []string{"nosuchcontainer"}},
|
||||
})
|
||||
assert.Check(t, is.ErrorType(err, cerrdefs.IsInvalidArgument))
|
||||
}
|
||||
|
||||
@@ -594,12 +580,9 @@ func TestCreatePlatformSpecificImageNoPlatform(t *testing.T) {
|
||||
|
||||
_, err := apiClient.ContainerCreate(
|
||||
ctx,
|
||||
&container.Config{Image: "arm32v7/hello-world"},
|
||||
&container.HostConfig{},
|
||||
nil,
|
||||
nil,
|
||||
"",
|
||||
)
|
||||
client.ContainerCreateOptions{
|
||||
Config: &container.Config{Image: "arm32v7/hello-world"},
|
||||
})
|
||||
assert.NilError(t, err)
|
||||
}
|
||||
|
||||
@@ -653,7 +636,10 @@ func TestCreateInvalidHostConfig(t *testing.T) {
|
||||
cfg := container.Config{
|
||||
Image: "busybox",
|
||||
}
|
||||
resp, err := apiClient.ContainerCreate(ctx, &cfg, &tc.hc, nil, nil, "")
|
||||
resp, err := apiClient.ContainerCreate(ctx, client.ContainerCreateOptions{
|
||||
Config: &cfg,
|
||||
HostConfig: &tc.hc,
|
||||
})
|
||||
assert.Check(t, is.Equal(len(resp.Warnings), 0))
|
||||
assert.Check(t, cerrdefs.IsInvalidArgument(err), "got: %T", err)
|
||||
assert.Error(t, err, tc.expectedErr)
|
||||
@@ -760,7 +746,10 @@ func TestCreateWithMultipleEndpointSettings(t *testing.T) {
|
||||
"net3": {},
|
||||
},
|
||||
}
|
||||
_, err = apiClient.ContainerCreate(ctx, &config, &container.HostConfig{}, &networkingConfig, nil, "")
|
||||
_, err = apiClient.ContainerCreate(ctx, client.ContainerCreateOptions{
|
||||
Config: &config,
|
||||
NetworkingConfig: &networkingConfig,
|
||||
})
|
||||
if tc.expectedErr == "" {
|
||||
assert.NilError(t, err)
|
||||
} else {
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"time"
|
||||
|
||||
containertypes "github.com/moby/moby/api/types/container"
|
||||
"github.com/moby/moby/client"
|
||||
"github.com/moby/moby/v2/integration/internal/container"
|
||||
"gotest.tools/v3/assert"
|
||||
"gotest.tools/v3/poll"
|
||||
@@ -24,9 +25,9 @@ func TestDiff(t *testing.T) {
|
||||
}
|
||||
|
||||
poll.WaitOn(t, container.IsStopped(ctx, apiClient, cID))
|
||||
items, err := apiClient.ContainerDiff(ctx, cID)
|
||||
result, err := apiClient.ContainerDiff(ctx, cID, client.ContainerDiffOptions{})
|
||||
assert.NilError(t, err)
|
||||
assert.DeepEqual(t, expected, items)
|
||||
assert.DeepEqual(t, expected, result.Changes)
|
||||
}
|
||||
|
||||
func TestDiffStoppedContainer(t *testing.T) {
|
||||
@@ -51,7 +52,7 @@ func TestDiffStoppedContainer(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
items, err := apiClient.ContainerDiff(ctx, cID)
|
||||
result, err := apiClient.ContainerDiff(ctx, cID, client.ContainerDiffOptions{})
|
||||
assert.NilError(t, err)
|
||||
assert.DeepEqual(t, expected, items)
|
||||
assert.DeepEqual(t, expected, result.Changes)
|
||||
}
|
||||
|
||||
@@ -64,7 +64,10 @@ func testIpcNonePrivateShareable(t *testing.T, mode string, mustBeMounted bool,
|
||||
}
|
||||
apiClient := testEnv.APIClient()
|
||||
|
||||
resp, err := apiClient.ContainerCreate(ctx, &cfg, &hostCfg, nil, nil, "")
|
||||
resp, err := apiClient.ContainerCreate(ctx, client.ContainerCreateOptions{
|
||||
Config: &cfg,
|
||||
HostConfig: &hostCfg,
|
||||
})
|
||||
assert.NilError(t, err)
|
||||
assert.Check(t, is.Equal(len(resp.Warnings), 0))
|
||||
|
||||
@@ -135,7 +138,10 @@ func testIpcContainer(t *testing.T, donorMode string, mustWork bool) {
|
||||
apiClient := testEnv.APIClient()
|
||||
|
||||
// create and start the "donor" container
|
||||
resp, err := apiClient.ContainerCreate(ctx, &cfg, &hostCfg, nil, nil, "")
|
||||
resp, err := apiClient.ContainerCreate(ctx, client.ContainerCreateOptions{
|
||||
Config: &cfg,
|
||||
HostConfig: &hostCfg,
|
||||
})
|
||||
assert.NilError(t, err)
|
||||
assert.Check(t, is.Equal(len(resp.Warnings), 0))
|
||||
name1 := resp.ID
|
||||
@@ -145,7 +151,10 @@ func testIpcContainer(t *testing.T, donorMode string, mustWork bool) {
|
||||
|
||||
// create and start the second container
|
||||
hostCfg.IpcMode = containertypes.IpcMode("container:" + name1)
|
||||
resp, err = apiClient.ContainerCreate(ctx, &cfg, &hostCfg, nil, nil, "")
|
||||
resp, err = apiClient.ContainerCreate(ctx, client.ContainerCreateOptions{
|
||||
Config: &cfg,
|
||||
HostConfig: &hostCfg,
|
||||
})
|
||||
assert.NilError(t, err)
|
||||
assert.Check(t, is.Equal(len(resp.Warnings), 0))
|
||||
name2 := resp.ID
|
||||
@@ -201,7 +210,10 @@ func TestAPIIpcModeHost(t *testing.T) {
|
||||
ctx := testutil.StartSpan(baseContext, t)
|
||||
|
||||
apiClient := testEnv.APIClient()
|
||||
resp, err := apiClient.ContainerCreate(ctx, &cfg, &hostCfg, nil, nil, "")
|
||||
resp, err := apiClient.ContainerCreate(ctx, client.ContainerCreateOptions{
|
||||
Config: &cfg,
|
||||
HostConfig: &hostCfg,
|
||||
})
|
||||
assert.NilError(t, err)
|
||||
assert.Check(t, is.Equal(len(resp.Warnings), 0))
|
||||
name := resp.ID
|
||||
@@ -237,7 +249,10 @@ func testDaemonIpcPrivateShareable(t *testing.T, mustBeShared bool, arg ...strin
|
||||
Cmd: []string{"top"},
|
||||
}
|
||||
|
||||
resp, err := c.ContainerCreate(ctx, &cfg, &containertypes.HostConfig{}, nil, nil, "")
|
||||
resp, err := c.ContainerCreate(ctx, client.ContainerCreateOptions{
|
||||
Config: &cfg,
|
||||
HostConfig: &containertypes.HostConfig{},
|
||||
})
|
||||
assert.NilError(t, err)
|
||||
assert.Check(t, is.Equal(len(resp.Warnings), 0))
|
||||
|
||||
|
||||
@@ -67,7 +67,11 @@ func TestContainerNetworkMountsNoChown(t *testing.T) {
|
||||
assert.NilError(t, err)
|
||||
defer cli.Close()
|
||||
|
||||
ctrCreate, err := cli.ContainerCreate(ctx, &config, &hostConfig, &network.NetworkingConfig{}, nil, "")
|
||||
ctrCreate, err := cli.ContainerCreate(ctx, client.ContainerCreateOptions{
|
||||
Config: &config,
|
||||
HostConfig: &hostConfig,
|
||||
NetworkingConfig: &network.NetworkingConfig{},
|
||||
})
|
||||
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, client.ContainerStartOptions{})
|
||||
@@ -179,10 +183,13 @@ func TestMountDaemonRoot(t *testing.T) {
|
||||
|
||||
ctx := testutil.StartSpan(ctx, t)
|
||||
|
||||
c, err := apiClient.ContainerCreate(ctx, &containertypes.Config{
|
||||
Image: "busybox",
|
||||
Cmd: []string{"true"},
|
||||
}, hc, nil, nil, "")
|
||||
c, err := apiClient.ContainerCreate(ctx, client.ContainerCreateOptions{
|
||||
Config: &containertypes.Config{
|
||||
Image: "busybox",
|
||||
Cmd: []string{"true"},
|
||||
},
|
||||
HostConfig: hc,
|
||||
})
|
||||
if err != nil {
|
||||
if test.expected != "" {
|
||||
t.Fatal(err)
|
||||
@@ -430,7 +437,13 @@ func TestContainerVolumeAnonymous(t *testing.T) {
|
||||
},
|
||||
},
|
||||
}))
|
||||
_, err := apiClient.ContainerCreate(ctx, config.Config, config.HostConfig, config.NetworkingConfig, config.Platform, config.Name)
|
||||
_, err := apiClient.ContainerCreate(ctx, client.ContainerCreateOptions{
|
||||
Config: config.Config,
|
||||
HostConfig: config.HostConfig,
|
||||
NetworkingConfig: config.NetworkingConfig,
|
||||
Platform: config.Platform,
|
||||
ContainerName: config.Name,
|
||||
})
|
||||
// We use [testNonExistingPlugin] for this, which produces an error
|
||||
// when used, which we use as indicator that the driver was passed
|
||||
// through. We should have a cleaner way for this, but that would
|
||||
|
||||
@@ -28,7 +28,7 @@ func TestNoOverlayfsWarningsAboutUndefinedBehaviors(t *testing.T) {
|
||||
operation func(t *testing.T) error
|
||||
}{
|
||||
{name: "diff", operation: func(*testing.T) error {
|
||||
_, err := apiClient.ContainerDiff(ctx, cID)
|
||||
_, err := apiClient.ContainerDiff(ctx, cID, client.ContainerDiffOptions{})
|
||||
return err
|
||||
}},
|
||||
{name: "export", operation: func(*testing.T) error {
|
||||
|
||||
@@ -100,7 +100,10 @@ func TestDaemonRestartKillContainers(t *testing.T) {
|
||||
Interval: 60 * time.Second,
|
||||
}
|
||||
}
|
||||
resp, err := apiClient.ContainerCreate(ctx, &config, &hostConfig, nil, nil, "")
|
||||
resp, err := apiClient.ContainerCreate(ctx, client.ContainerCreateOptions{
|
||||
Config: &config,
|
||||
HostConfig: &hostConfig,
|
||||
})
|
||||
assert.NilError(t, err)
|
||||
defer apiClient.ContainerRemove(ctx, resp.ID, client.ContainerRemoveOptions{Force: true})
|
||||
|
||||
|
||||
@@ -55,10 +55,13 @@ func TestGraphDriverPersistence(t *testing.T) {
|
||||
assert.Check(t, info.DriverStatus[0][1] != "io.containerd.snapshotter.v1")
|
||||
prevDriver := info.Driver
|
||||
|
||||
containerResp, err := c.ContainerCreate(ctx, &containertypes.Config{
|
||||
Image: testImage,
|
||||
Cmd: []string{"echo", "test"},
|
||||
}, nil, nil, nil, "test-container")
|
||||
containerResp, err := c.ContainerCreate(ctx, client.ContainerCreateOptions{
|
||||
Config: &containertypes.Config{
|
||||
Image: testImage,
|
||||
Cmd: []string{"echo", "test"},
|
||||
},
|
||||
ContainerName: "test-container",
|
||||
})
|
||||
assert.NilError(t, err, "Failed to create container")
|
||||
|
||||
containerID := containerResp.ID
|
||||
@@ -141,7 +144,7 @@ func TestInspectGraphDriverAPIBC(t *testing.T) {
|
||||
}
|
||||
|
||||
const testImage = "busybox:latest"
|
||||
ctr, err := c.ContainerCreate(ctx, &containertypes.Config{Image: testImage}, nil, nil, nil, "test-container")
|
||||
ctr, err := c.ContainerCreate(ctx, client.ContainerCreateOptions{Image: testImage, Name: "test-container"})
|
||||
assert.NilError(t, err)
|
||||
defer func() { _ = c.ContainerRemove(ctx, ctr.ID, client.ContainerRemoveOptions{Force: true}) }()
|
||||
|
||||
|
||||
@@ -55,7 +55,13 @@ func NewTestConfig(ops ...func(*TestContainerConfig)) *TestContainerConfig {
|
||||
func Create(ctx context.Context, t *testing.T, apiClient client.APIClient, ops ...func(*TestContainerConfig)) string {
|
||||
t.Helper()
|
||||
config := NewTestConfig(ops...)
|
||||
c, err := apiClient.ContainerCreate(ctx, config.Config, config.HostConfig, config.NetworkingConfig, config.Platform, config.Name)
|
||||
c, err := apiClient.ContainerCreate(ctx, client.ContainerCreateOptions{
|
||||
Config: config.Config,
|
||||
HostConfig: config.HostConfig,
|
||||
NetworkingConfig: config.NetworkingConfig,
|
||||
Platform: config.Platform,
|
||||
ContainerName: config.Name,
|
||||
})
|
||||
assert.NilError(t, err)
|
||||
|
||||
return c.ID
|
||||
@@ -67,8 +73,14 @@ func Create(ctx context.Context, t *testing.T, apiClient client.APIClient, ops .
|
||||
//
|
||||
// ctr, err := container.CreateFromConfig(ctx, apiClient, container.NewTestConfig(container.WithAutoRemove))
|
||||
// assert.Check(t, err)
|
||||
func CreateFromConfig(ctx context.Context, apiClient client.APIClient, config *TestContainerConfig) (container.CreateResponse, error) {
|
||||
return apiClient.ContainerCreate(ctx, config.Config, config.HostConfig, config.NetworkingConfig, config.Platform, config.Name)
|
||||
func CreateFromConfig(ctx context.Context, apiClient client.APIClient, config *TestContainerConfig) (client.ContainerCreateResult, error) {
|
||||
return apiClient.ContainerCreate(ctx, client.ContainerCreateOptions{
|
||||
Config: config.Config,
|
||||
HostConfig: config.HostConfig,
|
||||
NetworkingConfig: config.NetworkingConfig,
|
||||
Platform: config.Platform,
|
||||
ContainerName: config.Name,
|
||||
})
|
||||
}
|
||||
|
||||
// Run creates and start a container with the specified options
|
||||
@@ -108,7 +120,7 @@ func RunAttach(ctx context.Context, t *testing.T, apiClient client.APIClient, op
|
||||
err = apiClient.ContainerStart(ctx, id, client.ContainerStartOptions{})
|
||||
assert.NilError(t, err)
|
||||
|
||||
s, err := demultiplexStreams(ctx, aresp)
|
||||
s, err := demultiplexStreams(ctx, aresp.HijackedResponse)
|
||||
if !errors.Is(err, context.DeadlineExceeded) && !errors.Is(err, context.Canceled) {
|
||||
assert.NilError(t, err)
|
||||
}
|
||||
|
||||
@@ -963,7 +963,13 @@ func TestEmptyPortBindingsBC(t *testing.T) {
|
||||
config := ctr.NewTestConfig(ctr.WithCmd("top"),
|
||||
ctr.WithExposedPorts("80/tcp"),
|
||||
ctr.WithPortMap(networktypes.PortMap{networktypes.MustParsePort("80/tcp"): pbs}))
|
||||
c, err := apiClient.ContainerCreate(ctx, config.Config, config.HostConfig, config.NetworkingConfig, config.Platform, config.Name)
|
||||
c, err := apiClient.ContainerCreate(ctx, client.ContainerCreateOptions{
|
||||
Config: config.Config,
|
||||
HostConfig: config.HostConfig,
|
||||
NetworkingConfig: config.NetworkingConfig,
|
||||
Platform: config.Platform,
|
||||
ContainerName: config.Name,
|
||||
})
|
||||
assert.NilError(t, err)
|
||||
defer apiClient.ContainerRemove(ctx, c.ID, client.ContainerRemoveOptions{Force: true})
|
||||
|
||||
|
||||
@@ -54,13 +54,12 @@ func TestReadPluginNoRead(t *testing.T) {
|
||||
ctx := testutil.StartSpan(ctx, t)
|
||||
d.Start(t, append([]string{"--iptables=false", "--ip6tables=false"}, test.dOpts...)...)
|
||||
defer d.Stop(t)
|
||||
c, err := apiclient.ContainerCreate(ctx,
|
||||
cfg,
|
||||
&container.HostConfig{LogConfig: container.LogConfig{Type: "test"}},
|
||||
nil,
|
||||
nil,
|
||||
"",
|
||||
)
|
||||
c, err := apiclient.ContainerCreate(ctx, client.ContainerCreateOptions{
|
||||
Config: cfg,
|
||||
HostConfig: &container.HostConfig{
|
||||
LogConfig: container.LogConfig{Type: "test"},
|
||||
},
|
||||
})
|
||||
assert.Assert(t, err)
|
||||
defer apiclient.ContainerRemove(ctx, c.ID, client.ContainerRemoveOptions{Force: true})
|
||||
|
||||
|
||||
@@ -80,7 +80,12 @@ func TestRunMountVolumeSubdir(t *testing.T) {
|
||||
}
|
||||
|
||||
ctrName := strings.ReplaceAll(t.Name(), "/", "_")
|
||||
create, creatErr := apiClient.ContainerCreate(ctx, &cfg, &hostCfg, &network.NetworkingConfig{}, nil, ctrName)
|
||||
create, creatErr := apiClient.ContainerCreate(ctx, client.ContainerCreateOptions{
|
||||
Config: &cfg,
|
||||
HostConfig: &hostCfg,
|
||||
NetworkingConfig: &network.NetworkingConfig{},
|
||||
ContainerName: ctrName,
|
||||
})
|
||||
id := create.ID
|
||||
if id != "" {
|
||||
defer apiClient.ContainerRemove(ctx, id, client.ContainerRemoveOptions{Force: true})
|
||||
@@ -175,7 +180,12 @@ func TestRunMountImage(t *testing.T) {
|
||||
}
|
||||
|
||||
ctrName := strings.ReplaceAll(t.Name(), "/", "_")
|
||||
create, creatErr := apiClient.ContainerCreate(ctx, &cfg, &hostCfg, &network.NetworkingConfig{}, nil, ctrName)
|
||||
create, creatErr := apiClient.ContainerCreate(ctx, client.ContainerCreateOptions{
|
||||
Config: &cfg,
|
||||
HostConfig: &hostCfg,
|
||||
NetworkingConfig: &network.NetworkingConfig{},
|
||||
ContainerName: ctrName,
|
||||
})
|
||||
id := create.ID
|
||||
if id != "" {
|
||||
defer container.Remove(ctx, t, apiClient, id, client.ContainerRemoveOptions{Force: true})
|
||||
|
||||
@@ -154,10 +154,11 @@ COPY . /static`); err != nil {
|
||||
assert.NilError(t, err)
|
||||
|
||||
// Start the container
|
||||
b, err := c.ContainerCreate(context.Background(),
|
||||
&containertypes.Config{Image: imgName},
|
||||
&containertypes.HostConfig{PublishAllPorts: true},
|
||||
nil, nil, ctrName)
|
||||
b, err := c.ContainerCreate(context.Background(), client.ContainerCreateOptions{
|
||||
Config: &containertypes.Config{Image: imgName},
|
||||
HostConfig: &containertypes.HostConfig{PublishAllPorts: true},
|
||||
ContainerName: ctrName,
|
||||
})
|
||||
assert.NilError(t, err)
|
||||
err = c.ContainerStart(context.Background(), b.ID, client.ContainerStartOptions{})
|
||||
assert.NilError(t, err)
|
||||
|
||||
9
vendor/github.com/moby/moby/client/client_interfaces.go
generated
vendored
9
vendor/github.com/moby/moby/client/client_interfaces.go
generated
vendored
@@ -12,7 +12,6 @@ import (
|
||||
"github.com/moby/moby/api/types/registry"
|
||||
"github.com/moby/moby/api/types/swarm"
|
||||
"github.com/moby/moby/api/types/system"
|
||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
)
|
||||
|
||||
// APIClient is an interface that clients that talk with a docker server must implement.
|
||||
@@ -58,10 +57,10 @@ type HijackDialer interface {
|
||||
|
||||
// ContainerAPIClient defines API client methods for the containers
|
||||
type ContainerAPIClient interface {
|
||||
ContainerAttach(ctx context.Context, container string, options ContainerAttachOptions) (HijackedResponse, error)
|
||||
ContainerCommit(ctx context.Context, container string, options ContainerCommitOptions) (container.CommitResponse, error)
|
||||
ContainerCreate(ctx context.Context, config *container.Config, hostConfig *container.HostConfig, networkingConfig *network.NetworkingConfig, platform *ocispec.Platform, containerName string) (container.CreateResponse, error)
|
||||
ContainerDiff(ctx context.Context, container string) ([]container.FilesystemChange, error)
|
||||
ContainerAttach(ctx context.Context, container string, options ContainerAttachOptions) (ContainerAttachResult, error)
|
||||
ContainerCommit(ctx context.Context, container string, options ContainerCommitOptions) (ContainerCommitResult, error)
|
||||
ContainerCreate(ctx context.Context, options ContainerCreateOptions) (ContainerCreateResult, error)
|
||||
ContainerDiff(ctx context.Context, container string, options ContainerDiffOptions) (ContainerDiffResult, error)
|
||||
ExecAPIClient
|
||||
ContainerExport(ctx context.Context, container string) (io.ReadCloser, error)
|
||||
ContainerInspect(ctx context.Context, container string) (container.InspectResponse, error)
|
||||
|
||||
16
vendor/github.com/moby/moby/client/container_attach.go
generated
vendored
16
vendor/github.com/moby/moby/client/container_attach.go
generated
vendored
@@ -16,6 +16,11 @@ type ContainerAttachOptions struct {
|
||||
Logs bool
|
||||
}
|
||||
|
||||
// ContainerAttachResult is the result from attaching to a container.
|
||||
type ContainerAttachResult struct {
|
||||
HijackedResponse
|
||||
}
|
||||
|
||||
// ContainerAttach attaches a connection to a container in the server.
|
||||
// It returns a [HijackedResponse] with the hijacked connection
|
||||
// and a reader to get output. It's up to the called to close
|
||||
@@ -44,10 +49,10 @@ type ContainerAttachOptions struct {
|
||||
// [stdcopy.StdType]: https://pkg.go.dev/github.com/moby/moby/api/pkg/stdcopy#StdType
|
||||
// [Stdout]: https://pkg.go.dev/github.com/moby/moby/api/pkg/stdcopy#Stdout
|
||||
// [Stderr]: https://pkg.go.dev/github.com/moby/moby/api/pkg/stdcopy#Stderr
|
||||
func (cli *Client) ContainerAttach(ctx context.Context, containerID string, options ContainerAttachOptions) (HijackedResponse, error) {
|
||||
func (cli *Client) ContainerAttach(ctx context.Context, containerID string, options ContainerAttachOptions) (ContainerAttachResult, error) {
|
||||
containerID, err := trimID("container", containerID)
|
||||
if err != nil {
|
||||
return HijackedResponse{}, err
|
||||
return ContainerAttachResult{}, err
|
||||
}
|
||||
|
||||
query := url.Values{}
|
||||
@@ -70,7 +75,12 @@ func (cli *Client) ContainerAttach(ctx context.Context, containerID string, opti
|
||||
query.Set("logs", "1")
|
||||
}
|
||||
|
||||
return cli.postHijacked(ctx, "/containers/"+containerID+"/attach", query, nil, http.Header{
|
||||
hijacked, err := cli.postHijacked(ctx, "/containers/"+containerID+"/attach", query, nil, http.Header{
|
||||
"Content-Type": {"text/plain"},
|
||||
})
|
||||
if err != nil {
|
||||
return ContainerAttachResult{}, err
|
||||
}
|
||||
|
||||
return ContainerAttachResult{HijackedResponse: hijacked}, nil
|
||||
}
|
||||
|
||||
17
vendor/github.com/moby/moby/client/container_commit.go
generated
vendored
17
vendor/github.com/moby/moby/client/container_commit.go
generated
vendored
@@ -20,22 +20,27 @@ type ContainerCommitOptions struct {
|
||||
Config *container.Config
|
||||
}
|
||||
|
||||
// ContainerCommitResult is the result from committing a container.
|
||||
type ContainerCommitResult struct {
|
||||
ID string
|
||||
}
|
||||
|
||||
// ContainerCommit applies changes to a container and creates a new tagged image.
|
||||
func (cli *Client) ContainerCommit(ctx context.Context, containerID string, options ContainerCommitOptions) (container.CommitResponse, error) {
|
||||
func (cli *Client) ContainerCommit(ctx context.Context, containerID string, options ContainerCommitOptions) (ContainerCommitResult, error) {
|
||||
containerID, err := trimID("container", containerID)
|
||||
if err != nil {
|
||||
return container.CommitResponse{}, err
|
||||
return ContainerCommitResult{}, err
|
||||
}
|
||||
|
||||
var repository, tag string
|
||||
if options.Reference != "" {
|
||||
ref, err := reference.ParseNormalizedNamed(options.Reference)
|
||||
if err != nil {
|
||||
return container.CommitResponse{}, err
|
||||
return ContainerCommitResult{}, err
|
||||
}
|
||||
|
||||
if _, ok := ref.(reference.Digested); ok {
|
||||
return container.CommitResponse{}, errors.New("refusing to create a tag with a digest reference")
|
||||
return ContainerCommitResult{}, errors.New("refusing to create a tag with a digest reference")
|
||||
}
|
||||
ref = reference.TagNameOnly(ref)
|
||||
|
||||
@@ -62,9 +67,9 @@ func (cli *Client) ContainerCommit(ctx context.Context, containerID string, opti
|
||||
resp, err := cli.post(ctx, "/commit", query, options.Config, nil)
|
||||
defer ensureReaderClosed(resp)
|
||||
if err != nil {
|
||||
return response, err
|
||||
return ContainerCommitResult{}, err
|
||||
}
|
||||
|
||||
err = json.NewDecoder(resp.Body).Decode(&response)
|
||||
return response, err
|
||||
return ContainerCommitResult{ID: response.ID}, err
|
||||
}
|
||||
|
||||
31
vendor/github.com/moby/moby/client/container_create.go
generated
vendored
31
vendor/github.com/moby/moby/client/container_create.go
generated
vendored
@@ -10,49 +10,48 @@ import (
|
||||
|
||||
cerrdefs "github.com/containerd/errdefs"
|
||||
"github.com/moby/moby/api/types/container"
|
||||
"github.com/moby/moby/api/types/network"
|
||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
)
|
||||
|
||||
// ContainerCreate creates a new container based on 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, platform *ocispec.Platform, containerName string) (container.CreateResponse, error) {
|
||||
if config == nil {
|
||||
return container.CreateResponse{}, cerrdefs.ErrInvalidArgument.WithMessage("config is nil")
|
||||
func (cli *Client) ContainerCreate(ctx context.Context, options ContainerCreateOptions) (ContainerCreateResult, error) {
|
||||
if options.Config == nil {
|
||||
return ContainerCreateResult{}, cerrdefs.ErrInvalidArgument.WithMessage("config is nil")
|
||||
}
|
||||
|
||||
var response container.CreateResponse
|
||||
|
||||
if hostConfig != nil {
|
||||
hostConfig.CapAdd = normalizeCapabilities(hostConfig.CapAdd)
|
||||
hostConfig.CapDrop = normalizeCapabilities(hostConfig.CapDrop)
|
||||
if options.HostConfig != nil {
|
||||
options.HostConfig.CapAdd = normalizeCapabilities(options.HostConfig.CapAdd)
|
||||
options.HostConfig.CapDrop = normalizeCapabilities(options.HostConfig.CapDrop)
|
||||
}
|
||||
|
||||
query := url.Values{}
|
||||
if platform != nil {
|
||||
if p := formatPlatform(*platform); p != "unknown" {
|
||||
if options.Platform != nil {
|
||||
if p := formatPlatform(*options.Platform); p != "unknown" {
|
||||
query.Set("platform", p)
|
||||
}
|
||||
}
|
||||
|
||||
if containerName != "" {
|
||||
query.Set("name", containerName)
|
||||
if options.ContainerName != "" {
|
||||
query.Set("name", options.ContainerName)
|
||||
}
|
||||
|
||||
body := container.CreateRequest{
|
||||
Config: config,
|
||||
HostConfig: hostConfig,
|
||||
NetworkingConfig: networkingConfig,
|
||||
Config: options.Config,
|
||||
HostConfig: options.HostConfig,
|
||||
NetworkingConfig: options.NetworkingConfig,
|
||||
}
|
||||
|
||||
resp, err := cli.post(ctx, "/containers/create", query, body, nil)
|
||||
defer ensureReaderClosed(resp)
|
||||
if err != nil {
|
||||
return response, err
|
||||
return ContainerCreateResult{}, err
|
||||
}
|
||||
|
||||
err = json.NewDecoder(resp.Body).Decode(&response)
|
||||
return response, err
|
||||
return ContainerCreateResult{ID: response.ID, Warnings: response.Warnings}, err
|
||||
}
|
||||
|
||||
// formatPlatform returns a formatted string representing platform (e.g., "linux/arm/v7").
|
||||
|
||||
22
vendor/github.com/moby/moby/client/container_create_opts.go
generated
vendored
Normal file
22
vendor/github.com/moby/moby/client/container_create_opts.go
generated
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
package client
|
||||
|
||||
import (
|
||||
"github.com/moby/moby/api/types/container"
|
||||
"github.com/moby/moby/api/types/network"
|
||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
)
|
||||
|
||||
// ContainerCreateOptions holds parameters to create a container.
|
||||
type ContainerCreateOptions struct {
|
||||
Config *container.Config
|
||||
HostConfig *container.HostConfig
|
||||
NetworkingConfig *network.NetworkingConfig
|
||||
Platform *ocispec.Platform
|
||||
ContainerName string
|
||||
}
|
||||
|
||||
// ContainerCreateResult is the result from creating a container.
|
||||
type ContainerCreateResult struct {
|
||||
ID string
|
||||
Warnings []string
|
||||
}
|
||||
10
vendor/github.com/moby/moby/client/container_diff.go
generated
vendored
10
vendor/github.com/moby/moby/client/container_diff.go
generated
vendored
@@ -9,22 +9,22 @@ import (
|
||||
)
|
||||
|
||||
// ContainerDiff shows differences in a container filesystem since it was started.
|
||||
func (cli *Client) ContainerDiff(ctx context.Context, containerID string) ([]container.FilesystemChange, error) {
|
||||
func (cli *Client) ContainerDiff(ctx context.Context, containerID string, options ContainerDiffOptions) (ContainerDiffResult, error) {
|
||||
containerID, err := trimID("container", containerID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return ContainerDiffResult{}, err
|
||||
}
|
||||
|
||||
resp, err := cli.get(ctx, "/containers/"+containerID+"/changes", url.Values{}, nil)
|
||||
defer ensureReaderClosed(resp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return ContainerDiffResult{}, err
|
||||
}
|
||||
|
||||
var changes []container.FilesystemChange
|
||||
err = json.NewDecoder(resp.Body).Decode(&changes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return ContainerDiffResult{}, err
|
||||
}
|
||||
return changes, err
|
||||
return ContainerDiffResult{Changes: changes}, err
|
||||
}
|
||||
|
||||
13
vendor/github.com/moby/moby/client/container_diff_opts.go
generated
vendored
Normal file
13
vendor/github.com/moby/moby/client/container_diff_opts.go
generated
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
package client
|
||||
|
||||
import "github.com/moby/moby/api/types/container"
|
||||
|
||||
// ContainerDiffOptions holds parameters to show differences in a container filesystem.
|
||||
type ContainerDiffOptions struct {
|
||||
// Currently no options, but this allows for future extensibility
|
||||
}
|
||||
|
||||
// ContainerDiffResult is the result from showing differences in a container filesystem.
|
||||
type ContainerDiffResult struct {
|
||||
Changes []container.FilesystemChange
|
||||
}
|
||||
Reference in New Issue
Block a user