mirror of
https://github.com/moby/moby.git
synced 2026-01-11 18:51:37 +00:00
client: wrap volume create api options with client options
Signed-off-by: Austin Vazquez <austin.vazquez@docker.com>
This commit is contained in:
@@ -14,7 +14,6 @@ import (
|
||||
"github.com/moby/moby/api/types/registry"
|
||||
"github.com/moby/moby/api/types/swarm"
|
||||
"github.com/moby/moby/api/types/system"
|
||||
"github.com/moby/moby/api/types/volume"
|
||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
)
|
||||
|
||||
@@ -195,7 +194,7 @@ type SystemAPIClient interface {
|
||||
|
||||
// VolumeAPIClient defines API client methods for the volumes
|
||||
type VolumeAPIClient interface {
|
||||
VolumeCreate(ctx context.Context, options volume.CreateOptions) (volume.Volume, error)
|
||||
VolumeCreate(ctx context.Context, options VolumeCreateOptions) (VolumeCreateResult, error)
|
||||
VolumeInspect(ctx context.Context, volumeID string) (VolumeInspectResult, error)
|
||||
VolumeInspectWithRaw(ctx context.Context, volumeID string) (VolumeInspectResult, []byte, error)
|
||||
VolumeList(ctx context.Context, options VolumeListOptions) (VolumeListResult, error)
|
||||
|
||||
@@ -7,15 +7,36 @@ import (
|
||||
"github.com/moby/moby/api/types/volume"
|
||||
)
|
||||
|
||||
// VolumeCreateOptions specifies the options to create a volume.
|
||||
type VolumeCreateOptions struct {
|
||||
Name string
|
||||
Driver string
|
||||
DriverOpts map[string]string
|
||||
Labels map[string]string
|
||||
ClusterVolumeSpec *volume.ClusterVolumeSpec
|
||||
}
|
||||
|
||||
// VolumeCreateResult is the result of a volume creation.
|
||||
type VolumeCreateResult struct {
|
||||
Volume volume.Volume
|
||||
}
|
||||
|
||||
// VolumeCreate creates a volume in the docker host.
|
||||
func (cli *Client) VolumeCreate(ctx context.Context, options volume.CreateOptions) (volume.Volume, error) {
|
||||
resp, err := cli.post(ctx, "/volumes/create", nil, options, nil)
|
||||
func (cli *Client) VolumeCreate(ctx context.Context, options VolumeCreateOptions) (VolumeCreateResult, error) {
|
||||
createRequest := volume.CreateOptions{
|
||||
Name: options.Name,
|
||||
Driver: options.Driver,
|
||||
DriverOpts: options.DriverOpts,
|
||||
Labels: options.Labels,
|
||||
ClusterVolumeSpec: options.ClusterVolumeSpec,
|
||||
}
|
||||
resp, err := cli.post(ctx, "/volumes/create", nil, createRequest, nil)
|
||||
defer ensureReaderClosed(resp)
|
||||
if err != nil {
|
||||
return volume.Volume{}, err
|
||||
return VolumeCreateResult{}, err
|
||||
}
|
||||
|
||||
var vol volume.Volume
|
||||
err = json.NewDecoder(resp.Body).Decode(&vol)
|
||||
return vol, err
|
||||
var v volume.Volume
|
||||
err = json.NewDecoder(resp.Body).Decode(&v)
|
||||
return VolumeCreateResult{Volume: v}, err
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ func TestVolumeCreateError(t *testing.T) {
|
||||
client, err := NewClientWithOpts(WithMockClient(errorMock(http.StatusInternalServerError, "Server error")))
|
||||
assert.NilError(t, err)
|
||||
|
||||
_, err = client.VolumeCreate(context.Background(), volume.CreateOptions{})
|
||||
_, err = client.VolumeCreate(context.Background(), VolumeCreateOptions{})
|
||||
assert.Check(t, is.ErrorType(err, cerrdefs.IsInternal))
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ func TestVolumeCreate(t *testing.T) {
|
||||
}))
|
||||
assert.NilError(t, err)
|
||||
|
||||
vol, err := client.VolumeCreate(context.Background(), volume.CreateOptions{
|
||||
res, err := client.VolumeCreate(context.Background(), VolumeCreateOptions{
|
||||
Name: "myvolume",
|
||||
Driver: "mydriver",
|
||||
DriverOpts: map[string]string{
|
||||
@@ -53,7 +53,8 @@ func TestVolumeCreate(t *testing.T) {
|
||||
},
|
||||
})
|
||||
assert.NilError(t, err)
|
||||
assert.Check(t, is.Equal(vol.Name, "volume"))
|
||||
assert.Check(t, is.Equal(vol.Driver, "local"))
|
||||
assert.Check(t, is.Equal(vol.Mountpoint, "mountpoint"))
|
||||
v := res.Volume
|
||||
assert.Check(t, is.Equal(v.Name, "volume"))
|
||||
assert.Check(t, is.Equal(v.Driver, "local"))
|
||||
assert.Check(t, is.Equal(v.Mountpoint, "mountpoint"))
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@ import (
|
||||
"github.com/moby/moby/api/pkg/stdcopy"
|
||||
containertypes "github.com/moby/moby/api/types/container"
|
||||
"github.com/moby/moby/api/types/mount"
|
||||
"github.com/moby/moby/api/types/volume"
|
||||
"github.com/moby/moby/client"
|
||||
"github.com/moby/moby/v2/daemon/config"
|
||||
"github.com/moby/moby/v2/integration/internal/container"
|
||||
@@ -551,7 +550,7 @@ func testLiveRestoreVolumeReferences(t *testing.T) {
|
||||
t.Run(string(policy), func(t *testing.T) {
|
||||
ctx := testutil.StartSpan(ctx, t)
|
||||
volName := "test-live-restore-volume-references-" + string(policy)
|
||||
_, err := c.VolumeCreate(ctx, volume.CreateOptions{Name: volName})
|
||||
_, err := c.VolumeCreate(ctx, client.VolumeCreateOptions{Name: volName})
|
||||
assert.NilError(t, err)
|
||||
|
||||
// Create a container that uses the volume
|
||||
@@ -586,7 +585,7 @@ func testLiveRestoreVolumeReferences(t *testing.T) {
|
||||
// Addresses https://github.com/moby/moby/issues/44422
|
||||
t.Run("local volume with mount options", func(t *testing.T) {
|
||||
ctx := testutil.StartSpan(ctx, t)
|
||||
v, err := c.VolumeCreate(ctx, volume.CreateOptions{
|
||||
res, err := c.VolumeCreate(ctx, client.VolumeCreateOptions{
|
||||
Driver: "local",
|
||||
Name: "test-live-restore-volume-references-local",
|
||||
DriverOpts: map[string]string{
|
||||
@@ -595,6 +594,7 @@ func testLiveRestoreVolumeReferences(t *testing.T) {
|
||||
},
|
||||
})
|
||||
assert.NilError(t, err)
|
||||
v := res.Volume
|
||||
m := mount.Mount{
|
||||
Type: mount.TypeVolume,
|
||||
Source: v.Name,
|
||||
|
||||
@@ -8,7 +8,6 @@ import (
|
||||
"io"
|
||||
"testing"
|
||||
|
||||
"github.com/moby/moby/api/types/volume"
|
||||
"github.com/moby/moby/client"
|
||||
"github.com/moby/moby/v2/integration/internal/container"
|
||||
"github.com/moby/moby/v2/integration/internal/requirement"
|
||||
@@ -67,7 +66,7 @@ func TestAuthZPluginV2Disable(t *testing.T) {
|
||||
d.Restart(t, "--authorization-plugin="+authzPluginNameWithTag)
|
||||
d.LoadBusybox(ctx, t)
|
||||
|
||||
_, err = c.VolumeCreate(ctx, volume.CreateOptions{Driver: "local"})
|
||||
_, err = c.VolumeCreate(ctx, client.VolumeCreateOptions{Driver: "local"})
|
||||
assert.Assert(t, err != nil)
|
||||
assert.ErrorContains(t, err, fmt.Sprintf("Error response from daemon: plugin %s failed with error:", authzPluginNameWithTag))
|
||||
|
||||
@@ -76,7 +75,7 @@ func TestAuthZPluginV2Disable(t *testing.T) {
|
||||
assert.NilError(t, err)
|
||||
|
||||
// now test to see if the docker api works.
|
||||
_, err = c.VolumeCreate(ctx, volume.CreateOptions{Driver: "local"})
|
||||
_, err = c.VolumeCreate(ctx, client.VolumeCreateOptions{Driver: "local"})
|
||||
assert.NilError(t, err)
|
||||
}
|
||||
|
||||
@@ -93,7 +92,7 @@ func TestAuthZPluginV2RejectVolumeRequests(t *testing.T) {
|
||||
// restart the daemon with the plugin
|
||||
d.Restart(t, "--authorization-plugin="+authzPluginNameWithTag)
|
||||
|
||||
_, err = c.VolumeCreate(ctx, volume.CreateOptions{Driver: "local"})
|
||||
_, err = c.VolumeCreate(ctx, client.VolumeCreateOptions{Driver: "local"})
|
||||
assert.Assert(t, err != nil)
|
||||
assert.ErrorContains(t, err, fmt.Sprintf("Error response from daemon: plugin %s failed with error:", authzPluginNameWithTag))
|
||||
|
||||
|
||||
@@ -10,7 +10,6 @@ import (
|
||||
|
||||
"github.com/moby/moby/api/types/events"
|
||||
"github.com/moby/moby/api/types/mount"
|
||||
"github.com/moby/moby/api/types/volume"
|
||||
"github.com/moby/moby/client"
|
||||
"github.com/moby/moby/v2/integration/internal/container"
|
||||
"github.com/moby/moby/v2/internal/testutil/request"
|
||||
@@ -101,7 +100,7 @@ func TestEventsVolumeCreate(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
_, err := apiClient.VolumeCreate(ctx, volume.CreateOptions{Name: volName})
|
||||
_, err := apiClient.VolumeCreate(ctx, client.VolumeCreateOptions{Name: volName})
|
||||
assert.NilError(t, err)
|
||||
|
||||
filter := make(client.Filters).
|
||||
|
||||
@@ -13,7 +13,6 @@ import (
|
||||
"github.com/moby/moby/api/types/mount"
|
||||
"github.com/moby/moby/api/types/network"
|
||||
"github.com/moby/moby/api/types/versions"
|
||||
"github.com/moby/moby/api/types/volume"
|
||||
"github.com/moby/moby/client"
|
||||
"github.com/moby/moby/v2/daemon/volume/safepath"
|
||||
"github.com/moby/moby/v2/integration/internal/container"
|
||||
@@ -241,7 +240,7 @@ func setupTestVolume(t *testing.T, apiClient client.APIClient) string {
|
||||
err := apiClient.VolumeRemove(ctx, volumeName, client.VolumeRemoveOptions{Force: true})
|
||||
assert.NilError(t, err, "failed to clean volume")
|
||||
|
||||
_, err = apiClient.VolumeCreate(ctx, volume.CreateOptions{
|
||||
_, err = apiClient.VolumeCreate(ctx, client.VolumeCreateOptions{
|
||||
Name: volumeName,
|
||||
})
|
||||
assert.NilError(t, err, "failed to setup volume")
|
||||
|
||||
@@ -32,20 +32,21 @@ func TestVolumesCreateAndList(t *testing.T) {
|
||||
if testEnv.DaemonInfo.OSType == "windows" {
|
||||
name = strings.ToLower(name)
|
||||
}
|
||||
vol, err := apiClient.VolumeCreate(ctx, volume.CreateOptions{
|
||||
create, err := apiClient.VolumeCreate(ctx, client.VolumeCreateOptions{
|
||||
Name: name,
|
||||
})
|
||||
assert.NilError(t, err)
|
||||
namedV := create.Volume
|
||||
|
||||
expected := volume.Volume{
|
||||
// Ignore timestamp of CreatedAt
|
||||
CreatedAt: vol.CreatedAt,
|
||||
CreatedAt: namedV.CreatedAt,
|
||||
Driver: "local",
|
||||
Scope: "local",
|
||||
Name: name,
|
||||
Mountpoint: filepath.Join(testEnv.DaemonInfo.DockerRootDir, "volumes", name, "_data"),
|
||||
}
|
||||
assert.Check(t, is.DeepEqual(vol, expected, cmpopts.EquateEmpty()))
|
||||
assert.Check(t, is.DeepEqual(namedV, expected, cmpopts.EquateEmpty()))
|
||||
|
||||
res, err := apiClient.VolumeList(ctx, client.VolumeListOptions{})
|
||||
assert.NilError(t, err)
|
||||
@@ -54,7 +55,7 @@ func TestVolumesCreateAndList(t *testing.T) {
|
||||
|
||||
volumes := volList.Volumes[:0]
|
||||
for _, v := range volList.Volumes {
|
||||
if v.Name == vol.Name {
|
||||
if v.Name == namedV.Name {
|
||||
volumes = append(volumes, v)
|
||||
}
|
||||
}
|
||||
@@ -160,13 +161,14 @@ func TestVolumesInspect(t *testing.T) {
|
||||
apiClient := testEnv.APIClient()
|
||||
|
||||
now := time.Now()
|
||||
vol, err := apiClient.VolumeCreate(ctx, volume.CreateOptions{})
|
||||
create, err := apiClient.VolumeCreate(ctx, client.VolumeCreateOptions{})
|
||||
assert.NilError(t, err)
|
||||
v := create.Volume
|
||||
|
||||
inspected, err := apiClient.VolumeInspect(ctx, v.Name)
|
||||
assert.NilError(t, err)
|
||||
|
||||
inspected, err := apiClient.VolumeInspect(ctx, vol.Name)
|
||||
assert.NilError(t, err)
|
||||
|
||||
assert.Check(t, is.DeepEqual(inspected.Volume, vol, cmpopts.EquateEmpty()))
|
||||
assert.Check(t, is.DeepEqual(inspected.Volume, v, cmpopts.EquateEmpty()))
|
||||
|
||||
// comparing CreatedAt field time for the new volume to now. Truncate to 1 minute precision to avoid false positive
|
||||
createdAt, err := time.Parse(time.RFC3339, strings.TrimSpace(inspected.Volume.CreatedAt))
|
||||
@@ -178,7 +180,7 @@ func TestVolumesInspect(t *testing.T) {
|
||||
err = os.Chtimes(inspected.Volume.Mountpoint, modifiedAt, modifiedAt)
|
||||
assert.NilError(t, err)
|
||||
|
||||
inspected, err = apiClient.VolumeInspect(ctx, vol.Name)
|
||||
inspected, err = apiClient.VolumeInspect(ctx, v.Name)
|
||||
assert.NilError(t, err)
|
||||
|
||||
createdAt2, err := time.Parse(time.RFC3339, strings.TrimSpace(inspected.Volume.CreatedAt))
|
||||
@@ -261,45 +263,49 @@ func TestVolumePruneAnonymous(t *testing.T) {
|
||||
apiClient := testEnv.APIClient()
|
||||
|
||||
// Create an anonymous volume
|
||||
v, err := apiClient.VolumeCreate(ctx, volume.CreateOptions{})
|
||||
created, err := apiClient.VolumeCreate(ctx, client.VolumeCreateOptions{})
|
||||
assert.NilError(t, err)
|
||||
anonV := created.Volume
|
||||
|
||||
// Create a named volume
|
||||
vNamed, err := apiClient.VolumeCreate(ctx, volume.CreateOptions{
|
||||
created, err = apiClient.VolumeCreate(ctx, client.VolumeCreateOptions{
|
||||
Name: "test",
|
||||
})
|
||||
assert.NilError(t, err)
|
||||
namedV := created.Volume
|
||||
|
||||
// Prune anonymous volumes
|
||||
res, err := apiClient.VolumesPrune(ctx, client.VolumePruneOptions{})
|
||||
prune, err := apiClient.VolumesPrune(ctx, client.VolumePruneOptions{})
|
||||
assert.NilError(t, err)
|
||||
assert.Check(t, is.Equal(len(res.Report.VolumesDeleted), 1))
|
||||
assert.Check(t, is.Equal(res.Report.VolumesDeleted[0], v.Name))
|
||||
report := prune.Report
|
||||
assert.Check(t, is.Equal(len(report.VolumesDeleted), 1))
|
||||
assert.Check(t, is.Equal(report.VolumesDeleted[0], anonV.Name))
|
||||
|
||||
_, err = apiClient.VolumeInspect(ctx, vNamed.Name)
|
||||
_, err = apiClient.VolumeInspect(ctx, namedV.Name)
|
||||
assert.NilError(t, err)
|
||||
|
||||
// Prune all volumes
|
||||
_, err = apiClient.VolumeCreate(ctx, volume.CreateOptions{})
|
||||
_, err = apiClient.VolumeCreate(ctx, client.VolumeCreateOptions{})
|
||||
assert.NilError(t, err)
|
||||
res, err = apiClient.VolumesPrune(ctx, client.VolumePruneOptions{
|
||||
prune, err = apiClient.VolumesPrune(ctx, client.VolumePruneOptions{
|
||||
All: true,
|
||||
})
|
||||
assert.NilError(t, err)
|
||||
assert.Check(t, is.Equal(len(res.Report.VolumesDeleted), 2))
|
||||
assert.Check(t, is.Equal(len(prune.Report.VolumesDeleted), 2))
|
||||
|
||||
// Create a named volume and an anonymous volume, and prune all
|
||||
_, err = apiClient.VolumeCreate(ctx, volume.CreateOptions{})
|
||||
_, err = apiClient.VolumeCreate(ctx, client.VolumeCreateOptions{})
|
||||
assert.NilError(t, err)
|
||||
_, err = apiClient.VolumeCreate(ctx, volume.CreateOptions{Name: "test"})
|
||||
_, err = apiClient.VolumeCreate(ctx, client.VolumeCreateOptions{Name: "test"})
|
||||
assert.NilError(t, err)
|
||||
|
||||
res, err = apiClient.VolumesPrune(ctx, client.VolumePruneOptions{
|
||||
prune, err = apiClient.VolumesPrune(ctx, client.VolumePruneOptions{
|
||||
All: true,
|
||||
})
|
||||
|
||||
assert.NilError(t, err)
|
||||
assert.Check(t, is.Equal(len(res.Report.VolumesDeleted), 2))
|
||||
report = prune.Report
|
||||
assert.Check(t, is.Equal(len(report.VolumesDeleted), 2))
|
||||
|
||||
// Validate that older API versions still have the old behavior of pruning all local volumes
|
||||
clientOld, err := client.NewClientWithOpts(client.FromEnv, client.WithVersion("1.41"))
|
||||
@@ -307,16 +313,19 @@ func TestVolumePruneAnonymous(t *testing.T) {
|
||||
defer clientOld.Close()
|
||||
assert.Equal(t, clientOld.ClientVersion(), "1.41")
|
||||
|
||||
v, err = apiClient.VolumeCreate(ctx, volume.CreateOptions{})
|
||||
created, err = apiClient.VolumeCreate(ctx, client.VolumeCreateOptions{})
|
||||
assert.NilError(t, err)
|
||||
vNamed, err = apiClient.VolumeCreate(ctx, volume.CreateOptions{Name: "test-api141"})
|
||||
anonV = created.Volume
|
||||
created, err = apiClient.VolumeCreate(ctx, client.VolumeCreateOptions{Name: "test-api141"})
|
||||
assert.NilError(t, err)
|
||||
namedV = created.Volume
|
||||
|
||||
res, err = clientOld.VolumesPrune(ctx, client.VolumePruneOptions{})
|
||||
prune, err = clientOld.VolumesPrune(ctx, client.VolumePruneOptions{})
|
||||
assert.NilError(t, err)
|
||||
assert.Check(t, is.Equal(len(res.Report.VolumesDeleted), 2))
|
||||
assert.Check(t, is.Contains(res.Report.VolumesDeleted, v.Name))
|
||||
assert.Check(t, is.Contains(res.Report.VolumesDeleted, vNamed.Name))
|
||||
report = prune.Report
|
||||
assert.Check(t, is.Equal(len(report.VolumesDeleted), 2))
|
||||
assert.Check(t, is.Contains(report.VolumesDeleted, anonV.Name))
|
||||
assert.Check(t, is.Contains(report.VolumesDeleted, namedV.Name))
|
||||
}
|
||||
|
||||
func TestVolumePruneAnonFromImage(t *testing.T) {
|
||||
|
||||
3
vendor/github.com/moby/moby/client/client_interfaces.go
generated
vendored
3
vendor/github.com/moby/moby/client/client_interfaces.go
generated
vendored
@@ -14,7 +14,6 @@ import (
|
||||
"github.com/moby/moby/api/types/registry"
|
||||
"github.com/moby/moby/api/types/swarm"
|
||||
"github.com/moby/moby/api/types/system"
|
||||
"github.com/moby/moby/api/types/volume"
|
||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
)
|
||||
|
||||
@@ -195,7 +194,7 @@ type SystemAPIClient interface {
|
||||
|
||||
// VolumeAPIClient defines API client methods for the volumes
|
||||
type VolumeAPIClient interface {
|
||||
VolumeCreate(ctx context.Context, options volume.CreateOptions) (volume.Volume, error)
|
||||
VolumeCreate(ctx context.Context, options VolumeCreateOptions) (VolumeCreateResult, error)
|
||||
VolumeInspect(ctx context.Context, volumeID string) (VolumeInspectResult, error)
|
||||
VolumeInspectWithRaw(ctx context.Context, volumeID string) (VolumeInspectResult, []byte, error)
|
||||
VolumeList(ctx context.Context, options VolumeListOptions) (VolumeListResult, error)
|
||||
|
||||
33
vendor/github.com/moby/moby/client/volume_create.go
generated
vendored
33
vendor/github.com/moby/moby/client/volume_create.go
generated
vendored
@@ -7,15 +7,36 @@ import (
|
||||
"github.com/moby/moby/api/types/volume"
|
||||
)
|
||||
|
||||
// VolumeCreateOptions specifies the options to create a volume.
|
||||
type VolumeCreateOptions struct {
|
||||
Name string
|
||||
Driver string
|
||||
DriverOpts map[string]string
|
||||
Labels map[string]string
|
||||
ClusterVolumeSpec *volume.ClusterVolumeSpec
|
||||
}
|
||||
|
||||
// VolumeCreateResult is the result of a volume creation.
|
||||
type VolumeCreateResult struct {
|
||||
Volume volume.Volume
|
||||
}
|
||||
|
||||
// VolumeCreate creates a volume in the docker host.
|
||||
func (cli *Client) VolumeCreate(ctx context.Context, options volume.CreateOptions) (volume.Volume, error) {
|
||||
resp, err := cli.post(ctx, "/volumes/create", nil, options, nil)
|
||||
func (cli *Client) VolumeCreate(ctx context.Context, options VolumeCreateOptions) (VolumeCreateResult, error) {
|
||||
createRequest := volume.CreateOptions{
|
||||
Name: options.Name,
|
||||
Driver: options.Driver,
|
||||
DriverOpts: options.DriverOpts,
|
||||
Labels: options.Labels,
|
||||
ClusterVolumeSpec: options.ClusterVolumeSpec,
|
||||
}
|
||||
resp, err := cli.post(ctx, "/volumes/create", nil, createRequest, nil)
|
||||
defer ensureReaderClosed(resp)
|
||||
if err != nil {
|
||||
return volume.Volume{}, err
|
||||
return VolumeCreateResult{}, err
|
||||
}
|
||||
|
||||
var vol volume.Volume
|
||||
err = json.NewDecoder(resp.Body).Decode(&vol)
|
||||
return vol, err
|
||||
var v volume.Volume
|
||||
err = json.NewDecoder(resp.Body).Decode(&v)
|
||||
return VolumeCreateResult{Volume: v}, err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user