mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Merge pull request #34085 from cpuguy83/tests_use_locally_built_plugin
Use local plugins, not from hub for tests
This commit is contained in:
commit
f909119582
6 changed files with 338 additions and 207 deletions
|
@ -5,21 +5,26 @@ import (
|
|||
"net/http/httptest"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"sync"
|
||||
"syscall"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/docker/docker/api/types/swarm"
|
||||
"github.com/docker/docker/cli/config"
|
||||
"github.com/docker/docker/integration-cli/checker"
|
||||
"github.com/docker/docker/integration-cli/cli"
|
||||
"github.com/docker/docker/integration-cli/cli/build/fakestorage"
|
||||
"github.com/docker/docker/integration-cli/daemon"
|
||||
"github.com/docker/docker/integration-cli/environment"
|
||||
"github.com/docker/docker/integration-cli/fixtures/plugin"
|
||||
"github.com/docker/docker/integration-cli/registry"
|
||||
"github.com/docker/docker/pkg/reexec"
|
||||
"github.com/go-check/check"
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -442,3 +447,50 @@ func (s *DockerTrustedSwarmSuite) TearDownTest(c *check.C) {
|
|||
func (s *DockerTrustedSwarmSuite) OnTimeout(c *check.C) {
|
||||
s.swarmSuite.OnTimeout(c)
|
||||
}
|
||||
|
||||
func init() {
|
||||
check.Suite(&DockerPluginSuite{
|
||||
ds: &DockerSuite{},
|
||||
})
|
||||
}
|
||||
|
||||
type DockerPluginSuite struct {
|
||||
ds *DockerSuite
|
||||
registry *registry.V2
|
||||
}
|
||||
|
||||
func (ps *DockerPluginSuite) registryHost() string {
|
||||
return privateRegistryURL
|
||||
}
|
||||
|
||||
func (ps *DockerPluginSuite) getPluginRepo() string {
|
||||
return path.Join(ps.registryHost(), "plugin", "basic")
|
||||
}
|
||||
func (ps *DockerPluginSuite) getPluginRepoWithTag() string {
|
||||
return ps.getPluginRepo() + ":" + "latest"
|
||||
}
|
||||
|
||||
func (ps *DockerPluginSuite) SetUpSuite(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
ps.registry = setupRegistry(c, false, "", "")
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
|
||||
defer cancel()
|
||||
|
||||
err := plugin.CreateInRegistry(ctx, ps.getPluginRepo(), nil)
|
||||
c.Assert(err, checker.IsNil, check.Commentf("failed to create plugin"))
|
||||
}
|
||||
|
||||
func (ps *DockerPluginSuite) TearDownSuite(c *check.C) {
|
||||
if ps.registry != nil {
|
||||
ps.registry.Close()
|
||||
}
|
||||
}
|
||||
|
||||
func (ps *DockerPluginSuite) TearDownTest(c *check.C) {
|
||||
ps.ds.TearDownTest(c)
|
||||
}
|
||||
|
||||
func (ps *DockerPluginSuite) OnTimeout(c *check.C) {
|
||||
ps.ds.OnTimeout(c)
|
||||
}
|
||||
|
|
|
@ -5,14 +5,20 @@ import (
|
|||
"io/ioutil"
|
||||
"net/http"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/integration-cli/checker"
|
||||
"github.com/docker/docker/integration-cli/cli"
|
||||
"github.com/docker/docker/integration-cli/daemon"
|
||||
"github.com/docker/docker/integration-cli/fixtures/plugin"
|
||||
"github.com/docker/docker/integration-cli/request"
|
||||
icmd "github.com/docker/docker/pkg/testutil/cmd"
|
||||
"github.com/go-check/check"
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -24,31 +30,30 @@ var (
|
|||
npNameWithTag = npName + ":" + pTag
|
||||
)
|
||||
|
||||
func (s *DockerSuite) TestPluginBasicOps(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux, IsAmd64, Network)
|
||||
_, _, err := dockerCmdWithError("plugin", "install", "--grant-all-permissions", pNameWithTag)
|
||||
func (ps *DockerPluginSuite) TestPluginBasicOps(c *check.C) {
|
||||
plugin := ps.getPluginRepoWithTag()
|
||||
_, _, err := dockerCmdWithError("plugin", "install", "--grant-all-permissions", plugin)
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
out, _, err := dockerCmdWithError("plugin", "ls")
|
||||
c.Assert(err, checker.IsNil)
|
||||
c.Assert(out, checker.Contains, pName)
|
||||
c.Assert(out, checker.Contains, pTag)
|
||||
c.Assert(out, checker.Contains, plugin)
|
||||
c.Assert(out, checker.Contains, "true")
|
||||
|
||||
id, _, err := dockerCmdWithError("plugin", "inspect", "-f", "{{.Id}}", pNameWithTag)
|
||||
id, _, err := dockerCmdWithError("plugin", "inspect", "-f", "{{.Id}}", plugin)
|
||||
id = strings.TrimSpace(id)
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
out, _, err = dockerCmdWithError("plugin", "remove", pNameWithTag)
|
||||
out, _, err = dockerCmdWithError("plugin", "remove", plugin)
|
||||
c.Assert(err, checker.NotNil)
|
||||
c.Assert(out, checker.Contains, "is enabled")
|
||||
|
||||
_, _, err = dockerCmdWithError("plugin", "disable", pNameWithTag)
|
||||
_, _, err = dockerCmdWithError("plugin", "disable", plugin)
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
out, _, err = dockerCmdWithError("plugin", "remove", pNameWithTag)
|
||||
out, _, err = dockerCmdWithError("plugin", "remove", plugin)
|
||||
c.Assert(err, checker.IsNil)
|
||||
c.Assert(out, checker.Contains, pNameWithTag)
|
||||
c.Assert(out, checker.Contains, plugin)
|
||||
|
||||
_, err = os.Stat(filepath.Join(testEnv.DockerBasePath(), "plugins", id))
|
||||
if !os.IsNotExist(err) {
|
||||
|
@ -56,8 +61,9 @@ func (s *DockerSuite) TestPluginBasicOps(c *check.C) {
|
|||
}
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestPluginForceRemove(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux, IsAmd64, Network)
|
||||
func (ps *DockerPluginSuite) TestPluginForceRemove(c *check.C) {
|
||||
pNameWithTag := ps.getPluginRepoWithTag()
|
||||
|
||||
out, _, err := dockerCmdWithError("plugin", "install", "--grant-all-permissions", pNameWithTag)
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
|
@ -71,6 +77,7 @@ func (s *DockerSuite) TestPluginForceRemove(c *check.C) {
|
|||
|
||||
func (s *DockerSuite) TestPluginActive(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux, IsAmd64, Network)
|
||||
|
||||
_, _, err := dockerCmdWithError("plugin", "install", "--grant-all-permissions", pNameWithTag)
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
|
@ -118,8 +125,9 @@ func (s *DockerSuite) TestPluginActiveNetwork(c *check.C) {
|
|||
c.Assert(out, checker.Contains, npNameWithTag)
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestPluginInstallDisable(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux, IsAmd64, Network)
|
||||
func (ps *DockerPluginSuite) TestPluginInstallDisable(c *check.C) {
|
||||
pName := ps.getPluginRepoWithTag()
|
||||
|
||||
out, _, err := dockerCmdWithError("plugin", "install", "--grant-all-permissions", "--disable", pName)
|
||||
c.Assert(err, checker.IsNil)
|
||||
c.Assert(strings.TrimSpace(out), checker.Contains, pName)
|
||||
|
@ -150,22 +158,39 @@ func (s *DockerSuite) TestPluginInstallDisableVolumeLs(c *check.C) {
|
|||
dockerCmd(c, "volume", "ls")
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestPluginSet(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux, IsAmd64, Network)
|
||||
out, _ := dockerCmd(c, "plugin", "install", "--grant-all-permissions", "--disable", pName)
|
||||
c.Assert(strings.TrimSpace(out), checker.Contains, pName)
|
||||
func (ps *DockerPluginSuite) TestPluginSet(c *check.C) {
|
||||
// Create a new plugin with extra settings
|
||||
client, err := request.NewClient()
|
||||
c.Assert(err, checker.IsNil, check.Commentf("failed to create test client"))
|
||||
|
||||
env, _ := dockerCmd(c, "plugin", "inspect", "-f", "{{.Settings.Env}}", pName)
|
||||
name := "test"
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
|
||||
defer cancel()
|
||||
|
||||
initialValue := "0"
|
||||
err = plugin.Create(ctx, client, name, func(cfg *plugin.Config) {
|
||||
cfg.Env = []types.PluginEnv{{Name: "DEBUG", Value: &initialValue, Settable: []string{"value"}}}
|
||||
})
|
||||
c.Assert(err, checker.IsNil, check.Commentf("failed to create test plugin"))
|
||||
|
||||
env, _ := dockerCmd(c, "plugin", "inspect", "-f", "{{.Settings.Env}}", name)
|
||||
c.Assert(strings.TrimSpace(env), checker.Equals, "[DEBUG=0]")
|
||||
|
||||
dockerCmd(c, "plugin", "set", pName, "DEBUG=1")
|
||||
dockerCmd(c, "plugin", "set", name, "DEBUG=1")
|
||||
|
||||
env, _ = dockerCmd(c, "plugin", "inspect", "-f", "{{.Settings.Env}}", pName)
|
||||
env, _ = dockerCmd(c, "plugin", "inspect", "-f", "{{.Settings.Env}}", name)
|
||||
c.Assert(strings.TrimSpace(env), checker.Equals, "[DEBUG=1]")
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestPluginInstallArgs(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux, IsAmd64, Network)
|
||||
func (ps *DockerPluginSuite) TestPluginInstallArgs(c *check.C) {
|
||||
pName := path.Join(ps.registryHost(), "plugin", "testplugininstallwithargs")
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
|
||||
defer cancel()
|
||||
|
||||
plugin.CreateInRegistry(ctx, pName, nil, func(cfg *plugin.Config) {
|
||||
cfg.Env = []types.PluginEnv{{Name: "DEBUG", Settable: []string{"value"}}}
|
||||
})
|
||||
|
||||
out, _ := dockerCmd(c, "plugin", "install", "--grant-all-permissions", "--disable", pName, "DEBUG=1")
|
||||
c.Assert(strings.TrimSpace(out), checker.Contains, pName)
|
||||
|
||||
|
@ -173,8 +198,8 @@ func (s *DockerSuite) TestPluginInstallArgs(c *check.C) {
|
|||
c.Assert(strings.TrimSpace(env), checker.Equals, "[DEBUG=1]")
|
||||
}
|
||||
|
||||
func (s *DockerRegistrySuite) TestPluginInstallImage(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux, IsAmd64)
|
||||
func (ps *DockerPluginSuite) TestPluginInstallImage(c *check.C) {
|
||||
testRequires(c, IsAmd64)
|
||||
|
||||
repoName := fmt.Sprintf("%v/dockercli/busybox", privateRegistryURL)
|
||||
// tag the image to upload it to the private registry
|
||||
|
@ -187,8 +212,9 @@ func (s *DockerRegistrySuite) TestPluginInstallImage(c *check.C) {
|
|||
c.Assert(out, checker.Contains, `Encountered remote "application/vnd.docker.container.image.v1+json"(image) when fetching`)
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestPluginEnableDisableNegative(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux, IsAmd64, Network)
|
||||
func (ps *DockerPluginSuite) TestPluginEnableDisableNegative(c *check.C) {
|
||||
pName := ps.getPluginRepoWithTag()
|
||||
|
||||
out, _, err := dockerCmdWithError("plugin", "install", "--grant-all-permissions", pName)
|
||||
c.Assert(err, checker.IsNil)
|
||||
c.Assert(strings.TrimSpace(out), checker.Contains, pName)
|
||||
|
@ -208,9 +234,7 @@ func (s *DockerSuite) TestPluginEnableDisableNegative(c *check.C) {
|
|||
c.Assert(err, checker.IsNil)
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestPluginCreate(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux, IsAmd64, Network)
|
||||
|
||||
func (ps *DockerPluginSuite) TestPluginCreate(c *check.C) {
|
||||
name := "foo/bar-driver"
|
||||
temp, err := ioutil.TempDir("", "foo")
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
@ -242,15 +266,15 @@ func (s *DockerSuite) TestPluginCreate(c *check.C) {
|
|||
c.Assert(len(strings.Split(strings.TrimSpace(out), "\n")), checker.Equals, 2)
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestPluginInspect(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux, IsAmd64, Network)
|
||||
func (ps *DockerPluginSuite) TestPluginInspect(c *check.C) {
|
||||
pNameWithTag := ps.getPluginRepoWithTag()
|
||||
|
||||
_, _, err := dockerCmdWithError("plugin", "install", "--grant-all-permissions", pNameWithTag)
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
out, _, err := dockerCmdWithError("plugin", "ls")
|
||||
c.Assert(err, checker.IsNil)
|
||||
c.Assert(out, checker.Contains, pName)
|
||||
c.Assert(out, checker.Contains, pTag)
|
||||
c.Assert(out, checker.Contains, pNameWithTag)
|
||||
c.Assert(out, checker.Contains, "true")
|
||||
|
||||
// Find the ID first
|
||||
|
@ -275,7 +299,7 @@ func (s *DockerSuite) TestPluginInspect(c *check.C) {
|
|||
c.Assert(strings.TrimSpace(out), checker.Equals, id)
|
||||
|
||||
// Name without tag form
|
||||
out, _, err = dockerCmdWithError("plugin", "inspect", "-f", "{{.Id}}", pName)
|
||||
out, _, err = dockerCmdWithError("plugin", "inspect", "-f", "{{.Id}}", ps.getPluginRepo())
|
||||
c.Assert(err, checker.IsNil)
|
||||
c.Assert(strings.TrimSpace(out), checker.Equals, id)
|
||||
|
||||
|
@ -347,21 +371,29 @@ func (s *DockerTrustSuite) TestPluginUntrustedInstall(c *check.C) {
|
|||
})
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestPluginIDPrefix(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux, IsAmd64, Network)
|
||||
_, _, err := dockerCmdWithError("plugin", "install", "--disable", "--grant-all-permissions", pNameWithTag)
|
||||
c.Assert(err, checker.IsNil)
|
||||
func (ps *DockerPluginSuite) TestPluginIDPrefix(c *check.C) {
|
||||
name := "test"
|
||||
client, err := request.NewClient()
|
||||
c.Assert(err, checker.IsNil, check.Commentf("error creating test client"))
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
|
||||
initialValue := "0"
|
||||
err = plugin.Create(ctx, client, name, func(cfg *plugin.Config) {
|
||||
cfg.Env = []types.PluginEnv{{Name: "DEBUG", Value: &initialValue, Settable: []string{"value"}}}
|
||||
})
|
||||
cancel()
|
||||
|
||||
c.Assert(err, checker.IsNil, check.Commentf("failed to create test plugin"))
|
||||
|
||||
// Find ID first
|
||||
id, _, err := dockerCmdWithError("plugin", "inspect", "-f", "{{.Id}}", pNameWithTag)
|
||||
id, _, err := dockerCmdWithError("plugin", "inspect", "-f", "{{.Id}}", name)
|
||||
id = strings.TrimSpace(id)
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
// List current state
|
||||
out, _, err := dockerCmdWithError("plugin", "ls")
|
||||
c.Assert(err, checker.IsNil)
|
||||
c.Assert(out, checker.Contains, pName)
|
||||
c.Assert(out, checker.Contains, pTag)
|
||||
c.Assert(out, checker.Contains, name)
|
||||
c.Assert(out, checker.Contains, "false")
|
||||
|
||||
env, _ := dockerCmd(c, "plugin", "inspect", "-f", "{{.Settings.Env}}", id[:5])
|
||||
|
@ -377,8 +409,7 @@ func (s *DockerSuite) TestPluginIDPrefix(c *check.C) {
|
|||
c.Assert(err, checker.IsNil)
|
||||
out, _, err = dockerCmdWithError("plugin", "ls")
|
||||
c.Assert(err, checker.IsNil)
|
||||
c.Assert(out, checker.Contains, pName)
|
||||
c.Assert(out, checker.Contains, pTag)
|
||||
c.Assert(out, checker.Contains, name)
|
||||
c.Assert(out, checker.Contains, "true")
|
||||
|
||||
// Disable
|
||||
|
@ -386,8 +417,7 @@ func (s *DockerSuite) TestPluginIDPrefix(c *check.C) {
|
|||
c.Assert(err, checker.IsNil)
|
||||
out, _, err = dockerCmdWithError("plugin", "ls")
|
||||
c.Assert(err, checker.IsNil)
|
||||
c.Assert(out, checker.Contains, pName)
|
||||
c.Assert(out, checker.Contains, pTag)
|
||||
c.Assert(out, checker.Contains, name)
|
||||
c.Assert(out, checker.Contains, "false")
|
||||
|
||||
// Remove
|
||||
|
@ -396,13 +426,10 @@ func (s *DockerSuite) TestPluginIDPrefix(c *check.C) {
|
|||
// List returns none
|
||||
out, _, err = dockerCmdWithError("plugin", "ls")
|
||||
c.Assert(err, checker.IsNil)
|
||||
c.Assert(out, checker.Not(checker.Contains), pName)
|
||||
c.Assert(out, checker.Not(checker.Contains), pTag)
|
||||
c.Assert(out, checker.Not(checker.Contains), name)
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestPluginListDefaultFormat(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux, Network, IsAmd64)
|
||||
|
||||
func (ps *DockerPluginSuite) TestPluginListDefaultFormat(c *check.C) {
|
||||
config, err := ioutil.TempDir("", "config-file-")
|
||||
c.Assert(err, check.IsNil)
|
||||
defer os.RemoveAll(config)
|
||||
|
@ -410,17 +437,25 @@ func (s *DockerSuite) TestPluginListDefaultFormat(c *check.C) {
|
|||
err = ioutil.WriteFile(filepath.Join(config, "config.json"), []byte(`{"pluginsFormat": "raw"}`), 0644)
|
||||
c.Assert(err, check.IsNil)
|
||||
|
||||
out, _ := dockerCmd(c, "plugin", "install", "--grant-all-permissions", pName)
|
||||
c.Assert(strings.TrimSpace(out), checker.Contains, pName)
|
||||
name := "test:latest"
|
||||
client, err := request.NewClient()
|
||||
c.Assert(err, checker.IsNil, check.Commentf("error creating test client"))
|
||||
|
||||
out, _ = dockerCmd(c, "plugin", "inspect", "--format", "{{.ID}}", pNameWithTag)
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
|
||||
defer cancel()
|
||||
err = plugin.Create(ctx, client, name, func(cfg *plugin.Config) {
|
||||
cfg.Description = "test plugin"
|
||||
})
|
||||
c.Assert(err, checker.IsNil, check.Commentf("failed to create test plugin"))
|
||||
|
||||
out, _ := dockerCmd(c, "plugin", "inspect", "--format", "{{.ID}}", name)
|
||||
id := strings.TrimSpace(out)
|
||||
|
||||
// We expect the format to be in `raw + --no-trunc`
|
||||
expectedOutput := fmt.Sprintf(`plugin_id: %s
|
||||
name: %s
|
||||
description: A sample volume plugin for Docker
|
||||
enabled: true`, id, pNameWithTag)
|
||||
description: test plugin
|
||||
enabled: false`, id, name)
|
||||
|
||||
out, _ = dockerCmd(c, "--config", config, "plugin", "ls", "--no-trunc")
|
||||
c.Assert(strings.TrimSpace(out), checker.Contains, expectedOutput)
|
||||
|
|
|
@ -1,20 +1,9 @@
|
|||
package plugin
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/libcontainerd"
|
||||
"github.com/docker/docker/pkg/archive"
|
||||
"github.com/docker/docker/plugin"
|
||||
"github.com/docker/docker/registry"
|
||||
"github.com/pkg/errors"
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
|
@ -43,141 +32,3 @@ func WithBinary(bin string) CreateOpt {
|
|||
type CreateClient interface {
|
||||
PluginCreate(context.Context, io.Reader, types.PluginCreateOptions) error
|
||||
}
|
||||
|
||||
// Create creates a new plugin with the specified name
|
||||
func Create(ctx context.Context, c CreateClient, name string, opts ...CreateOpt) error {
|
||||
tmpDir, err := ioutil.TempDir("", "create-test-plugin")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
tar, err := makePluginBundle(tmpDir, opts...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer tar.Close()
|
||||
|
||||
ctx, cancel := context.WithTimeout(ctx, 30*time.Second)
|
||||
defer cancel()
|
||||
|
||||
return c.PluginCreate(ctx, tar, types.PluginCreateOptions{RepoName: name})
|
||||
}
|
||||
|
||||
// TODO(@cpuguy83): we really shouldn't have to do this...
|
||||
// The manager panics on init when `Executor` is not set.
|
||||
type dummyExecutor struct{}
|
||||
|
||||
func (dummyExecutor) Client(libcontainerd.Backend) (libcontainerd.Client, error) { return nil, nil }
|
||||
func (dummyExecutor) Cleanup() {}
|
||||
func (dummyExecutor) UpdateOptions(...libcontainerd.RemoteOption) error { return nil }
|
||||
|
||||
// CreateInRegistry makes a plugin (locally) and pushes it to a registry.
|
||||
// This does not use a dockerd instance to create or push the plugin.
|
||||
// If you just want to create a plugin in some daemon, use `Create`.
|
||||
//
|
||||
// This can be useful when testing plugins on swarm where you don't really want
|
||||
// the plugin to exist on any of the daemons (immediately) and there needs to be
|
||||
// some way to distribute the plugin.
|
||||
func CreateInRegistry(ctx context.Context, repo string, auth *types.AuthConfig, opts ...CreateOpt) error {
|
||||
tmpDir, err := ioutil.TempDir("", "create-test-plugin-local")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
inPath := filepath.Join(tmpDir, "plugin")
|
||||
if err := os.MkdirAll(inPath, 0755); err != nil {
|
||||
return errors.Wrap(err, "error creating plugin root")
|
||||
}
|
||||
|
||||
tar, err := makePluginBundle(inPath, opts...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer tar.Close()
|
||||
|
||||
managerConfig := plugin.ManagerConfig{
|
||||
Store: plugin.NewStore(),
|
||||
RegistryService: registry.NewService(registry.ServiceOptions{V2Only: true}),
|
||||
Root: filepath.Join(tmpDir, "root"),
|
||||
ExecRoot: "/run/docker", // manager init fails if not set
|
||||
Executor: dummyExecutor{},
|
||||
LogPluginEvent: func(id, name, action string) {}, // panics when not set
|
||||
}
|
||||
manager, err := plugin.NewManager(managerConfig)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "error creating plugin manager")
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithTimeout(ctx, 30*time.Second)
|
||||
defer cancel()
|
||||
if err := manager.CreateFromContext(ctx, tar, &types.PluginCreateOptions{RepoName: repo}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if auth == nil {
|
||||
auth = &types.AuthConfig{}
|
||||
}
|
||||
err = manager.Push(ctx, repo, nil, auth, ioutil.Discard)
|
||||
return errors.Wrap(err, "error pushing plugin")
|
||||
}
|
||||
|
||||
func makePluginBundle(inPath string, opts ...CreateOpt) (io.ReadCloser, error) {
|
||||
p := &types.PluginConfig{
|
||||
Interface: types.PluginConfigInterface{
|
||||
Socket: "basic.sock",
|
||||
Types: []types.PluginInterfaceType{{Capability: "docker.dummy/1.0"}},
|
||||
},
|
||||
Entrypoint: []string{"/basic"},
|
||||
}
|
||||
cfg := &Config{
|
||||
PluginConfig: p,
|
||||
}
|
||||
for _, o := range opts {
|
||||
o(cfg)
|
||||
}
|
||||
if cfg.binPath == "" {
|
||||
binPath, err := ensureBasicPluginBin()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cfg.binPath = binPath
|
||||
}
|
||||
|
||||
configJSON, err := json.Marshal(p)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := ioutil.WriteFile(filepath.Join(inPath, "config.json"), configJSON, 0644); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := os.MkdirAll(filepath.Join(inPath, "rootfs", filepath.Dir(p.Entrypoint[0])), 0755); err != nil {
|
||||
return nil, errors.Wrap(err, "error creating plugin rootfs dir")
|
||||
}
|
||||
if err := archive.NewDefaultArchiver().CopyFileWithTar(cfg.binPath, filepath.Join(inPath, "rootfs", p.Entrypoint[0])); err != nil {
|
||||
return nil, errors.Wrap(err, "error copying plugin binary to rootfs path")
|
||||
}
|
||||
tar, err := archive.Tar(inPath, archive.Uncompressed)
|
||||
return tar, errors.Wrap(err, "error making plugin archive")
|
||||
}
|
||||
|
||||
func ensureBasicPluginBin() (string, error) {
|
||||
name := "docker-basic-plugin"
|
||||
p, err := exec.LookPath(name)
|
||||
if err == nil {
|
||||
return p, nil
|
||||
}
|
||||
|
||||
goBin, err := exec.LookPath("go")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
installPath := filepath.Join(os.Getenv("GOPATH"), "bin", name)
|
||||
cmd := exec.Command(goBin, "build", "-o", installPath, "./"+filepath.Join("fixtures", "plugin", "basic"))
|
||||
cmd.Env = append(cmd.Env, "CGO_ENABLED=0")
|
||||
if out, err := cmd.CombinedOutput(); err != nil {
|
||||
return "", errors.Wrapf(err, "error building basic plugin bin: %s", string(out))
|
||||
}
|
||||
return installPath, nil
|
||||
}
|
||||
|
|
157
integration-cli/fixtures/plugin/plugin_linux.go
Normal file
157
integration-cli/fixtures/plugin/plugin_linux.go
Normal file
|
@ -0,0 +1,157 @@
|
|||
package plugin
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/libcontainerd"
|
||||
"github.com/docker/docker/pkg/archive"
|
||||
"github.com/docker/docker/plugin"
|
||||
"github.com/docker/docker/registry"
|
||||
"github.com/pkg/errors"
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
// Create creates a new plugin with the specified name
|
||||
func Create(ctx context.Context, c CreateClient, name string, opts ...CreateOpt) error {
|
||||
tmpDir, err := ioutil.TempDir("", "create-test-plugin")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
tar, err := makePluginBundle(tmpDir, opts...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer tar.Close()
|
||||
|
||||
ctx, cancel := context.WithTimeout(ctx, 30*time.Second)
|
||||
defer cancel()
|
||||
|
||||
return c.PluginCreate(ctx, tar, types.PluginCreateOptions{RepoName: name})
|
||||
}
|
||||
|
||||
// TODO(@cpuguy83): we really shouldn't have to do this...
|
||||
// The manager panics on init when `Executor` is not set.
|
||||
type dummyExecutor struct{}
|
||||
|
||||
func (dummyExecutor) Client(libcontainerd.Backend) (libcontainerd.Client, error) { return nil, nil }
|
||||
func (dummyExecutor) Cleanup() {}
|
||||
func (dummyExecutor) UpdateOptions(...libcontainerd.RemoteOption) error { return nil }
|
||||
|
||||
// CreateInRegistry makes a plugin (locally) and pushes it to a registry.
|
||||
// This does not use a dockerd instance to create or push the plugin.
|
||||
// If you just want to create a plugin in some daemon, use `Create`.
|
||||
//
|
||||
// This can be useful when testing plugins on swarm where you don't really want
|
||||
// the plugin to exist on any of the daemons (immediately) and there needs to be
|
||||
// some way to distribute the plugin.
|
||||
func CreateInRegistry(ctx context.Context, repo string, auth *types.AuthConfig, opts ...CreateOpt) error {
|
||||
tmpDir, err := ioutil.TempDir("", "create-test-plugin-local")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
inPath := filepath.Join(tmpDir, "plugin")
|
||||
if err := os.MkdirAll(inPath, 0755); err != nil {
|
||||
return errors.Wrap(err, "error creating plugin root")
|
||||
}
|
||||
|
||||
tar, err := makePluginBundle(inPath, opts...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer tar.Close()
|
||||
|
||||
managerConfig := plugin.ManagerConfig{
|
||||
Store: plugin.NewStore(),
|
||||
RegistryService: registry.NewService(registry.ServiceOptions{V2Only: true}),
|
||||
Root: filepath.Join(tmpDir, "root"),
|
||||
ExecRoot: "/run/docker", // manager init fails if not set
|
||||
Executor: dummyExecutor{},
|
||||
LogPluginEvent: func(id, name, action string) {}, // panics when not set
|
||||
}
|
||||
manager, err := plugin.NewManager(managerConfig)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "error creating plugin manager")
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithTimeout(ctx, 30*time.Second)
|
||||
defer cancel()
|
||||
if err := manager.CreateFromContext(ctx, tar, &types.PluginCreateOptions{RepoName: repo}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if auth == nil {
|
||||
auth = &types.AuthConfig{}
|
||||
}
|
||||
err = manager.Push(ctx, repo, nil, auth, ioutil.Discard)
|
||||
return errors.Wrap(err, "error pushing plugin")
|
||||
}
|
||||
|
||||
func makePluginBundle(inPath string, opts ...CreateOpt) (io.ReadCloser, error) {
|
||||
p := &types.PluginConfig{
|
||||
Interface: types.PluginConfigInterface{
|
||||
Socket: "basic.sock",
|
||||
Types: []types.PluginInterfaceType{{Capability: "docker.dummy/1.0"}},
|
||||
},
|
||||
Entrypoint: []string{"/basic"},
|
||||
}
|
||||
cfg := &Config{
|
||||
PluginConfig: p,
|
||||
}
|
||||
for _, o := range opts {
|
||||
o(cfg)
|
||||
}
|
||||
if cfg.binPath == "" {
|
||||
binPath, err := ensureBasicPluginBin()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cfg.binPath = binPath
|
||||
}
|
||||
|
||||
configJSON, err := json.Marshal(p)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := ioutil.WriteFile(filepath.Join(inPath, "config.json"), configJSON, 0644); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := os.MkdirAll(filepath.Join(inPath, "rootfs", filepath.Dir(p.Entrypoint[0])), 0755); err != nil {
|
||||
return nil, errors.Wrap(err, "error creating plugin rootfs dir")
|
||||
}
|
||||
if err := archive.NewDefaultArchiver().CopyFileWithTar(cfg.binPath, filepath.Join(inPath, "rootfs", p.Entrypoint[0])); err != nil {
|
||||
return nil, errors.Wrap(err, "error copying plugin binary to rootfs path")
|
||||
}
|
||||
tar, err := archive.Tar(inPath, archive.Uncompressed)
|
||||
return tar, errors.Wrap(err, "error making plugin archive")
|
||||
}
|
||||
|
||||
func ensureBasicPluginBin() (string, error) {
|
||||
name := "docker-basic-plugin"
|
||||
p, err := exec.LookPath(name)
|
||||
if err == nil {
|
||||
return p, nil
|
||||
}
|
||||
|
||||
goBin, err := exec.LookPath("go")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
installPath := filepath.Join(os.Getenv("GOPATH"), "bin", name)
|
||||
cmd := exec.Command(goBin, "build", "-o", installPath, "./"+filepath.Join("fixtures", "plugin", "basic"))
|
||||
cmd.Env = append(cmd.Env, "CGO_ENABLED=0")
|
||||
if out, err := cmd.CombinedOutput(); err != nil {
|
||||
return "", errors.Wrapf(err, "error building basic plugin bin: %s", string(out))
|
||||
}
|
||||
return installPath, nil
|
||||
}
|
19
integration-cli/fixtures/plugin/plugin_unsuported.go
Normal file
19
integration-cli/fixtures/plugin/plugin_unsuported.go
Normal file
|
@ -0,0 +1,19 @@
|
|||
// +build !linux
|
||||
|
||||
package plugin
|
||||
|
||||
import (
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/pkg/errors"
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
// Create is not supported on this platform
|
||||
func Create(ctx context.Context, c CreateClient, name string, opts ...CreateOpt) error {
|
||||
return errors.New("not supported on this platform")
|
||||
}
|
||||
|
||||
// CreateInRegistry is not supported on this platform
|
||||
func CreateInRegistry(ctx context.Context, repo string, auth *types.AuthConfig, opts ...CreateOpt) error {
|
||||
return errors.New("not supported on this platform")
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
|
@ -11,9 +12,12 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/docker/docker/api/types"
|
||||
cliconfig "github.com/docker/docker/cli/config"
|
||||
"github.com/docker/docker/integration-cli/checker"
|
||||
"github.com/docker/docker/integration-cli/cli"
|
||||
"github.com/docker/docker/integration-cli/fixtures/plugin"
|
||||
"github.com/docker/docker/integration-cli/request"
|
||||
icmd "github.com/docker/docker/pkg/testutil/cmd"
|
||||
"github.com/docker/go-connections/tlsconfig"
|
||||
"github.com/go-check/check"
|
||||
|
@ -225,10 +229,23 @@ func (s *DockerTrustSuite) setupTrustedImage(c *check.C, name string) string {
|
|||
|
||||
func (s *DockerTrustSuite) setupTrustedplugin(c *check.C, source, name string) string {
|
||||
repoName := fmt.Sprintf("%v/dockercli/%s:latest", privateRegistryURL, name)
|
||||
|
||||
client, err := request.NewClient()
|
||||
c.Assert(err, checker.IsNil, check.Commentf("could not create test client"))
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
|
||||
err = plugin.Create(ctx, client, repoName)
|
||||
cancel()
|
||||
c.Assert(err, checker.IsNil, check.Commentf("could not create test plugin"))
|
||||
|
||||
// tag the image and upload it to the private registry
|
||||
cli.DockerCmd(c, "plugin", "install", "--grant-all-permissions", "--alias", repoName, source)
|
||||
// TODO: shouldn't need to use the CLI to do trust
|
||||
cli.Docker(cli.Args("plugin", "push", repoName), trustedCmd).Assert(c, SuccessSigningAndPushing)
|
||||
cli.DockerCmd(c, "plugin", "rm", "-f", repoName)
|
||||
|
||||
ctx, cancel = context.WithTimeout(context.Background(), 60*time.Second)
|
||||
err = client.PluginRemove(ctx, repoName, types.PluginRemoveOptions{Force: true})
|
||||
cancel()
|
||||
c.Assert(err, checker.IsNil, check.Commentf("failed to cleanup test plugin for trust suite"))
|
||||
return repoName
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue