package common // import "github.com/docker/docker/integration/plugin/common" import ( "context" "encoding/base64" "encoding/json" "io" "io/ioutil" "net" "net/http" "path" "strings" "testing" "github.com/docker/docker/api/types" "github.com/docker/docker/testutil/daemon" "github.com/docker/docker/testutil/fixtures/plugin" "github.com/docker/docker/testutil/registry" "github.com/docker/docker/testutil/request" "gotest.tools/v3/assert" is "gotest.tools/v3/assert/cmp" "gotest.tools/v3/skip" ) func TestPluginInvalidJSON(t *testing.T) { defer setupTest(t)() endpoints := []string{"/plugins/foobar/set"} for _, ep := range endpoints { t.Run(ep, func(t *testing.T) { t.Parallel() res, body, err := request.Post(ep, request.RawString("{invalid json"), request.JSON) assert.NilError(t, err) assert.Equal(t, res.StatusCode, http.StatusBadRequest) buf, err := request.ReadBody(body) assert.NilError(t, err) assert.Check(t, is.Contains(string(buf), "invalid character 'i' looking for beginning of object key string")) res, body, err = request.Post(ep, request.JSON) assert.NilError(t, err) assert.Equal(t, res.StatusCode, http.StatusBadRequest) buf, err = request.ReadBody(body) assert.NilError(t, err) assert.Check(t, is.Contains(string(buf), "got EOF while reading request body")) }) } } func TestPluginInstall(t *testing.T) { skip.If(t, testEnv.IsRemoteDaemon, "cannot run daemon when remote daemon") skip.If(t, testEnv.OSType == "windows") skip.If(t, testEnv.IsRootless, "rootless mode has different view of localhost") ctx := context.Background() client := testEnv.APIClient() t.Run("no auth", func(t *testing.T) { defer setupTest(t)() reg := registry.NewV2(t) defer reg.Close() name := "test-" + strings.ToLower(t.Name()) repo := path.Join(registry.DefaultURL, name+":latest") assert.NilError(t, plugin.CreateInRegistry(ctx, repo, nil)) rdr, err := client.PluginInstall(ctx, repo, types.PluginInstallOptions{Disabled: true, RemoteRef: repo}) assert.NilError(t, err) defer rdr.Close() _, err = io.Copy(ioutil.Discard, rdr) assert.NilError(t, err) _, _, err = client.PluginInspectWithRaw(ctx, repo) assert.NilError(t, err) }) t.Run("with htpasswd", func(t *testing.T) { defer setupTest(t)() reg := registry.NewV2(t, registry.Htpasswd) defer reg.Close() name := "test-" + strings.ToLower(t.Name()) repo := path.Join(registry.DefaultURL, name+":latest") auth := &types.AuthConfig{ServerAddress: registry.DefaultURL, Username: "testuser", Password: "testpassword"} assert.NilError(t, plugin.CreateInRegistry(ctx, repo, auth)) authEncoded, err := json.Marshal(auth) assert.NilError(t, err) rdr, err := client.PluginInstall(ctx, repo, types.PluginInstallOptions{ RegistryAuth: base64.URLEncoding.EncodeToString(authEncoded), Disabled: true, RemoteRef: repo, }) assert.NilError(t, err) defer rdr.Close() _, err = io.Copy(ioutil.Discard, rdr) assert.NilError(t, err) _, _, err = client.PluginInspectWithRaw(ctx, repo) assert.NilError(t, err) }) t.Run("with insecure", func(t *testing.T) { skip.If(t, !testEnv.IsLocalDaemon()) addrs, err := net.InterfaceAddrs() assert.NilError(t, err) var bindTo string for _, addr := range addrs { ip, ok := addr.(*net.IPNet) if !ok { continue } if ip.IP.IsLoopback() || ip.IP.To4() == nil { continue } bindTo = ip.IP.String() } if bindTo == "" { t.Skip("No suitable interface to bind registry to") } regURL := bindTo + ":5000" d := daemon.New(t) defer d.Stop(t) d.Start(t, "--insecure-registry="+regURL) defer d.Stop(t) reg := registry.NewV2(t, registry.URL(regURL)) defer reg.Close() name := "test-" + strings.ToLower(t.Name()) repo := path.Join(regURL, name+":latest") assert.NilError(t, plugin.CreateInRegistry(ctx, repo, nil, plugin.WithInsecureRegistry(regURL))) client := d.NewClientT(t) rdr, err := client.PluginInstall(ctx, repo, types.PluginInstallOptions{Disabled: true, RemoteRef: repo}) assert.NilError(t, err) defer rdr.Close() _, err = io.Copy(ioutil.Discard, rdr) assert.NilError(t, err) _, _, err = client.PluginInspectWithRaw(ctx, repo) assert.NilError(t, err) }) // TODO: test insecure registry with https }