diff --git a/hack/make/.integration-test-helpers b/hack/make/.integration-test-helpers index d9b4cf15b5..af6e63f998 100644 --- a/hack/make/.integration-test-helpers +++ b/hack/make/.integration-test-helpers @@ -15,7 +15,7 @@ source "$SCRIPTDIR/make/.go-autogen" integration_api_dirs=${TEST_INTEGRATION_DIR:-"$( find ./integration -type d | - grep -vE '^(./integration($|/util|/internal|/testdata|/plugin$))')"} + grep -vE '^(./integration($|/util|/testdata|/plugin$))')"} run_test_integration() { [[ "$TESTFLAGS" != *-check.f* ]] && run_test_integration_suites diff --git a/integration/internal/api/container/container.go b/integration/internal/api/container/container.go deleted file mode 100644 index d65a9ea3b6..0000000000 --- a/integration/internal/api/container/container.go +++ /dev/null @@ -1,128 +0,0 @@ -package container - -import ( - "context" - "io" - "os" - "time" - - "github.com/docker/docker/api/types" - "github.com/docker/docker/api/types/container" - networktypes "github.com/docker/docker/api/types/network" - "github.com/docker/docker/client" -) - -// CreateVMemLabel creates a container with the supplied parameters -func CreateVMemLabel(client client.APIClient, v []string, memoryMB int, labels map[string]string, img string, cmd []string) (string, error) { - ctx := context.Background() - config := container.Config{ - Cmd: cmd, - Image: img, - Labels: labels, - } - hostConfig := container.HostConfig{ - Binds: v, - Resources: container.Resources{ - Memory: int64(memoryMB * 1024 * 1024), - }, - } - networkingConfig := networktypes.NetworkingConfig{} - name := "" - response, err := client.ContainerCreate(ctx, &config, &hostConfig, &networkingConfig, name) - - if err != nil { - return "", err - } - - return response.ID, nil -} - -// Run runs the command provided in the container image named -func Run(client client.APIClient, img string, cmd []string) (string, error) { - return RunV(client, []string{}, img, cmd) -} - -// RunV runs the command provided in the container image named with -// the equivalent of -v bind mounts -func RunV(client client.APIClient, v []string, img string, cmd []string) (string, error) { - return RunVMem(client, v, 0, img, cmd) -} - -// RunVMem runs the command provided in the container image named with -// the equivalent of -v bind mounts and a specified memory limit -func RunVMem(client client.APIClient, v []string, memoryMB int, img string, cmd []string) (string, error) { - return RunVMemLabel(client, v, memoryMB, map[string]string{}, img, cmd) -} - -// RunVLabel runs the command provided in the container image named -// with the equivalent of -v bind mounts and the specified labels -func RunVLabel(client client.APIClient, v []string, labels map[string]string, img string, cmd []string) (string, error) { - return RunVMemLabel(client, v, 0, labels, img, cmd) -} - -// RunVMemLabel runs the command provided in the container image named -// with the equivalent of -v bind mounts, a specified memory limit, -// and the specified labels -func RunVMemLabel(client client.APIClient, v []string, memoryMB int, labels map[string]string, img string, cmd []string) (string, error) { - containerID, err := CreateVMemLabel(client, v, memoryMB, labels, img, cmd) - if err != nil { - return "", err - } - - ctx := context.Background() - if err := client.ContainerStart(ctx, containerID, types.ContainerStartOptions{}); err != nil { - return "", err - } - - return containerID, nil -} - -// Wait waits until the named container has exited -func Wait(client client.APIClient, container string) (int64, error) { - resultC, errC := client.ContainerWait(context.Background(), container, "") - - select { - case result := <-resultC: - return result.StatusCode, nil - case err := <-errC: - return -1, err - } -} - -// Stop stops the named container -func Stop(client client.APIClient, container string) error { - timeout := time.Duration(10) * time.Second - ctx := context.Background() - return client.ContainerStop(ctx, container, &timeout) -} - -// Start starts the named container -func Start(client client.APIClient, container string) error { - ctx := context.Background() - return client.ContainerStart(ctx, container, types.ContainerStartOptions{}) -} - -// Kill kills the named container with SIGKILL -func Kill(client client.APIClient, container string) error { - ctx := context.Background() - return client.ContainerKill(ctx, container, "KILL") -} - -// Export exports a container's file system as a tarball -func Export(client client.APIClient, path, name string) error { - ctx := context.Background() - responseReader, err := client.ContainerExport(ctx, name) - if err != nil { - return err - } - defer responseReader.Close() - - file, err := os.Create(path) - if err != nil { - return err - } - defer file.Close() - - _, err = io.Copy(file, responseReader) - return err -} diff --git a/integration/internal/api/image/image.go b/integration/internal/api/image/image.go deleted file mode 100644 index 67ed7a0248..0000000000 --- a/integration/internal/api/image/image.go +++ /dev/null @@ -1,66 +0,0 @@ -package image - -import ( - "context" - "io" - "os" - - "github.com/docker/docker/api/types" - "github.com/docker/docker/client" -) - -// Save saves an image to a tarball names by path -func Save(client client.APIClient, path, image string) error { - ctx := context.Background() - responseReader, err := client.ImageSave(ctx, []string{image}) - if err != nil { - return err - } - defer responseReader.Close() - file, err := os.Create(path) - if err != nil { - return err - } - defer file.Close() - _, err = io.Copy(file, responseReader) - return err -} - -// Load loads an image from a tarball named by path -func Load(client client.APIClient, path string) error { - file, err := os.Open(path) - if err != nil { - return err - } - defer file.Close() - quiet := true - ctx := context.Background() - response, err := client.ImageLoad(ctx, file, quiet) - if err != nil { - return err - } - defer response.Body.Close() - return nil -} - -// Import imports the contents of a tarball named by path -func Import(client client.APIClient, path string) error { - file, err := os.Open(path) - if err != nil { - return err - } - defer file.Close() - options := types.ImageImportOptions{} - ref := "" - source := types.ImageImportSource{ - Source: file, - SourceName: "-", - } - ctx := context.Background() - responseReader, err := client.ImageImport(ctx, source, ref, options) - if err != nil { - return err - } - defer responseReader.Close() - return nil -} diff --git a/integration/internal/api/plugin/plugin.go b/integration/internal/api/plugin/plugin.go deleted file mode 100644 index cc771ec706..0000000000 --- a/integration/internal/api/plugin/plugin.go +++ /dev/null @@ -1,59 +0,0 @@ -package plugin - -import ( - "context" - "io/ioutil" - - "github.com/docker/docker/api/types" - "github.com/docker/docker/client" -) - -// InstallGrantAllPermissions installs the plugin named and grants it -// all permissions it may require -func InstallGrantAllPermissions(client client.APIClient, name string) error { - ctx := context.Background() - options := types.PluginInstallOptions{ - RemoteRef: name, - AcceptAllPermissions: true, - } - responseReader, err := client.PluginInstall(ctx, "", options) - if err != nil { - return err - } - defer responseReader.Close() - // we have to read the response out here because the client API - // actually starts a goroutine which we can only be sure has - // completed when we get EOF from reading responseBody - _, err = ioutil.ReadAll(responseReader) - return err -} - -// Enable enables the named plugin -func Enable(client client.APIClient, name string) error { - ctx := context.Background() - options := types.PluginEnableOptions{} - return client.PluginEnable(ctx, name, options) -} - -// Disable disables the named plugin -func Disable(client client.APIClient, name string) error { - ctx := context.Background() - options := types.PluginDisableOptions{} - return client.PluginDisable(ctx, name, options) -} - -// Rm removes the named plugin -func Rm(client client.APIClient, name string) error { - return remove(client, name, false) -} - -// RmF forces the removal of the named plugin -func RmF(client client.APIClient, name string) error { - return remove(client, name, true) -} - -func remove(client client.APIClient, name string, force bool) error { - ctx := context.Background() - options := types.PluginRemoveOptions{Force: force} - return client.PluginRemove(ctx, name, options) -} diff --git a/integration/internal/api/system/system.go b/integration/internal/api/system/system.go deleted file mode 100644 index 6983479636..0000000000 --- a/integration/internal/api/system/system.go +++ /dev/null @@ -1,45 +0,0 @@ -package system - -import ( - "context" - "testing" - "time" - - "github.com/docker/docker/api/types" - "github.com/docker/docker/api/types/events" - "github.com/docker/docker/client" - "github.com/docker/docker/internal/test/environment" - "github.com/stretchr/testify/require" -) - -// Time provides the current time on the daemon host -func Time(t *testing.T, client client.APIClient, testEnv *environment.Execution) time.Time { - if testEnv.IsLocalDaemon() { - return time.Now() - } - - ctx := context.Background() - info, err := client.Info(ctx) - require.Nil(t, err) - - dt, err := time.Parse(time.RFC3339Nano, info.SystemTime) - require.Nil(t, err, "invalid time format in GET /info response") - return dt -} - -// Version provides the version of the daemon -func Version(client client.APIClient) (types.Version, error) { - ctx := context.Background() - return client.ServerVersion(ctx) -} - -// EventsSince returns event and error streams since a provided time -func EventsSince(client client.APIClient, since string) (<-chan events.Message, <-chan error, func()) { - eventOptions := types.EventsOptions{ - Since: since, - } - ctx, cancel := context.WithCancel(context.Background()) - events, errs := client.Events(ctx, eventOptions) - - return events, errs, cancel -} diff --git a/integration/internal/api/volume/volume.go b/integration/internal/api/volume/volume.go deleted file mode 100644 index 3f07645f06..0000000000 --- a/integration/internal/api/volume/volume.go +++ /dev/null @@ -1,61 +0,0 @@ -package volume - -import ( - "context" - - "github.com/docker/docker/api/types" - "github.com/docker/docker/api/types/filters" - volumetypes "github.com/docker/docker/api/types/volume" - "github.com/docker/docker/client" -) - -// Create creates a volume using the named driver with the specified options -func Create(client client.APIClient, driver string, opts map[string]string) (string, error) { - volReq := volumetypes.VolumesCreateBody{ - Driver: driver, - DriverOpts: opts, - Name: "", - } - - ctx := context.Background() - vol, err := client.VolumeCreate(ctx, volReq) - if err != nil { - return "", err - } - return vol.Name, nil -} - -// Rm removes the volume named -func Rm(client client.APIClient, name string) error { - ctx := context.Background() - return client.VolumeRemove(ctx, name, false) -} - -// Ls lists the volumes available -func Ls(client client.APIClient) ([]string, error) { - ctx := context.Background() - volumes, err := client.VolumeList(ctx, filters.Args{}) - if err != nil { - return []string{}, err - } - - names := []string{} - for _, volume := range volumes.Volumes { - names = append(names, volume.Name) - } - - return names, nil -} - -// Prune removes all volumes not used by at least one container -func Prune(client client.APIClient) (types.VolumesPruneReport, error) { - ctx := context.Background() - - return client.VolumesPrune(ctx, filters.Args{}) -} - -// Inspect retrieves detailed information about the named volume -func Inspect(client client.APIClient, name string) (types.Volume, error) { - ctx := context.Background() - return client.VolumeInspect(ctx, name) -} diff --git a/integration/plugin/authz/authz_plugin_test.go b/integration/plugin/authz/authz_plugin_test.go index 49bb3e0d21..0f46d8f85a 100644 --- a/integration/plugin/authz/authz_plugin_test.go +++ b/integration/plugin/authz/authz_plugin_test.go @@ -18,11 +18,13 @@ import ( "testing" "time" + "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/container" eventtypes "github.com/docker/docker/api/types/events" - "github.com/docker/docker/integration/internal/api/container" - "github.com/docker/docker/integration/internal/api/image" - "github.com/docker/docker/integration/internal/api/system" + networktypes "github.com/docker/docker/api/types/network" + "github.com/docker/docker/client" "github.com/docker/docker/integration/util/request" + "github.com/docker/docker/internal/test/environment" "github.com/docker/docker/pkg/authorization" "github.com/gotestyourself/gotestyourself/skip" "github.com/stretchr/testify/require" @@ -90,13 +92,16 @@ func TestAuthZPluginAllowRequest(t *testing.T) { require.Nil(t, err) // Ensure command successful - id, err := container.Run(client, "busybox", []string{"top"}) + createResponse, err := client.ContainerCreate(context.Background(), &container.Config{Cmd: []string{"top"}, Image: "busybox"}, &container.HostConfig{}, &networktypes.NetworkingConfig{}, "") + require.Nil(t, err) + + err = client.ContainerStart(context.Background(), createResponse.ID, types.ContainerStartOptions{}) require.Nil(t, err) assertURIRecorded(t, ctrl.requestsURIs, "/containers/create") - assertURIRecorded(t, ctrl.requestsURIs, fmt.Sprintf("/containers/%s/start", id)) + assertURIRecorded(t, ctrl.requestsURIs, fmt.Sprintf("/containers/%s/start", createResponse.ID)) - _, err = system.Version(client) + _, err = client.ServerVersion(context.Background()) require.Nil(t, err) require.Equal(t, 1, ctrl.versionReqCount) require.Equal(t, 1, ctrl.versionResCount) @@ -127,7 +132,7 @@ func TestAuthZPluginTLS(t *testing.T) { client, err := request.NewTLSAPIClient(t, testDaemonHTTPSAddr, cacertPath, clientCertPath, clientKeyPath) require.Nil(t, err) - _, err = system.Version(client) + _, err = client.ServerVersion(context.Background()) require.Nil(t, err) require.Equal(t, "client", ctrl.reqUser) @@ -144,7 +149,7 @@ func TestAuthZPluginDenyRequest(t *testing.T) { require.Nil(t, err) // Ensure command is blocked - _, err = system.Version(client) + _, err = client.ServerVersion(context.Background()) require.NotNil(t, err) require.Equal(t, 1, ctrl.versionReqCount) require.Equal(t, 0, ctrl.versionResCount) @@ -186,7 +191,7 @@ func TestAuthZPluginDenyResponse(t *testing.T) { require.Nil(t, err) // Ensure command is blocked - _, err = system.Version(client) + _, err = client.ServerVersion(context.Background()) require.NotNil(t, err) require.Equal(t, 1, ctrl.versionReqCount) require.Equal(t, 1, ctrl.versionResCount) @@ -208,15 +213,19 @@ func TestAuthZPluginAllowEventStream(t *testing.T) { client, err := d.NewClient() require.Nil(t, err) - startTime := strconv.FormatInt(system.Time(t, client, testEnv).Unix(), 10) - events, errs, cancel := system.EventsSince(client, startTime) + startTime := strconv.FormatInt(systemTime(t, client, testEnv).Unix(), 10) + events, errs, cancel := systemEventsSince(client, startTime) defer cancel() // Create a container and wait for the creation events - id, err := container.Run(client, "busybox", []string{"top"}) + createResponse, err := client.ContainerCreate(context.Background(), &container.Config{Cmd: []string{"top"}, Image: "busybox"}, &container.HostConfig{}, &networktypes.NetworkingConfig{}, "") require.Nil(t, err) + + err = client.ContainerStart(context.Background(), createResponse.ID, types.ContainerStartOptions{}) + require.Nil(t, err) + for i := 0; i < 100; i++ { - c, err := client.ContainerInspect(context.Background(), id) + c, err := client.ContainerInspect(context.Background(), createResponse.ID) require.Nil(t, err) if c.State.Running { break @@ -232,7 +241,7 @@ func TestAuthZPluginAllowEventStream(t *testing.T) { for !created && !started { select { case event := <-events: - if event.Type == eventtypes.ContainerEventType && event.Actor.ID == id { + if event.Type == eventtypes.ContainerEventType && event.Actor.ID == createResponse.ID { if event.Action == "create" { created = true } @@ -255,7 +264,31 @@ func TestAuthZPluginAllowEventStream(t *testing.T) { // authorization plugin assertURIRecorded(t, ctrl.requestsURIs, "/events") assertURIRecorded(t, ctrl.requestsURIs, "/containers/create") - assertURIRecorded(t, ctrl.requestsURIs, fmt.Sprintf("/containers/%s/start", id)) + assertURIRecorded(t, ctrl.requestsURIs, fmt.Sprintf("/containers/%s/start", createResponse.ID)) +} + +func systemTime(t *testing.T, client client.APIClient, testEnv *environment.Execution) time.Time { + if testEnv.IsLocalDaemon() { + return time.Now() + } + + ctx := context.Background() + info, err := client.Info(ctx) + require.Nil(t, err) + + dt, err := time.Parse(time.RFC3339Nano, info.SystemTime) + require.Nil(t, err, "invalid time format in GET /info response") + return dt +} + +func systemEventsSince(client client.APIClient, since string) (<-chan eventtypes.Message, <-chan error, func()) { + eventOptions := types.EventsOptions{ + Since: since, + } + ctx, cancel := context.WithCancel(context.Background()) + events, errs := client.Events(ctx, eventOptions) + + return events, errs, cancel } func TestAuthZPluginErrorResponse(t *testing.T) { @@ -268,7 +301,7 @@ func TestAuthZPluginErrorResponse(t *testing.T) { require.Nil(t, err) // Ensure command is blocked - _, err = system.Version(client) + _, err = client.ServerVersion(context.Background()) require.NotNil(t, err) require.Equal(t, fmt.Sprintf("Error response from daemon: plugin %s failed with error: %s: %s", testAuthZPlugin, authorization.AuthZApiResponse, errorMessage), err.Error()) } @@ -282,7 +315,7 @@ func TestAuthZPluginErrorRequest(t *testing.T) { require.Nil(t, err) // Ensure command is blocked - _, err = system.Version(client) + _, err = client.ServerVersion(context.Background()) require.NotNil(t, err) require.Equal(t, fmt.Sprintf("Error response from daemon: plugin %s failed with error: %s: %s", testAuthZPlugin, authorization.AuthZApiRequest, errorMessage), err.Error()) } @@ -297,7 +330,7 @@ func TestAuthZPluginEnsureNoDuplicatePluginRegistration(t *testing.T) { client, err := d.NewClient() require.Nil(t, err) - _, err = system.Version(client) + _, err = client.ServerVersion(context.Background()) require.Nil(t, err) // assert plugin is only called once.. @@ -320,19 +353,83 @@ func TestAuthZPluginEnsureLoadImportWorking(t *testing.T) { savedImagePath := filepath.Join(tmp, "save.tar") - err = image.Save(client, savedImagePath, "busybox") + err = imageSave(client, savedImagePath, "busybox") require.Nil(t, err) - err = image.Load(client, savedImagePath) + err = imageLoad(client, savedImagePath) require.Nil(t, err) exportedImagePath := filepath.Join(tmp, "export.tar") - id, err := container.Run(client, "busybox", []string{}) + createResponse, err := client.ContainerCreate(context.Background(), &container.Config{Cmd: []string{}, Image: "busybox"}, &container.HostConfig{}, &networktypes.NetworkingConfig{}, "") require.Nil(t, err) - err = container.Export(client, exportedImagePath, id) + + err = client.ContainerStart(context.Background(), createResponse.ID, types.ContainerStartOptions{}) require.Nil(t, err) - err = image.Import(client, exportedImagePath) + + responseReader, err := client.ContainerExport(context.Background(), createResponse.ID) require.Nil(t, err) + defer responseReader.Close() + file, err := os.Create(exportedImagePath) + require.Nil(t, err) + defer file.Close() + _, err = io.Copy(file, responseReader) + require.Nil(t, err) + + err = imageImport(client, exportedImagePath) + require.Nil(t, err) +} + +func imageSave(client client.APIClient, path, image string) error { + ctx := context.Background() + responseReader, err := client.ImageSave(ctx, []string{image}) + if err != nil { + return err + } + defer responseReader.Close() + file, err := os.Create(path) + if err != nil { + return err + } + defer file.Close() + _, err = io.Copy(file, responseReader) + return err +} + +func imageLoad(client client.APIClient, path string) error { + file, err := os.Open(path) + if err != nil { + return err + } + defer file.Close() + quiet := true + ctx := context.Background() + response, err := client.ImageLoad(ctx, file, quiet) + if err != nil { + return err + } + defer response.Body.Close() + return nil +} + +func imageImport(client client.APIClient, path string) error { + file, err := os.Open(path) + if err != nil { + return err + } + defer file.Close() + options := types.ImageImportOptions{} + ref := "" + source := types.ImageImportSource{ + Source: file, + SourceName: "-", + } + ctx := context.Background() + responseReader, err := client.ImageImport(ctx, source, ref, options) + if err != nil { + return err + } + defer responseReader.Close() + return nil } func TestAuthZPluginHeader(t *testing.T) { diff --git a/integration/plugin/authz/authz_plugin_v2_test.go b/integration/plugin/authz/authz_plugin_v2_test.go index 6f8a934b38..27ecbce5b6 100644 --- a/integration/plugin/authz/authz_plugin_v2_test.go +++ b/integration/plugin/authz/authz_plugin_v2_test.go @@ -5,13 +5,17 @@ package authz import ( "context" "fmt" + "io/ioutil" "os" "strings" "testing" - "github.com/docker/docker/integration/internal/api/container" - "github.com/docker/docker/integration/internal/api/plugin" - "github.com/docker/docker/integration/internal/api/volume" + "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/container" + "github.com/docker/docker/api/types/filters" + networktypes "github.com/docker/docker/api/types/network" + volumetypes "github.com/docker/docker/api/types/volume" + "github.com/docker/docker/client" "github.com/docker/docker/integration/util/requirement" "github.com/gotestyourself/gotestyourself/skip" "github.com/stretchr/testify/require" @@ -44,7 +48,7 @@ func TestAuthZPluginV2AllowNonVolumeRequest(t *testing.T) { require.Nil(t, err) // Install authz plugin - err = plugin.InstallGrantAllPermissions(client, authzPluginNameWithTag) + err = pluginInstallGrantAllPermissions(client, authzPluginNameWithTag) require.Nil(t, err) // start the daemon with the plugin and load busybox, --net=none build fails otherwise // because it needs to pull busybox @@ -52,10 +56,13 @@ func TestAuthZPluginV2AllowNonVolumeRequest(t *testing.T) { d.LoadBusybox(t) // Ensure docker run command and accompanying docker ps are successful - id, err := container.Run(client, "busybox", []string{"top"}) + createResponse, err := client.ContainerCreate(context.Background(), &container.Config{Cmd: []string{"top"}, Image: "busybox"}, &container.HostConfig{}, &networktypes.NetworkingConfig{}, "") require.Nil(t, err) - _, err = client.ContainerInspect(context.Background(), id) + err = client.ContainerStart(context.Background(), createResponse.ID, types.ContainerStartOptions{}) + require.Nil(t, err) + + _, err = client.ContainerInspect(context.Background(), createResponse.ID) require.Nil(t, err) } @@ -67,22 +74,22 @@ func TestAuthZPluginV2Disable(t *testing.T) { require.Nil(t, err) // Install authz plugin - err = plugin.InstallGrantAllPermissions(client, authzPluginNameWithTag) + err = pluginInstallGrantAllPermissions(client, authzPluginNameWithTag) require.Nil(t, err) d.Restart(t, "--authorization-plugin="+authzPluginNameWithTag) d.LoadBusybox(t) - _, err = volume.Create(client, "local", map[string]string{}) + _, err = client.VolumeCreate(context.Background(), volumetypes.VolumesCreateBody{Driver: "local"}) require.NotNil(t, err) require.True(t, strings.Contains(err.Error(), fmt.Sprintf("Error response from daemon: plugin %s failed with error:", authzPluginNameWithTag))) // disable the plugin - err = plugin.Disable(client, authzPluginNameWithTag) + err = client.PluginDisable(context.Background(), authzPluginNameWithTag, types.PluginDisableOptions{}) require.Nil(t, err) // now test to see if the docker api works. - _, err = volume.Create(client, "local", map[string]string{}) + _, err = client.VolumeCreate(context.Background(), volumetypes.VolumesCreateBody{Driver: "local"}) require.Nil(t, err) } @@ -94,30 +101,30 @@ func TestAuthZPluginV2RejectVolumeRequests(t *testing.T) { require.Nil(t, err) // Install authz plugin - err = plugin.InstallGrantAllPermissions(client, authzPluginNameWithTag) + err = pluginInstallGrantAllPermissions(client, authzPluginNameWithTag) require.Nil(t, err) // restart the daemon with the plugin d.Restart(t, "--authorization-plugin="+authzPluginNameWithTag) - _, err = volume.Create(client, "local", map[string]string{}) + _, err = client.VolumeCreate(context.Background(), volumetypes.VolumesCreateBody{Driver: "local"}) require.NotNil(t, err) require.True(t, strings.Contains(err.Error(), fmt.Sprintf("Error response from daemon: plugin %s failed with error:", authzPluginNameWithTag))) - _, err = volume.Ls(client) + _, err = client.VolumeList(context.Background(), filters.Args{}) require.NotNil(t, err) require.True(t, strings.Contains(err.Error(), fmt.Sprintf("Error response from daemon: plugin %s failed with error:", authzPluginNameWithTag))) // The plugin will block the command before it can determine the volume does not exist - err = volume.Rm(client, "test") + err = client.VolumeRemove(context.Background(), "test", false) require.NotNil(t, err) require.True(t, strings.Contains(err.Error(), fmt.Sprintf("Error response from daemon: plugin %s failed with error:", authzPluginNameWithTag))) - _, err = volume.Inspect(client, "test") + _, err = client.VolumeInspect(context.Background(), "test") require.NotNil(t, err) require.True(t, strings.Contains(err.Error(), fmt.Sprintf("Error response from daemon: plugin %s failed with error:", authzPluginNameWithTag))) - _, err = volume.Prune(client) + _, err = client.VolumesPrune(context.Background(), filters.Args{}) require.NotNil(t, err) require.True(t, strings.Contains(err.Error(), fmt.Sprintf("Error response from daemon: plugin %s failed with error:", authzPluginNameWithTag))) } @@ -130,7 +137,7 @@ func TestAuthZPluginV2BadManifestFailsDaemonStart(t *testing.T) { require.Nil(t, err) // Install authz plugin with bad manifest - err = plugin.InstallGrantAllPermissions(client, authzPluginBadManifestName) + err = pluginInstallGrantAllPermissions(client, authzPluginBadManifestName) require.Nil(t, err) // start the daemon with the plugin, it will error @@ -151,3 +158,21 @@ func TestAuthZPluginV2NonexistentFailsDaemonStart(t *testing.T) { // restarting the daemon without requiring the plugin will succeed d.Start(t) } + +func pluginInstallGrantAllPermissions(client client.APIClient, name string) error { + ctx := context.Background() + options := types.PluginInstallOptions{ + RemoteRef: name, + AcceptAllPermissions: true, + } + responseReader, err := client.PluginInstall(ctx, "", options) + if err != nil { + return err + } + defer responseReader.Close() + // we have to read the response out here because the client API + // actually starts a goroutine which we can only be sure has + // completed when we get EOF from reading responseBody + _, err = ioutil.ReadAll(responseReader) + return err +}