Browse code

Clean some integration-cli/fixtures package/files

- Move go package used by both `integration-cli` and `integration` to
`internal/test/fixtures`.
- Remove fixtures that are not used anymore (moved to `docker/cli` a
while ago) : deploy, notary, secrets.

Signed-off-by: Vincent Demeester <vincent@sbr.pm>

Vincent Demeester authored on 2018/04/16 17:48:58
Showing 32 changed files
... ...
@@ -19,9 +19,9 @@ import (
19 19
 	"github.com/docker/docker/integration-cli/cli/build/fakestorage"
20 20
 	"github.com/docker/docker/integration-cli/daemon"
21 21
 	"github.com/docker/docker/integration-cli/environment"
22
-	"github.com/docker/docker/integration-cli/fixtures/plugin"
23 22
 	testdaemon "github.com/docker/docker/internal/test/daemon"
24 23
 	ienv "github.com/docker/docker/internal/test/environment"
24
+	"github.com/docker/docker/internal/test/fixtures/plugin"
25 25
 	"github.com/docker/docker/internal/test/registry"
26 26
 	"github.com/docker/docker/pkg/reexec"
27 27
 	"github.com/go-check/check"
... ...
@@ -14,8 +14,8 @@ import (
14 14
 	"github.com/docker/docker/api/types/swarm/runtime"
15 15
 	"github.com/docker/docker/integration-cli/checker"
16 16
 	"github.com/docker/docker/integration-cli/daemon"
17
-	"github.com/docker/docker/integration-cli/fixtures/plugin"
18 17
 	testdaemon "github.com/docker/docker/internal/test/daemon"
18
+	"github.com/docker/docker/internal/test/fixtures/plugin"
19 19
 	"github.com/docker/docker/internal/test/registry"
20 20
 	"github.com/go-check/check"
21 21
 	"golang.org/x/net/context"
... ...
@@ -14,7 +14,7 @@ import (
14 14
 	"github.com/docker/docker/integration-cli/checker"
15 15
 	"github.com/docker/docker/integration-cli/cli"
16 16
 	"github.com/docker/docker/integration-cli/daemon"
17
-	"github.com/docker/docker/integration-cli/fixtures/plugin"
17
+	"github.com/docker/docker/internal/test/fixtures/plugin"
18 18
 	"github.com/go-check/check"
19 19
 	"golang.org/x/net/context"
20 20
 )
... ...
@@ -332,7 +332,7 @@ func listTar(f io.Reader) ([]string, error) {
332 332
 func (s *DockerSuite) TestLoadZeroSizeLayer(c *check.C) {
333 333
 	testRequires(c, DaemonIsLinux)
334 334
 
335
-	dockerCmd(c, "load", "-i", "fixtures/load/emptyLayer.tar")
335
+	dockerCmd(c, "load", "-i", "testdata/emptyLayer.tar")
336 336
 }
337 337
 
338 338
 func (s *DockerSuite) TestSaveLoadParents(c *check.C) {
339 339
deleted file mode 100644
... ...
@@ -1,9 +0,0 @@
1
-
2
-version: "3"
3
-services:
4
-  web:
5
-    image: busybox@sha256:e4f93f6ed15a0cdd342f5aae387886fba0ab98af0a102da6276eaf24d6e6ade0
6
-    command: top
7
-  db:
8
-    image: busybox@sha256:e4f93f6ed15a0cdd342f5aae387886fba0ab98af0a102da6276eaf24d6e6ade0
9
-    command: "tail -f /dev/null"
10 1
deleted file mode 100644
... ...
@@ -1,11 +0,0 @@
1
-
2
-version: "3.1"
3
-services:
4
-  web:
5
-    image: busybox:latest
6
-    command: top
7
-    secrets:
8
-      - special
9
-secrets:
10
-  special:
11
-    file: fixtures/secrets/default
12 1
deleted file mode 100644
... ...
@@ -1,20 +0,0 @@
1
-
2
-version: "3.1"
3
-services:
4
-  web:
5
-    image: busybox@sha256:e4f93f6ed15a0cdd342f5aae387886fba0ab98af0a102da6276eaf24d6e6ade0
6
-    command: top
7
-    secrets:
8
-      - special
9
-      - source: super
10
-        target: foo.txt
11
-        mode: 0400
12
-      - star
13
-secrets:
14
-  special:
15
-    file: fixtures/secrets/default
16
-  super:
17
-    file: fixtures/secrets/default
18
-  star:
19
-    external:
20
-      name: outside
21 1
deleted file mode 100644
22 2
Binary files a/integration-cli/fixtures/load/emptyLayer.tar and /dev/null differ
23 3
deleted file mode 100644
... ...
@@ -1,197 +0,0 @@
1
-package load // import "github.com/docker/docker/integration-cli/fixtures/load"
2
-
3
-import (
4
-	"bufio"
5
-	"bytes"
6
-	"os"
7
-	"os/exec"
8
-	"path/filepath"
9
-	"strings"
10
-	"sync"
11
-
12
-	"context"
13
-
14
-	"github.com/docker/docker/api/types"
15
-	"github.com/docker/docker/client"
16
-	"github.com/docker/docker/pkg/jsonmessage"
17
-	"github.com/docker/docker/pkg/term"
18
-	"github.com/pkg/errors"
19
-)
20
-
21
-const frozenImgDir = "/docker-frozen-images"
22
-
23
-// FrozenImagesLinux loads the frozen image set for the integration suite
24
-// If the images are not available locally it will download them
25
-// TODO: This loads whatever is in the frozen image dir, regardless of what
26
-// images were passed in. If the images need to be downloaded, then it will respect
27
-// the passed in images
28
-func FrozenImagesLinux(client client.APIClient, images ...string) error {
29
-	var loadImages []struct{ srcName, destName string }
30
-	for _, img := range images {
31
-		if !imageExists(client, img) {
32
-			srcName := img
33
-			// hello-world:latest gets re-tagged as hello-world:frozen
34
-			// there are some tests that use hello-world:latest specifically so it pulls
35
-			// the image and hello-world:frozen is used for when we just want a super
36
-			// small image
37
-			if img == "hello-world:frozen" {
38
-				srcName = "hello-world:latest"
39
-			}
40
-			loadImages = append(loadImages, struct{ srcName, destName string }{
41
-				srcName:  srcName,
42
-				destName: img,
43
-			})
44
-		}
45
-	}
46
-	if len(loadImages) == 0 {
47
-		// everything is loaded, we're done
48
-		return nil
49
-	}
50
-
51
-	ctx := context.Background()
52
-	fi, err := os.Stat(frozenImgDir)
53
-	if err != nil || !fi.IsDir() {
54
-		srcImages := make([]string, 0, len(loadImages))
55
-		for _, img := range loadImages {
56
-			srcImages = append(srcImages, img.srcName)
57
-		}
58
-		if err := pullImages(ctx, client, srcImages); err != nil {
59
-			return errors.Wrap(err, "error pulling image list")
60
-		}
61
-	} else {
62
-		if err := loadFrozenImages(ctx, client); err != nil {
63
-			return err
64
-		}
65
-	}
66
-
67
-	for _, img := range loadImages {
68
-		if img.srcName != img.destName {
69
-			if err := client.ImageTag(ctx, img.srcName, img.destName); err != nil {
70
-				return errors.Wrapf(err, "failed to tag %s as %s", img.srcName, img.destName)
71
-			}
72
-			if _, err := client.ImageRemove(ctx, img.srcName, types.ImageRemoveOptions{}); err != nil {
73
-				return errors.Wrapf(err, "failed to remove %s", img.srcName)
74
-			}
75
-		}
76
-	}
77
-	return nil
78
-}
79
-
80
-func imageExists(client client.APIClient, name string) bool {
81
-	_, _, err := client.ImageInspectWithRaw(context.Background(), name)
82
-	return err == nil
83
-}
84
-
85
-func loadFrozenImages(ctx context.Context, client client.APIClient) error {
86
-	tar, err := exec.LookPath("tar")
87
-	if err != nil {
88
-		return errors.Wrap(err, "could not find tar binary")
89
-	}
90
-	tarCmd := exec.Command(tar, "-cC", frozenImgDir, ".")
91
-	out, err := tarCmd.StdoutPipe()
92
-	if err != nil {
93
-		return errors.Wrap(err, "error getting stdout pipe for tar command")
94
-	}
95
-
96
-	errBuf := bytes.NewBuffer(nil)
97
-	tarCmd.Stderr = errBuf
98
-	tarCmd.Start()
99
-	defer tarCmd.Wait()
100
-
101
-	resp, err := client.ImageLoad(ctx, out, true)
102
-	if err != nil {
103
-		return errors.Wrap(err, "failed to load frozen images")
104
-	}
105
-	defer resp.Body.Close()
106
-	fd, isTerminal := term.GetFdInfo(os.Stdout)
107
-	return jsonmessage.DisplayJSONMessagesStream(resp.Body, os.Stdout, fd, isTerminal, nil)
108
-}
109
-
110
-func pullImages(ctx context.Context, client client.APIClient, images []string) error {
111
-	cwd, err := os.Getwd()
112
-	if err != nil {
113
-		return errors.Wrap(err, "error getting path to dockerfile")
114
-	}
115
-	dockerfile := os.Getenv("DOCKERFILE")
116
-	if dockerfile == "" {
117
-		dockerfile = "Dockerfile"
118
-	}
119
-	dockerfilePath := filepath.Join(filepath.Dir(filepath.Clean(cwd)), dockerfile)
120
-	pullRefs, err := readFrozenImageList(dockerfilePath, images)
121
-	if err != nil {
122
-		return errors.Wrap(err, "error reading frozen image list")
123
-	}
124
-
125
-	var wg sync.WaitGroup
126
-	chErr := make(chan error, len(images))
127
-	for tag, ref := range pullRefs {
128
-		wg.Add(1)
129
-		go func(tag, ref string) {
130
-			defer wg.Done()
131
-			if err := pullTagAndRemove(ctx, client, ref, tag); err != nil {
132
-				chErr <- err
133
-				return
134
-			}
135
-		}(tag, ref)
136
-	}
137
-	wg.Wait()
138
-	close(chErr)
139
-	return <-chErr
140
-}
141
-
142
-func pullTagAndRemove(ctx context.Context, client client.APIClient, ref string, tag string) error {
143
-	resp, err := client.ImagePull(ctx, ref, types.ImagePullOptions{})
144
-	if err != nil {
145
-		return errors.Wrapf(err, "failed to pull %s", ref)
146
-	}
147
-	defer resp.Close()
148
-	fd, isTerminal := term.GetFdInfo(os.Stdout)
149
-	if err := jsonmessage.DisplayJSONMessagesStream(resp, os.Stdout, fd, isTerminal, nil); err != nil {
150
-		return err
151
-	}
152
-
153
-	if err := client.ImageTag(ctx, ref, tag); err != nil {
154
-		return errors.Wrapf(err, "failed to tag %s as %s", ref, tag)
155
-	}
156
-	_, err = client.ImageRemove(ctx, ref, types.ImageRemoveOptions{})
157
-	return errors.Wrapf(err, "failed to remove %s", ref)
158
-
159
-}
160
-
161
-func readFrozenImageList(dockerfilePath string, images []string) (map[string]string, error) {
162
-	f, err := os.Open(dockerfilePath)
163
-	if err != nil {
164
-		return nil, errors.Wrap(err, "error reading dockerfile")
165
-	}
166
-	defer f.Close()
167
-	ls := make(map[string]string)
168
-
169
-	scanner := bufio.NewScanner(f)
170
-	for scanner.Scan() {
171
-		line := strings.Fields(scanner.Text())
172
-		if len(line) < 3 {
173
-			continue
174
-		}
175
-		if !(line[0] == "RUN" && line[1] == "./contrib/download-frozen-image-v2.sh") {
176
-			continue
177
-		}
178
-
179
-		for scanner.Scan() {
180
-			img := strings.TrimSpace(scanner.Text())
181
-			img = strings.TrimSuffix(img, "\\")
182
-			img = strings.TrimSpace(img)
183
-			split := strings.Split(img, "@")
184
-			if len(split) < 2 {
185
-				break
186
-			}
187
-
188
-			for _, i := range images {
189
-				if split[0] == i {
190
-					ls[i] = img
191
-					break
192
-				}
193
-			}
194
-		}
195
-	}
196
-	return ls, nil
197
-}
198 1
deleted file mode 100644
... ...
@@ -1,21 +0,0 @@
1
-MIIDhTCCAm2gAwIBAgIJAP2EcMN2UXPcMA0GCSqGSIb3DQEBCwUAMFcxCzAJBgNV
2
-BAYTAlVTMQswCQYDVQQIEwJDQTEVMBMGA1UEBxMMU2FuRnJhbmNpc2NvMQ8wDQYD
3
-VQQKEwZEb2NrZXIxEzARBgNVBAMTCmRlbGVnYXRpb24wHhcNMTYwOTI4MTc0ODQ4
4
-WhcNMjYwNjI4MTc0ODQ4WjBXMQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExFTAT
5
-BgNVBAcTDFNhbkZyYW5jaXNjbzEPMA0GA1UEChMGRG9ja2VyMRMwEQYDVQQDEwpk
6
-ZWxlZ2F0aW9uMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvgewhaYs
7
-Ke5s2AM7xxKrT4A6n7hW17qSnBjonCcPcwTFmYqIOdxWjYITgJuHrTwB4ZhBqWS7
8
-tTsUUu6hWLMeB7Uo5/GEQAAZspKkT9G/rNKF9lbWK9PPhGGkeR01c/Q932m92Hsn
9
-fCQ0Pp/OzD3nVTh0v9HKk+PObNMOCcqG87eYs4ylPRxs0RrE/rP+bEGssKQSbeCZ
10
-wazDnO+kiatVgKQZ2CK23iFdRE1z2rzqVDeaFWdvBqrRdWnkOZClhlLgEQ5nK2yV
11
-B6tSqOiI3MmHyHzIkGOQJp2/s7Pe0ckEkzsjTsJW8oKHlBBl6pRxHIKzNN4VFbeB
12
-vvYvrogrDrC/owIDAQABo1QwUjAMBgNVHRMBAf8EAjAAMA4GA1UdDwEB/wQEAwIF
13
-oDATBgNVHSUEDDAKBggrBgEFBQcDAzAdBgNVHQ4EFgQUFoHfukRa6qGk1ncON64Z
14
-ASKlZdkwDQYJKoZIhvcNAQELBQADggEBAEq9Adpd03CPmpbRtTAJGAkjjLFr60sV
15
-2r+/l/m9R31ZCN9ymM9nxToQ8zfMdeAh/nnPcErziil2gDVqXueCNDkRj09tmDIE
16
-Q1Oc92uyNZNgcECow77cKZCTZSTku+qsJrYaykH5vSnia8ltcKj8inJedIcpBR+p
17
-608HEQvF0Eg5eaLPJwH48BCb0Gqdri1dJgrNnqptz7MDr8M+u7tHVulbAd3YxLlq
18
-JH1W2bkVUx6esbn/MUE5HL5iTuOYREEINvBSmLdmmFkampmCnCB/bDEyJeL9bAkt
19
-ZPIi0UNSnqFKLSP1Vf8AGLXt6iO7+1OGvtsDXEEYdXVOMsSXZtUuT7A=
20 1
deleted file mode 100644
... ...
@@ -1,27 +0,0 @@
1
-MIIEpAIBAAKCAQEAvgewhaYsKe5s2AM7xxKrT4A6n7hW17qSnBjonCcPcwTFmYqI
2
-OdxWjYITgJuHrTwB4ZhBqWS7tTsUUu6hWLMeB7Uo5/GEQAAZspKkT9G/rNKF9lbW
3
-K9PPhGGkeR01c/Q932m92HsnfCQ0Pp/OzD3nVTh0v9HKk+PObNMOCcqG87eYs4yl
4
-PRxs0RrE/rP+bEGssKQSbeCZwazDnO+kiatVgKQZ2CK23iFdRE1z2rzqVDeaFWdv
5
-BqrRdWnkOZClhlLgEQ5nK2yVB6tSqOiI3MmHyHzIkGOQJp2/s7Pe0ckEkzsjTsJW
6
-8oKHlBBl6pRxHIKzNN4VFbeBvvYvrogrDrC/owIDAQABAoIBAB/o8KZwsgfUhqh7
7
-WoViSCwQb0e0z7hoFwhpUl4uXPTGf1v6HEgDDPG0PwwgkdbwNaypQZVtWevj4NTQ
8
-R326jjdjH1xbfQa2PZpz722L3jDqJR6plEtFxRoIv3KrCffPsrgabIu2mnnJJpDB
9
-ixtW5cq0sT4ov2i4H0i85CWWwbSY/G/MHsvCuK9PhoCj9uToVqrf1KrAESE5q4fh
10
-mPSYUL99KVnj7SZkUz+79rc8sLLPVks3szZACMlm1n05ZTj/d6Nd2ZZUO45DllIj
11
-1XJghfWmnChrB/P/KYXgQ3Y9BofIAw1ra2y3wOZeqRFNsbmojcGldfdtN/iQzhEj
12
-uk4ThokCgYEA9FTmv36N8qSPWuqX/KzkixDQ8WrDGohcB54kK98Wx4ijXx3i38SY
13
-tFjO8YUS9GVo1+UgmRjZbzVX7xeum6+TdBBwOjNOxEQ4tzwiQBWDdGpli8BccdJ2
14
-OOIVxSslWhiUWfpYloXVetrR88iHbT882g795pbonDaJdXSLnij4UW8CgYEAxxrr
15
-QFpsmOEZvI/yPSOGdG7A1RIsCeH+cEOf4cKghs7+aCtAHlIweztNOrqirl3oKI1r
16
-I0zQl46WsaW8S/y99v9lmmnZbWwqLa4vIu0NWs0zaZdzKZw3xljMhgp4Ge69hHa2
17
-utCtAxcX+7q/yLlHoTiYwKdxX54iLkheCB8csw0CgYEAleEG820kkjXUIodJ2JwO
18
-Tihwo8dEC6CeI6YktizRgnEVFqH0rCOjMO5Rc+KX8AfNOrK5PnD54LguSuKSH7qi
19
-j04OKgWTSd43lF90+y63RtCFnibQDpp2HwrBJAQFk7EEP/XMJfnPLN/SbuMSADgM
20
-kg8kPTFRW5Iw3DYz9z9WpE0CgYAkn6/8Q2XMbUOFqti9JEa8Lg8sYk5VdwuNbPMA
21
-3QMYKQUk9ieyLB4c3Nik3+XCuyVUKEc31A5egmz3umu7cn8i6vGuiJ/k/8t2YZ7s
22
-Bry5Ihu95Yzab5DW3Eiqs0xKQN79ebS9AluAwQO5Wy2h52rknfuDHIm/M+BHsSoS
23
-xl5KFQKBgQCokCsYuX1z2GojHw369/R2aX3ovCGuHqy4k7fWxUrpHTHvth2+qNPr
24
-84qLJ9rLWoZE5sUiZ5YdwCgW877EdfkT+v4aaBX79ixso5VdqgJ/PdnoNntah/Vq
25
-njQiW1skn6/P5V/eyimN2n0VsyBr/zMDEtYTRP/Tb1zi/njFLQkZEA==
26 1
deleted file mode 100644
... ...
@@ -1,21 +0,0 @@
1
-MIIDhTCCAm2gAwIBAgIJAIq8naKlYAQfMA0GCSqGSIb3DQEBCwUAMFcxCzAJBgNV
2
-BAYTAlVTMQswCQYDVQQIEwJDQTEVMBMGA1UEBxMMU2FuRnJhbmNpc2NvMQ8wDQYD
3
-VQQKEwZEb2NrZXIxEzARBgNVBAMTCmRlbGVnYXRpb24wHhcNMTYwOTI4MTc0ODQ4
4
-WhcNMjYwNjI4MTc0ODQ4WjBXMQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExFTAT
5
-BgNVBAcTDFNhbkZyYW5jaXNjbzEPMA0GA1UEChMGRG9ja2VyMRMwEQYDVQQDEwpk
6
-ZWxlZ2F0aW9uMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyY2EWYTW
7
-5VHipw08t675upmD6a+akiuZ1z+XpuOxZCgjZ0aHfoOe8wGKg3Ohz7UCBdD5Mob/
8
-L/qvRlsCaqPHGZKIyyX1HDO4mpuQQFBhYxt+ZAO3AaawEUOw2rwwMDEjLnDDTSZM
9
-z8jxCMvsJjBDqgb8g3z+AmjducQ/OH6llldgHIBY8ioRbROCL2PGgqywWq2fThav
10
-c70YMxtKviBGDNCouYeQ8JMK/PuLwPNDXNQAagFHVARXiUv/ILHk7ImYnSGJUcuk
11
-JTUGN2MBnpY0eakg7i+4za8sjjqOdn+2I6aVzlGJDSiRP72nkg/cE4BqMl9FrMwK
12
-9iS8xa9yMDLUvwIDAQABo1QwUjAMBgNVHRMBAf8EAjAAMA4GA1UdDwEB/wQEAwIF
13
-oDATBgNVHSUEDDAKBggrBgEFBQcDAzAdBgNVHQ4EFgQUvQzzFmh3Sv3HcdExY3wx
14
-/1u6JLAwDQYJKoZIhvcNAQELBQADggEBAJcmDme2Xj/HPUPwaN/EyCmjhY73EiHO
15
-x6Pm16tscg5JGn5A+u3CZ1DmxUYl8Hp6MaW/sWzdtL0oKJg76pynadCWh5EacFR8
16
-u+2GV/IcN9mSX6JQzvrqbjSqo5/FehqBD+W5h3euwwApWA3STAadYeyEfmdOA3SQ
17
-W1vzrA1y7i8qgTqeJ7UX1sEAXlIhBK2zPYaMB+en+ZOiPyNxJYj6IDdGdD2paC9L
18
-6H9wKC+GAUTSdCWp89HP7ETSXEGr94AXkrwU+qNsiN+OyK8ke0EMngEPh5IQoplw
19
-/7zEZCth3oKxvR1/4S5LmTVaHI2ZlbU4q9bnY72G4tw8YQr2gcBGo4w=
20 1
deleted file mode 100644
... ...
@@ -1,27 +0,0 @@
1
-MIIEogIBAAKCAQEAyY2EWYTW5VHipw08t675upmD6a+akiuZ1z+XpuOxZCgjZ0aH
2
-foOe8wGKg3Ohz7UCBdD5Mob/L/qvRlsCaqPHGZKIyyX1HDO4mpuQQFBhYxt+ZAO3
3
-AaawEUOw2rwwMDEjLnDDTSZMz8jxCMvsJjBDqgb8g3z+AmjducQ/OH6llldgHIBY
4
-8ioRbROCL2PGgqywWq2fThavc70YMxtKviBGDNCouYeQ8JMK/PuLwPNDXNQAagFH
5
-VARXiUv/ILHk7ImYnSGJUcukJTUGN2MBnpY0eakg7i+4za8sjjqOdn+2I6aVzlGJ
6
-DSiRP72nkg/cE4BqMl9FrMwK9iS8xa9yMDLUvwIDAQABAoIBAHmffvzx7ydESWwa
7
-zcfdu26BkptiTvjjfJrqEd4wSewxWGPKqJqMXE8xX99A2KTZClZuKuH1mmnecQQY
8
-iRXGrK9ewFMuHYGeKEiLlPlqR8ohXhyGLVm+t0JDwaXMp5t9G0i73O5iLTm5fNGd
9
-FGxa9YnVW20Q8MqNczbVGH1D1zInhxzzOyFzBd4bBBJ8PdrUdyLpd7+RxY2ghnbT
10
-p9ZANR2vk5zmDLJgZx72n/u+miJWuhY6p0v3Vq4z/HHgdhf+K6vpDdzTcYlA0rO4
11
-c/c+RKED3ZadGUD5QoLsmEN0e3FVSMPN1kt4ZRTqWfH8f2X4mLz33aBryTjktP6+
12
-1rX6ThECgYEA74wc1Tq23B5R0/GaMm1AK3Ko2zzTD8wK7NSCElh2dls02B+GzrEB
13
-aE3A2GMQSuzb+EA0zkipwANBaqs3ZemH5G1pu4hstQsXCMd4jAJn0TmTXlplXBCf
14
-PSc8ZUU6XcJENRr9Q7O9/TGlgahX+z0ndxYx/CMCsSu7XsMg4IZsbAcCgYEA12Vb
15
-wKOVG15GGp7pMshr+2rQfVimARUP4gf3JnQmenktI4PfdnMW3a4L3DEHfLhIerwT
16
-6lRp/NpxSADmuT4h1UO1l2lc+gmTVPw0Vbl6VwHpgS5Kfu4ZyM6n3S66f/dE4nu7
17
-hQF9yZz7vn5Agghak4p6a1wC1gdMzR1tvxFzk4kCgYByBMTskWfcWeok8Yitm+bB
18
-R3Ar+kWT7VD97SCETusD5uG+RTNLSmEbHnc+B9kHcLo67YS0800pAeOvPBPARGnU
19
-RmffRU5I1iB+o0MzkSmNItSMQoagTaEd4IEUyuC/I+qHRHNsOC+kRm86ycAm67LP
20
-MhdUpe1wGxqyPjp15EXTHQKBgDKzFu+3EWfJvvKRKQ7dAh3BvKVkcl6a2Iw5l8Ej
21
-YdM+JpPPfI/i8yTmzL/dgoem0Nii4IUtrWzo9fUe0TAVId2S/HFRSaNJEbbVTnRH
22
-HjbQqmfPv5U08jjD+9siHp/0UfCFc1QRT8xe+RqTmReCY9+KntoaZEiAm2FEZgqt
23
-TukRAoGAf7QqbTP5/UH1KSkX89F5qy/6GS3pw6TLj9Ufm/l/NO8Um8gag6YhEKWR
24
-7HpkpCqjfWj8Av8ESR9cqddPGrbdqXFm9z7dCjlAd5T3Q3h/h+v+JzLQWbsI6WOb
25
-SsOSWNyE006ZZdIiFwO6GfxpLI24sVtYKgyob6Q71oxSqfnrnT0=
26 1
deleted file mode 100644
... ...
@@ -1,21 +0,0 @@
1
-MIIDhTCCAm2gAwIBAgIJAKHt/jxiWqMtMA0GCSqGSIb3DQEBCwUAMFcxCzAJBgNV
2
-BAYTAlVTMQswCQYDVQQIEwJDQTEVMBMGA1UEBxMMU2FuRnJhbmNpc2NvMQ8wDQYD
3
-VQQKEwZEb2NrZXIxEzARBgNVBAMTCmRlbGVnYXRpb24wHhcNMTYwOTI4MTc0ODQ5
4
-WhcNMjYwNjI4MTc0ODQ5WjBXMQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExFTAT
5
-BgNVBAcTDFNhbkZyYW5jaXNjbzEPMA0GA1UEChMGRG9ja2VyMRMwEQYDVQQDEwpk
6
-ZWxlZ2F0aW9uMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqfbJk2Dk
7
-C9FJVjV2+Q2CQrJphG3vFc1Qlu9jgVA5RhGmF9jJzetsclsV/95nBhinIGcSmPQA
8
-l318G7Bz/cG/6O2n5+hj+S1+YOvQweReZj3d4kCeS86SOyLNTpMD9gsF0S8nR1RN
9
-h0jD4t1vxAVeGD1o61U8/k0O5eDoeOfOSWZagKk5PhyrMZgNip4IrG46umCkFlrw
10
-zMMcgQdwTQXywPqkr/LmYpqT1WpMlzHYTQEY8rKorIJQbPtHVYdr4UxYnNmk6fbU
11
-biEP1DQlwjBWcFTsDLqXKP/K+e3O0/e/hMB0y7Tj9fZ7Viw0t5IKXZPsxMhwknUT
12
-9vmPzIJO6NiniwIDAQABo1QwUjAMBgNVHRMBAf8EAjAAMA4GA1UdDwEB/wQEAwIF
13
-oDATBgNVHSUEDDAKBggrBgEFBQcDAzAdBgNVHQ4EFgQUdTXRP1EzxQ+UDZSoheVo
14
-Mobud1cwDQYJKoZIhvcNAQELBQADggEBADV9asTWWdbmpkeRuKyi0xGho39ONK88
15
-xxkFlco766BVgemo/rGQj3oPuw6M6SzHFoJ6JUPjmLiAQDIGEU/2/b6LcOuLjP+4
16
-YejCcDTY3lSW/HMNoAmzr2foo/LngNGfe/qhVFUqV7GjFT9+XzFFBfIZ1cQiL2ed
17
-kc8rgQxFPwWXFCSwaENWeFnMDugkd+7xanoAHq8GsJpg5fTruDTmJkUqC2RNiMLn
18
-WM7QaqW7+lmUnMnc1IBoz0hFhgoiadWM/1RQxx51zTVw6Au1koIm4ZXu5a+/WyC8
19
-K1+HyUbc0AVaDaRBpRSOR9aHRwLGh6WQ4aUZQNyJroc999qfYrDEEV8=
20 1
deleted file mode 100644
... ...
@@ -1,27 +0,0 @@
1
-MIIEpQIBAAKCAQEAqfbJk2DkC9FJVjV2+Q2CQrJphG3vFc1Qlu9jgVA5RhGmF9jJ
2
-zetsclsV/95nBhinIGcSmPQAl318G7Bz/cG/6O2n5+hj+S1+YOvQweReZj3d4kCe
3
-S86SOyLNTpMD9gsF0S8nR1RNh0jD4t1vxAVeGD1o61U8/k0O5eDoeOfOSWZagKk5
4
-PhyrMZgNip4IrG46umCkFlrwzMMcgQdwTQXywPqkr/LmYpqT1WpMlzHYTQEY8rKo
5
-rIJQbPtHVYdr4UxYnNmk6fbUbiEP1DQlwjBWcFTsDLqXKP/K+e3O0/e/hMB0y7Tj
6
-9fZ7Viw0t5IKXZPsxMhwknUT9vmPzIJO6NiniwIDAQABAoIBAQCAr/ed3A2umO7T
7
-FDYZik3nXBiiiW4t7r+nGGgZ3/kNgY1lnuHlROxehXLZwbX1mrLnyML/BjhwezV9
8
-7ZNVPd6laVPpNj6DyxtWHRZ5yARlm1Al39E7CpQTrF0QsiWcpGnqIa62xjDRTpnq
9
-askV/Q5qggyvqmE9FnFCQpEiAjlhvp7F0kVHVJm9s3MK3zSyR0UTZ3cpYus2Jr2z
10
-OotHgAMHq5Hgb3dvxOeE2xRMeYAVDujbkNzXm2SddAtiRdLhWDh7JIr3zXhp0HyN
11
-4rLOyhlgz00oIGeDt/C0q3fRmghr3iZOG+7m2sUx0FD1Ru1dI9v2A+jYmIVNW6+x
12
-YJk5PzxJAoGBANDj7AGdcHSci/LDBPoTTUiz3uucAd27/IJma/iy8mdbVfOAb0Fy
13
-PRSPvoozlpZyOxg2J4eH/o4QxQR4lVKtnLKZLNHK2tg3LarwyBX1LiI3vVlB+DT1
14
-AmV8i5bJAckDhqFeEH5qdWZFi03oZsSXWEqX5iMYCrdK5lTZggcrFZeHAoGBANBL
15
-fkk3knAdcVfTYpmHx18GBi2AsCWTd20KD49YBdbVy0Y2Jaa1EJAmGWpTUKdYx40R
16
-H5CuGgcAviXQz3bugdTU1I3tAclBtpJNU7JkhuE+Epz0CM/6WERJrE0YxcGQA5ui
17
-6fOguFyiXD1/85jrDBOKy74aoS7lYz9r/a6eqmjdAoGBAJpm/nmrIAZx+Ff2ouUe
18
-A1Ar9Ch/Zjm5zEmu3zwzOU4AiyWz14iuoktifNq2iyalRNz+mnVpplToPFizsNwu
19
-C9dPtXtU0DJlhtIFrD/evLz6KnGhe4/ZUm4lgyBvb2xfuNHqL5Lhqelwmil6EQxb
20
-Oh3Y7XkfOjyFln89TwlxZUJdAoGAJRMa4kta7EvBTeGZLjyltvsqhFTghX+vBSCC
21
-ToBbYbbiHJgssXSPAylU4sD7nR3HPwuqM6VZip+OOMrm8oNXZpuPTce+xqTEq1vK
22
-JvmPrG3RAFDLdMFZjqYSXhKnuGE60yv3Ol8EEbDwfB3XLQPBPYU56Jdy0xcPSE2f
23
-dMJXEJ0CgYEAisZw0nXw6lFeYecu642EGuU0wv1O9i21p7eho9QwOcsoTl4Q9l+M
24
-M8iBv+qTHO+D19l4JbkGvy2H2diKoYduUFACcuiFYs8fjrT+4Z6DyOQAQGAf6Ylw
25
-BFbU15k6KbA9v4mZDfd1tY9x62L/XO55ZxYG+J+q0e26tEThgD8cEog=
26 1
deleted file mode 100644
... ...
@@ -1,21 +0,0 @@
1
-MIIDhTCCAm2gAwIBAgIJANae++ZkUEWMMA0GCSqGSIb3DQEBCwUAMFcxCzAJBgNV
2
-BAYTAlVTMQswCQYDVQQIEwJDQTEVMBMGA1UEBxMMU2FuRnJhbmNpc2NvMQ8wDQYD
3
-VQQKEwZEb2NrZXIxEzARBgNVBAMTCmRlbGVnYXRpb24wHhcNMTYwOTI4MTc0ODQ5
4
-WhcNMjYwNjI4MTc0ODQ5WjBXMQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExFTAT
5
-BgNVBAcTDFNhbkZyYW5jaXNjbzEPMA0GA1UEChMGRG9ja2VyMRMwEQYDVQQDEwpk
6
-ZWxlZ2F0aW9uMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqULAjgba
7
-Y2I10WfqdmYnPfEqEe6iMDbzcgECb2xKafXcI4ltkQj1iO4zBTs0Ft9EzXFc5ZBh
8
-pTjZrL6vrIa0y/CH2BiIHBJ0wRHx/40HXp4DSj3HZpVOlEMI3npRfBGNIBllUaRN
9
-PWG7zL7DcKMIepBfPXyjBsxzH3yNiISq0W5hSiy+ImhSo3aipJUHHcp9Z9NgvpNC
10
-3QvnxsGKRnECmDRDlxkq+FQu9Iqs/HWFYWgyfcsw+YTrWZq3qVnnqUouHO//c9PG
11
-Ry3sZSDU97MwvkjvWys1e01Xvd3AbHx08YAsxih58i/OBKe81eD9NuZDP2KrjTxI
12
-5xkXKhj6DV2NnQIDAQABo1QwUjAMBgNVHRMBAf8EAjAAMA4GA1UdDwEB/wQEAwIF
13
-oDATBgNVHSUEDDAKBggrBgEFBQcDAzAdBgNVHQ4EFgQUDt95hiqbQvi0KcvZGAUu
14
-VisnztQwDQYJKoZIhvcNAQELBQADggEBAGi7qHai7MWbfeu6SlXhzIP3AIMa8TMi
15
-lp/+mvPUFPswIVqYJ71MAN8uA7CTH3z50a2vYupGeOEtZqVJeRf+xgOEpwycncxp
16
-Qz6wc6TWPVIoT5q1Hqxw1RD2MyKL+Y+QBDYwFxFkthpDMlX48I9frcqoJUWFxBF2
17
-lnRr/cE7BbPE3sMbXV3wGPlH7+eUf+CgzXJo2HB6THzagyEgNrDiz/0rCQa1ipFd
18
-mNU3D/U6BFGmJNxhvSOtXX9escg8yjr05YwwzokHS2K4jE0ZuJPBd50C/Rvo3Mf4
19
-0h7/2Q95e7d42zPe9WYPu2F8KTWsf4r+6ddhKrKhYzXIcTAfHIOiO+U=
20 1
deleted file mode 100644
... ...
@@ -1,27 +0,0 @@
1
-MIIEpAIBAAKCAQEAqULAjgbaY2I10WfqdmYnPfEqEe6iMDbzcgECb2xKafXcI4lt
2
-kQj1iO4zBTs0Ft9EzXFc5ZBhpTjZrL6vrIa0y/CH2BiIHBJ0wRHx/40HXp4DSj3H
3
-ZpVOlEMI3npRfBGNIBllUaRNPWG7zL7DcKMIepBfPXyjBsxzH3yNiISq0W5hSiy+
4
-ImhSo3aipJUHHcp9Z9NgvpNC3QvnxsGKRnECmDRDlxkq+FQu9Iqs/HWFYWgyfcsw
5
-+YTrWZq3qVnnqUouHO//c9PGRy3sZSDU97MwvkjvWys1e01Xvd3AbHx08YAsxih5
6
-8i/OBKe81eD9NuZDP2KrjTxI5xkXKhj6DV2NnQIDAQABAoIBAGK0ZKnuYSiXux60
7
-5MvK4pOCsa/nY3mOcgVHhW4IzpRgJdIrcFOlz9ncXrBsSAIWjX7o3u2Ydvjs4DOW
8
-t8d6frB3QiDInYcRVDjLCD6otWV97Bk9Ua0G4N4hAWkMF7ysV4oihS1JDSoAdo39
9
-qOdki6s9yeyHZGKwk2oHLlowU5TxQMBA8DHmxqBII1HTm+8xRz45bcEqRXydYSUn
10
-P1JuSU9jFqdylxU+Nrq6ehslMQ3y7qNWQyiLGxu6EmR+vgrzSU0s3iAOqCHthaOS
11
-VBBXPL3DNEYUS+0QGnGrACuJhanOMBfdiO6Orelx6ZzWZm38PNGv0yBt0WCM+8/A
12
-TtQNGkECgYEA1LqR6AH9XikUQ0+rM4526BgVuYqtjw21h4Lj9alaA+YTQntBBJOv
13
-iAcUpnJiV4T8jzAMLeqpK8R/rbxRnK5S9jOV2gr+puk4L6tH46cgahBUESDigDp8
14
-6vK8ur6ubBcXNPh3AT6rsPj+Ph2EU3raqiYdouvCdga/OCYZb+jr6UkCgYEAy7Cr
15
-l8WssI/8/ORcQ4MFJFNyfz/Y2beNXyLd1PX0H+wRSiGcKzeUuTHNtzFFpMbrK/nx
16
-ZOPCT2ROdHsBHzp1L+WquCb0fyMVSiYiXBU+VCFDbUU5tBr3ycTc7VwuFPENOiha
17
-IdlWgew/aW110FQHIaqe9g+htRe+mXe++faZtbUCgYB/MSJmNzJX53XvHSZ/CBJ+
18
-iVAMBSfq3caJRLCqRNzGcf1YBbwFUYxlZ95n+wJj0+byckcF+UW3HqE8rtmZNf3y
19
-qTtTCLnj8JQgpGeybU4LPMIXD7N9+fqQvBwuCC7gABpnGJyHCQK9KNNTLnDdPRqb
20
-G3ki3ZYC3dvdZaJV8E2FyQKBgQCMa5Mf4kqWvezueo+QizZ0QILibqWUEhIH0AWV
21
-1qkhiKCytlDvCjYhJdBnxjP40Jk3i+t6XfmKud/MNTAk0ywOhQoYQeKz8v+uSnPN
22
-f2ekn/nXzq1lGGJSWsDjcXTjQvqXaVIZm7cjgjaE+80IfaUc9H75qvUT3vaq3f5u
23
-XC7DMQKBgQDMAzCCpWlEPbZoFMl6F49+7jG0/TiqM/WRUSQnNtufPMbrR9Je4QM1
24
-L1UCANCPaHFOncKYer15NfIV1ctt5MZKImevDsUaQO8CUlO+dzd5H8KvHw9E29gA
25
-B22v8k3jIjsYeRL+UJ/sBnWHgxdAe/NEM+TdlP2oP9D1gTifutPqAg==
26 1
deleted file mode 100755
... ...
@@ -1,18 +0,0 @@
1
-for selfsigned in delgkey1 delgkey2 delgkey3 delgkey4; do
2
-        subj='/C=US/ST=CA/L=SanFrancisco/O=Docker/CN=delegation'
3
-
4
-        openssl genrsa -out "${selfsigned}.key" 2048
5
-        openssl req -new -key "${selfsigned}.key" -out "${selfsigned}.csr" -sha256 -subj "${subj}"
6
-        cat > "${selfsigned}.cnf" <<EOL
7
-[selfsigned]
8
-basicConstraints = critical,CA:FALSE
9
-keyUsage = critical, digitalSignature, keyEncipherment
10
-extendedKeyUsage=codeSigning
11
-subjectKeyIdentifier=hash
12
-EOL
13
-
14
-        openssl x509 -req -days 3560 -in "${selfsigned}.csr" -signkey "${selfsigned}.key" -sha256 \
15
-                -out "${selfsigned}.crt" -extfile "${selfsigned}.cnf" -extensions selfsigned
16
-
17
-        rm "${selfsigned}.cnf" "${selfsigned}.csr"
18
-done
19 1
deleted file mode 100644
... ...
@@ -1,19 +0,0 @@
1
-MIIDCTCCAfOgAwIBAgIQTOoFF+ypXwgdXnXHuCTvYDALBgkqhkiG9w0BAQswJjER
2
-MA8GA1UEChMIUXVpY2tUTFMxETAPBgNVBAMTCFF1aWNrVExTMB4XDTE1MDcxNzE5
3
-NDg1M1oXDTE4MDcwMTE5NDg1M1owJzERMA8GA1UEChMIUXVpY2tUTFMxEjAQBgNV
4
-BAMTCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMDO
5
-qvTBAi0ApXLfe90ApJkdkRGwF838Qzt1UFSxomu5fHRV6l3FjX5XCVHiFQ4w3ROh
6
-dMOu9NahfGLJv9VvWU2MV3YoY9Y7lIXpKwnK1v064wuls4nPh13BUWKQKofcY/e2
7
-qaSPd6/qmSRc/kJUvOI9jZMSX6ZRPu9K4PCqm2CivlbLq9UYuo1AbRGfuqHRvTxg
8
-mQG7WQCzGSvSjuSg5qX3TEh0HckTczJG9ODULNRWNE7ld0W4sfv4VF8R7Uc/G7LO
9
-8QwLCZ9TIl3gYMPCrhUL3Q6z9Jnn1SQS4mhDnPi6ugRYO1X8k3jjdxV9C2sXwUvN
10
-OZI1rLEWl9TJNA7ZXtMCAwEAAaM2MDQwDgYDVR0PAQH/BAQDAgCgMAwGA1UdEwEB
11
-/wQCMAAwFAYDVR0RBA0wC4IJbG9jYWxob3N0MAsGCSqGSIb3DQEBCwOCAQEAH6iq
12
-kM2+UMukGDLEQKHHiauioWJlHDlLXv76bJiNfjSz94B/2XOQMb9PT04//tnGUyPK
13
-K8Dx7RoxSodU6T5VRiz/A36mLOvt2t3bcL/1nHf9sAOHcexGtnCbQbW91V7RKfIL
14
-sjiLNFDkQ9VfVNY+ynQptZoyH1sy07+dplfkIiPzRs5WuVAnEGsX3r6BrhgUITzi
15
-g1B4kpmGZIohP4m6ZEBY5xuo/NQ0+GhjAENQMU38GpuoMyFS0i0dGcbx8weqnI/B
16
-Er/qa0+GE/rBnWY8TiRow8dzpneSFQnUZpJ4EwD9IoOIDHo7k2Nbz2P50HMiCXZf
17
-4RqzctVssRlrRVnO5w==
18 1
deleted file mode 100644
... ...
@@ -1,27 +0,0 @@
1
-MIIEogIBAAKCAQEAwM6q9MECLQClct973QCkmR2REbAXzfxDO3VQVLGia7l8dFXq
2
-XcWNflcJUeIVDjDdE6F0w6701qF8Ysm/1W9ZTYxXdihj1juUhekrCcrW/TrjC6Wz
3
-ic+HXcFRYpAqh9xj97appI93r+qZJFz+QlS84j2NkxJfplE+70rg8KqbYKK+Vsur
4
-1Ri6jUBtEZ+6odG9PGCZAbtZALMZK9KO5KDmpfdMSHQdyRNzMkb04NQs1FY0TuV3
5
-Rbix+/hUXxHtRz8bss7xDAsJn1MiXeBgw8KuFQvdDrP0mefVJBLiaEOc+Lq6BFg7
6
-VfyTeON3FX0LaxfBS805kjWssRaX1Mk0Dtle0wIDAQABAoIBAHbuhNHZROhRn70O
7
-Ui9vOBki/dt1ThnH5AkHQngb4t6kWjrAzILvW2p1cdBKr0ZDqftz+rzCbVD/5+Rg
8
-Iq8bsnB9g23lWEBMHD/GJsAxmRA3hNooamk11IBmwTcVSsbnkdq5mEdkICYphjHC
9
-Ey0DbEf6RBxWlx3WvAWLoNmTw6iFaOCH8IyLavPpe7kLbZc219oNUw2qjCnCXCZE
10
-/NuViADHJBPN8r7g1gmyclJmTumdUK6oHgXEMMPe43vhReGcgcReK9QZjnTcIXPM
11
-4oJOraw+BtoZXVvvIPnC+5ntoLFOzjIzM0kaveReZbdgffqF4zy2vRfCHhWssanc
12
-7a0xR4ECgYEA3Xuvcqy5Xw+v/jVCO0VZj++Z7apA78dY4tWsPx5/0DUTTziTlXkC
13
-ADduEbwX6HgZ/iLvA9j4C3Z4mO8qByby/6UoBU8NEe+PQt6fT7S+dKSP4uy5ZxVM
14
-i5opkEyrJsMbve9Jrlj4bk5CICsydrZ+SBFHnpNGjbduGQick5LORWECgYEA3trt
15
-gepteDGiUYmnnBgjbYtcD11RvpKC8Z/QwGnzN5vk4eBu8r7DkMcLN+SiHjAovlJo
16
-r5j3EbF8sla1zBf/yySdQZFqUGcwtw7MaAKCLdhQl5WsViNMIx6p2OJapu0dzbv2
17
-KTXrnoRCafcH92k0dUX1ahE9eyc8KX6VhbWwXLMCgYATGCCuEDoC+gVAMzM8jOQF
18
-xrBMjwr+IP+GvskUv/pg5tJ9V/FRR5dmkWDJ4p9lCUWkZTqZ6FCqHFKVTLkg2LjG
19
-VWS34HLOAwskxrCRXJG22KEW/TWWr31j46yFpjZzJwrzOvftMfpo+BI3V8IH/f+x
20
-EtxLzYKdoRy6x8VH67YgwQKBgHor2vjV45142FuK83AHa6SqOZXSuvWWrGJ6Ep7p
21
-doSN2jRaLXi2S9AaznOdy6JxFGUCGJHrcccpXgsGrjNtFLXxJKTFa1sYtwQkALsk
22
-ZOltJQF09D1krGC0driHntrUMvqOiKye+sS0DRS6cIuaCUAhUiELwoC5SaoV0zKy
23
-IDUxAoGAOK8Xq+3/sqe79vTpw25RXl+nkAmOAeKjqf3Kh6jbnBhr81rmefyKXB9a
24
-uj0b980tzUnliwA5cCOsyxfN2vASvMnJxFE721QZI04arlcPFHcFqCtmNnUYTcLp
25
-0hgn/yLZptcoxpy+eTBu3eNsxz1Bu/Tx/198+2Wr3MbtGpLNIcA=
26 1
deleted file mode 100644
... ...
@@ -1,34 +0,0 @@
1
-package main
2
-
3
-import (
4
-	"fmt"
5
-	"net"
6
-	"net/http"
7
-	"os"
8
-	"path/filepath"
9
-)
10
-
11
-func main() {
12
-	p, err := filepath.Abs(filepath.Join("run", "docker", "plugins"))
13
-	if err != nil {
14
-		panic(err)
15
-	}
16
-	if err := os.MkdirAll(p, 0755); err != nil {
17
-		panic(err)
18
-	}
19
-	l, err := net.Listen("unix", filepath.Join(p, "basic.sock"))
20
-	if err != nil {
21
-		panic(err)
22
-	}
23
-
24
-	mux := http.NewServeMux()
25
-	server := http.Server{
26
-		Addr:    l.Addr().String(),
27
-		Handler: http.NewServeMux(),
28
-	}
29
-	mux.HandleFunc("/Plugin.Activate", func(w http.ResponseWriter, r *http.Request) {
30
-		w.Header().Set("Content-Type", "application/vnd.docker.plugins.v1.1+json")
31
-		fmt.Println(w, `{"Implements": ["dummy"]}`)
32
-	})
33
-	server.Serve(l)
34
-}
35 1
deleted file mode 100644
... ...
@@ -1,215 +0,0 @@
1
-package plugin // import "github.com/docker/docker/integration-cli/fixtures/plugin"
2
-
3
-import (
4
-	"encoding/json"
5
-	"io"
6
-	"io/ioutil"
7
-	"os"
8
-	"os/exec"
9
-	"path/filepath"
10
-	"time"
11
-
12
-	"github.com/docker/docker/api/types"
13
-	"github.com/docker/docker/pkg/archive"
14
-	"github.com/docker/docker/plugin"
15
-	"github.com/docker/docker/registry"
16
-	"github.com/pkg/errors"
17
-	"golang.org/x/net/context"
18
-)
19
-
20
-// CreateOpt is is passed used to change the default plugin config before
21
-// creating it
22
-type CreateOpt func(*Config)
23
-
24
-// Config wraps types.PluginConfig to provide some extra state for options
25
-// extra customizations on the plugin details, such as using a custom binary to
26
-// create the plugin with.
27
-type Config struct {
28
-	*types.PluginConfig
29
-	binPath string
30
-}
31
-
32
-// WithBinary is a CreateOpt to set an custom binary to create the plugin with.
33
-// This binary must be statically compiled.
34
-func WithBinary(bin string) CreateOpt {
35
-	return func(cfg *Config) {
36
-		cfg.binPath = bin
37
-	}
38
-}
39
-
40
-// CreateClient is the interface used for `BuildPlugin` to interact with the
41
-// daemon.
42
-type CreateClient interface {
43
-	PluginCreate(context.Context, io.Reader, types.PluginCreateOptions) error
44
-}
45
-
46
-// Create creates a new plugin with the specified name
47
-func Create(ctx context.Context, c CreateClient, name string, opts ...CreateOpt) error {
48
-	tmpDir, err := ioutil.TempDir("", "create-test-plugin")
49
-	if err != nil {
50
-		return err
51
-	}
52
-	defer os.RemoveAll(tmpDir)
53
-
54
-	tar, err := makePluginBundle(tmpDir, opts...)
55
-	if err != nil {
56
-		return err
57
-	}
58
-	defer tar.Close()
59
-
60
-	ctx, cancel := context.WithTimeout(ctx, 30*time.Second)
61
-	defer cancel()
62
-
63
-	return c.PluginCreate(ctx, tar, types.PluginCreateOptions{RepoName: name})
64
-}
65
-
66
-// CreateInRegistry makes a plugin (locally) and pushes it to a registry.
67
-// This does not use a dockerd instance to create or push the plugin.
68
-// If you just want to create a plugin in some daemon, use `Create`.
69
-//
70
-// This can be useful when testing plugins on swarm where you don't really want
71
-// the plugin to exist on any of the daemons (immediately) and there needs to be
72
-// some way to distribute the plugin.
73
-func CreateInRegistry(ctx context.Context, repo string, auth *types.AuthConfig, opts ...CreateOpt) error {
74
-	tmpDir, err := ioutil.TempDir("", "create-test-plugin-local")
75
-	if err != nil {
76
-		return err
77
-	}
78
-	defer os.RemoveAll(tmpDir)
79
-
80
-	inPath := filepath.Join(tmpDir, "plugin")
81
-	if err := os.MkdirAll(inPath, 0755); err != nil {
82
-		return errors.Wrap(err, "error creating plugin root")
83
-	}
84
-
85
-	tar, err := makePluginBundle(inPath, opts...)
86
-	if err != nil {
87
-		return err
88
-	}
89
-	defer tar.Close()
90
-
91
-	dummyExec := func(m *plugin.Manager) (plugin.Executor, error) {
92
-		return nil, nil
93
-	}
94
-
95
-	regService, err := registry.NewService(registry.ServiceOptions{V2Only: true})
96
-	if err != nil {
97
-		return err
98
-	}
99
-
100
-	managerConfig := plugin.ManagerConfig{
101
-		Store:           plugin.NewStore(),
102
-		RegistryService: regService,
103
-		Root:            filepath.Join(tmpDir, "root"),
104
-		ExecRoot:        "/run/docker", // manager init fails if not set
105
-		CreateExecutor:  dummyExec,
106
-		LogPluginEvent:  func(id, name, action string) {}, // panics when not set
107
-	}
108
-	manager, err := plugin.NewManager(managerConfig)
109
-	if err != nil {
110
-		return errors.Wrap(err, "error creating plugin manager")
111
-	}
112
-
113
-	ctx, cancel := context.WithTimeout(ctx, 30*time.Second)
114
-	defer cancel()
115
-	if err := manager.CreateFromContext(ctx, tar, &types.PluginCreateOptions{RepoName: repo}); err != nil {
116
-		return err
117
-	}
118
-
119
-	if auth == nil {
120
-		auth = &types.AuthConfig{}
121
-	}
122
-	err = manager.Push(ctx, repo, nil, auth, ioutil.Discard)
123
-	return errors.Wrap(err, "error pushing plugin")
124
-}
125
-
126
-func makePluginBundle(inPath string, opts ...CreateOpt) (io.ReadCloser, error) {
127
-	p := &types.PluginConfig{
128
-		Interface: types.PluginConfigInterface{
129
-			Socket: "basic.sock",
130
-			Types:  []types.PluginInterfaceType{{Capability: "docker.dummy/1.0"}},
131
-		},
132
-		Entrypoint: []string{"/basic"},
133
-	}
134
-	cfg := &Config{
135
-		PluginConfig: p,
136
-	}
137
-	for _, o := range opts {
138
-		o(cfg)
139
-	}
140
-	if cfg.binPath == "" {
141
-		binPath, err := ensureBasicPluginBin()
142
-		if err != nil {
143
-			return nil, err
144
-		}
145
-		cfg.binPath = binPath
146
-	}
147
-
148
-	configJSON, err := json.Marshal(p)
149
-	if err != nil {
150
-		return nil, err
151
-	}
152
-	if err := ioutil.WriteFile(filepath.Join(inPath, "config.json"), configJSON, 0644); err != nil {
153
-		return nil, err
154
-	}
155
-	if err := os.MkdirAll(filepath.Join(inPath, "rootfs", filepath.Dir(p.Entrypoint[0])), 0755); err != nil {
156
-		return nil, errors.Wrap(err, "error creating plugin rootfs dir")
157
-	}
158
-
159
-	// Ensure the mount target paths exist
160
-	for _, m := range p.Mounts {
161
-		var stat os.FileInfo
162
-		if m.Source != nil {
163
-			stat, err = os.Stat(*m.Source)
164
-			if err != nil && !os.IsNotExist(err) {
165
-				return nil, err
166
-			}
167
-		}
168
-
169
-		if stat == nil || stat.IsDir() {
170
-			var mode os.FileMode = 0755
171
-			if stat != nil {
172
-				mode = stat.Mode()
173
-			}
174
-			if err := os.MkdirAll(filepath.Join(inPath, "rootfs", m.Destination), mode); err != nil {
175
-				return nil, errors.Wrap(err, "error preparing plugin mount destination path")
176
-			}
177
-		} else {
178
-			if err := os.MkdirAll(filepath.Join(inPath, "rootfs", filepath.Dir(m.Destination)), 0755); err != nil {
179
-				return nil, errors.Wrap(err, "error preparing plugin mount destination dir")
180
-			}
181
-			f, err := os.Create(filepath.Join(inPath, "rootfs", m.Destination))
182
-			if err != nil && !os.IsExist(err) {
183
-				return nil, errors.Wrap(err, "error preparing plugin mount destination file")
184
-			}
185
-			if f != nil {
186
-				f.Close()
187
-			}
188
-		}
189
-	}
190
-	if err := archive.NewDefaultArchiver().CopyFileWithTar(cfg.binPath, filepath.Join(inPath, "rootfs", p.Entrypoint[0])); err != nil {
191
-		return nil, errors.Wrap(err, "error copying plugin binary to rootfs path")
192
-	}
193
-	tar, err := archive.Tar(inPath, archive.Uncompressed)
194
-	return tar, errors.Wrap(err, "error making plugin archive")
195
-}
196
-
197
-func ensureBasicPluginBin() (string, error) {
198
-	name := "docker-basic-plugin"
199
-	p, err := exec.LookPath(name)
200
-	if err == nil {
201
-		return p, nil
202
-	}
203
-
204
-	goBin, err := exec.LookPath("go")
205
-	if err != nil {
206
-		return "", err
207
-	}
208
-	installPath := filepath.Join(os.Getenv("GOPATH"), "bin", name)
209
-	cmd := exec.Command(goBin, "build", "-o", installPath, "./"+filepath.Join("fixtures", "plugin", "basic"))
210
-	cmd.Env = append(cmd.Env, "CGO_ENABLED=0")
211
-	if out, err := cmd.CombinedOutput(); err != nil {
212
-		return "", errors.Wrapf(err, "error building basic plugin bin: %s", string(out))
213
-	}
214
-	return installPath, nil
215
-}
216 1
deleted file mode 100644
... ...
@@ -1 +0,0 @@
1
-this is the secret
... ...
@@ -11,7 +11,7 @@ import (
11 11
 	"sync"
12 12
 
13 13
 	"github.com/docker/docker/integration-cli/checker"
14
-	"github.com/docker/docker/integration-cli/fixtures/load"
14
+	"github.com/docker/docker/internal/test/fixtures/load"
15 15
 	"github.com/go-check/check"
16 16
 )
17 17
 
18 18
new file mode 100644
19 19
Binary files /dev/null and b/integration-cli/testdata/emptyLayer.tar differ
... ...
@@ -9,7 +9,7 @@ import (
9 9
 	"time"
10 10
 
11 11
 	"github.com/docker/docker/api/types"
12
-	"github.com/docker/docker/integration-cli/fixtures/plugin"
12
+	"github.com/docker/docker/internal/test/fixtures/plugin"
13 13
 	"github.com/docker/docker/pkg/locker"
14 14
 	"github.com/pkg/errors"
15 15
 )
... ...
@@ -9,7 +9,7 @@ import (
9 9
 	"time"
10 10
 
11 11
 	"github.com/docker/docker/api/types"
12
-	"github.com/docker/docker/integration-cli/fixtures/plugin"
12
+	"github.com/docker/docker/internal/test/fixtures/plugin"
13 13
 	"github.com/docker/docker/pkg/locker"
14 14
 	"github.com/pkg/errors"
15 15
 )
... ...
@@ -7,8 +7,8 @@ import (
7 7
 	"testing"
8 8
 
9 9
 	"github.com/docker/docker/api/types"
10
-	"github.com/docker/docker/integration-cli/fixtures/plugin"
11 10
 	"github.com/docker/docker/internal/test/daemon"
11
+	"github.com/docker/docker/internal/test/fixtures/plugin"
12 12
 	"github.com/gotestyourself/gotestyourself/assert"
13 13
 )
14 14
 
... ...
@@ -8,7 +8,7 @@ import (
8 8
 
9 9
 	"github.com/docker/docker/api/types"
10 10
 	"github.com/docker/docker/client"
11
-	"github.com/docker/docker/integration-cli/fixtures/load"
11
+	"github.com/docker/docker/internal/test/fixtures/load"
12 12
 	"github.com/pkg/errors"
13 13
 	"golang.org/x/net/context"
14 14
 )
15 15
new file mode 100644
... ...
@@ -0,0 +1,197 @@
0
+package load // import "github.com/docker/docker/internal/test/fixtures/load"
1
+
2
+import (
3
+	"bufio"
4
+	"bytes"
5
+	"os"
6
+	"os/exec"
7
+	"path/filepath"
8
+	"strings"
9
+	"sync"
10
+
11
+	"context"
12
+
13
+	"github.com/docker/docker/api/types"
14
+	"github.com/docker/docker/client"
15
+	"github.com/docker/docker/pkg/jsonmessage"
16
+	"github.com/docker/docker/pkg/term"
17
+	"github.com/pkg/errors"
18
+)
19
+
20
+const frozenImgDir = "/docker-frozen-images"
21
+
22
+// FrozenImagesLinux loads the frozen image set for the integration suite
23
+// If the images are not available locally it will download them
24
+// TODO: This loads whatever is in the frozen image dir, regardless of what
25
+// images were passed in. If the images need to be downloaded, then it will respect
26
+// the passed in images
27
+func FrozenImagesLinux(client client.APIClient, images ...string) error {
28
+	var loadImages []struct{ srcName, destName string }
29
+	for _, img := range images {
30
+		if !imageExists(client, img) {
31
+			srcName := img
32
+			// hello-world:latest gets re-tagged as hello-world:frozen
33
+			// there are some tests that use hello-world:latest specifically so it pulls
34
+			// the image and hello-world:frozen is used for when we just want a super
35
+			// small image
36
+			if img == "hello-world:frozen" {
37
+				srcName = "hello-world:latest"
38
+			}
39
+			loadImages = append(loadImages, struct{ srcName, destName string }{
40
+				srcName:  srcName,
41
+				destName: img,
42
+			})
43
+		}
44
+	}
45
+	if len(loadImages) == 0 {
46
+		// everything is loaded, we're done
47
+		return nil
48
+	}
49
+
50
+	ctx := context.Background()
51
+	fi, err := os.Stat(frozenImgDir)
52
+	if err != nil || !fi.IsDir() {
53
+		srcImages := make([]string, 0, len(loadImages))
54
+		for _, img := range loadImages {
55
+			srcImages = append(srcImages, img.srcName)
56
+		}
57
+		if err := pullImages(ctx, client, srcImages); err != nil {
58
+			return errors.Wrap(err, "error pulling image list")
59
+		}
60
+	} else {
61
+		if err := loadFrozenImages(ctx, client); err != nil {
62
+			return err
63
+		}
64
+	}
65
+
66
+	for _, img := range loadImages {
67
+		if img.srcName != img.destName {
68
+			if err := client.ImageTag(ctx, img.srcName, img.destName); err != nil {
69
+				return errors.Wrapf(err, "failed to tag %s as %s", img.srcName, img.destName)
70
+			}
71
+			if _, err := client.ImageRemove(ctx, img.srcName, types.ImageRemoveOptions{}); err != nil {
72
+				return errors.Wrapf(err, "failed to remove %s", img.srcName)
73
+			}
74
+		}
75
+	}
76
+	return nil
77
+}
78
+
79
+func imageExists(client client.APIClient, name string) bool {
80
+	_, _, err := client.ImageInspectWithRaw(context.Background(), name)
81
+	return err == nil
82
+}
83
+
84
+func loadFrozenImages(ctx context.Context, client client.APIClient) error {
85
+	tar, err := exec.LookPath("tar")
86
+	if err != nil {
87
+		return errors.Wrap(err, "could not find tar binary")
88
+	}
89
+	tarCmd := exec.Command(tar, "-cC", frozenImgDir, ".")
90
+	out, err := tarCmd.StdoutPipe()
91
+	if err != nil {
92
+		return errors.Wrap(err, "error getting stdout pipe for tar command")
93
+	}
94
+
95
+	errBuf := bytes.NewBuffer(nil)
96
+	tarCmd.Stderr = errBuf
97
+	tarCmd.Start()
98
+	defer tarCmd.Wait()
99
+
100
+	resp, err := client.ImageLoad(ctx, out, true)
101
+	if err != nil {
102
+		return errors.Wrap(err, "failed to load frozen images")
103
+	}
104
+	defer resp.Body.Close()
105
+	fd, isTerminal := term.GetFdInfo(os.Stdout)
106
+	return jsonmessage.DisplayJSONMessagesStream(resp.Body, os.Stdout, fd, isTerminal, nil)
107
+}
108
+
109
+func pullImages(ctx context.Context, client client.APIClient, images []string) error {
110
+	cwd, err := os.Getwd()
111
+	if err != nil {
112
+		return errors.Wrap(err, "error getting path to dockerfile")
113
+	}
114
+	dockerfile := os.Getenv("DOCKERFILE")
115
+	if dockerfile == "" {
116
+		dockerfile = "Dockerfile"
117
+	}
118
+	dockerfilePath := filepath.Join(filepath.Dir(filepath.Clean(cwd)), dockerfile)
119
+	pullRefs, err := readFrozenImageList(dockerfilePath, images)
120
+	if err != nil {
121
+		return errors.Wrap(err, "error reading frozen image list")
122
+	}
123
+
124
+	var wg sync.WaitGroup
125
+	chErr := make(chan error, len(images))
126
+	for tag, ref := range pullRefs {
127
+		wg.Add(1)
128
+		go func(tag, ref string) {
129
+			defer wg.Done()
130
+			if err := pullTagAndRemove(ctx, client, ref, tag); err != nil {
131
+				chErr <- err
132
+				return
133
+			}
134
+		}(tag, ref)
135
+	}
136
+	wg.Wait()
137
+	close(chErr)
138
+	return <-chErr
139
+}
140
+
141
+func pullTagAndRemove(ctx context.Context, client client.APIClient, ref string, tag string) error {
142
+	resp, err := client.ImagePull(ctx, ref, types.ImagePullOptions{})
143
+	if err != nil {
144
+		return errors.Wrapf(err, "failed to pull %s", ref)
145
+	}
146
+	defer resp.Close()
147
+	fd, isTerminal := term.GetFdInfo(os.Stdout)
148
+	if err := jsonmessage.DisplayJSONMessagesStream(resp, os.Stdout, fd, isTerminal, nil); err != nil {
149
+		return err
150
+	}
151
+
152
+	if err := client.ImageTag(ctx, ref, tag); err != nil {
153
+		return errors.Wrapf(err, "failed to tag %s as %s", ref, tag)
154
+	}
155
+	_, err = client.ImageRemove(ctx, ref, types.ImageRemoveOptions{})
156
+	return errors.Wrapf(err, "failed to remove %s", ref)
157
+
158
+}
159
+
160
+func readFrozenImageList(dockerfilePath string, images []string) (map[string]string, error) {
161
+	f, err := os.Open(dockerfilePath)
162
+	if err != nil {
163
+		return nil, errors.Wrap(err, "error reading dockerfile")
164
+	}
165
+	defer f.Close()
166
+	ls := make(map[string]string)
167
+
168
+	scanner := bufio.NewScanner(f)
169
+	for scanner.Scan() {
170
+		line := strings.Fields(scanner.Text())
171
+		if len(line) < 3 {
172
+			continue
173
+		}
174
+		if !(line[0] == "RUN" && line[1] == "./contrib/download-frozen-image-v2.sh") {
175
+			continue
176
+		}
177
+
178
+		for scanner.Scan() {
179
+			img := strings.TrimSpace(scanner.Text())
180
+			img = strings.TrimSuffix(img, "\\")
181
+			img = strings.TrimSpace(img)
182
+			split := strings.Split(img, "@")
183
+			if len(split) < 2 {
184
+				break
185
+			}
186
+
187
+			for _, i := range images {
188
+				if split[0] == i {
189
+					ls[i] = img
190
+					break
191
+				}
192
+			}
193
+		}
194
+	}
195
+	return ls, nil
196
+}
0 197
new file mode 100644
... ...
@@ -0,0 +1,34 @@
0
+package main
1
+
2
+import (
3
+	"fmt"
4
+	"net"
5
+	"net/http"
6
+	"os"
7
+	"path/filepath"
8
+)
9
+
10
+func main() {
11
+	p, err := filepath.Abs(filepath.Join("run", "docker", "plugins"))
12
+	if err != nil {
13
+		panic(err)
14
+	}
15
+	if err := os.MkdirAll(p, 0755); err != nil {
16
+		panic(err)
17
+	}
18
+	l, err := net.Listen("unix", filepath.Join(p, "basic.sock"))
19
+	if err != nil {
20
+		panic(err)
21
+	}
22
+
23
+	mux := http.NewServeMux()
24
+	server := http.Server{
25
+		Addr:    l.Addr().String(),
26
+		Handler: http.NewServeMux(),
27
+	}
28
+	mux.HandleFunc("/Plugin.Activate", func(w http.ResponseWriter, r *http.Request) {
29
+		w.Header().Set("Content-Type", "application/vnd.docker.plugins.v1.1+json")
30
+		fmt.Println(w, `{"Implements": ["dummy"]}`)
31
+	})
32
+	server.Serve(l)
33
+}
0 34
new file mode 100644
... ...
@@ -0,0 +1,216 @@
0
+package plugin // import "github.com/docker/docker/internal/test/fixtures/plugin"
1
+
2
+import (
3
+	"encoding/json"
4
+	"io"
5
+	"io/ioutil"
6
+	"os"
7
+	"os/exec"
8
+	"path/filepath"
9
+	"time"
10
+
11
+	"github.com/docker/docker/api/types"
12
+	"github.com/docker/docker/pkg/archive"
13
+	"github.com/docker/docker/plugin"
14
+	"github.com/docker/docker/registry"
15
+	"github.com/pkg/errors"
16
+	"golang.org/x/net/context"
17
+)
18
+
19
+// CreateOpt is is passed used to change the default plugin config before
20
+// creating it
21
+type CreateOpt func(*Config)
22
+
23
+// Config wraps types.PluginConfig to provide some extra state for options
24
+// extra customizations on the plugin details, such as using a custom binary to
25
+// create the plugin with.
26
+type Config struct {
27
+	*types.PluginConfig
28
+	binPath string
29
+}
30
+
31
+// WithBinary is a CreateOpt to set an custom binary to create the plugin with.
32
+// This binary must be statically compiled.
33
+func WithBinary(bin string) CreateOpt {
34
+	return func(cfg *Config) {
35
+		cfg.binPath = bin
36
+	}
37
+}
38
+
39
+// CreateClient is the interface used for `BuildPlugin` to interact with the
40
+// daemon.
41
+type CreateClient interface {
42
+	PluginCreate(context.Context, io.Reader, types.PluginCreateOptions) error
43
+}
44
+
45
+// Create creates a new plugin with the specified name
46
+func Create(ctx context.Context, c CreateClient, name string, opts ...CreateOpt) error {
47
+	tmpDir, err := ioutil.TempDir("", "create-test-plugin")
48
+	if err != nil {
49
+		return err
50
+	}
51
+	defer os.RemoveAll(tmpDir)
52
+
53
+	tar, err := makePluginBundle(tmpDir, opts...)
54
+	if err != nil {
55
+		return err
56
+	}
57
+	defer tar.Close()
58
+
59
+	ctx, cancel := context.WithTimeout(ctx, 30*time.Second)
60
+	defer cancel()
61
+
62
+	return c.PluginCreate(ctx, tar, types.PluginCreateOptions{RepoName: name})
63
+}
64
+
65
+// CreateInRegistry makes a plugin (locally) and pushes it to a registry.
66
+// This does not use a dockerd instance to create or push the plugin.
67
+// If you just want to create a plugin in some daemon, use `Create`.
68
+//
69
+// This can be useful when testing plugins on swarm where you don't really want
70
+// the plugin to exist on any of the daemons (immediately) and there needs to be
71
+// some way to distribute the plugin.
72
+func CreateInRegistry(ctx context.Context, repo string, auth *types.AuthConfig, opts ...CreateOpt) error {
73
+	tmpDir, err := ioutil.TempDir("", "create-test-plugin-local")
74
+	if err != nil {
75
+		return err
76
+	}
77
+	defer os.RemoveAll(tmpDir)
78
+
79
+	inPath := filepath.Join(tmpDir, "plugin")
80
+	if err := os.MkdirAll(inPath, 0755); err != nil {
81
+		return errors.Wrap(err, "error creating plugin root")
82
+	}
83
+
84
+	tar, err := makePluginBundle(inPath, opts...)
85
+	if err != nil {
86
+		return err
87
+	}
88
+	defer tar.Close()
89
+
90
+	dummyExec := func(m *plugin.Manager) (plugin.Executor, error) {
91
+		return nil, nil
92
+	}
93
+
94
+	regService, err := registry.NewService(registry.ServiceOptions{V2Only: true})
95
+	if err != nil {
96
+		return err
97
+	}
98
+
99
+	managerConfig := plugin.ManagerConfig{
100
+		Store:           plugin.NewStore(),
101
+		RegistryService: regService,
102
+		Root:            filepath.Join(tmpDir, "root"),
103
+		ExecRoot:        "/run/docker", // manager init fails if not set
104
+		CreateExecutor:  dummyExec,
105
+		LogPluginEvent:  func(id, name, action string) {}, // panics when not set
106
+	}
107
+	manager, err := plugin.NewManager(managerConfig)
108
+	if err != nil {
109
+		return errors.Wrap(err, "error creating plugin manager")
110
+	}
111
+
112
+	ctx, cancel := context.WithTimeout(ctx, 30*time.Second)
113
+	defer cancel()
114
+	if err := manager.CreateFromContext(ctx, tar, &types.PluginCreateOptions{RepoName: repo}); err != nil {
115
+		return err
116
+	}
117
+
118
+	if auth == nil {
119
+		auth = &types.AuthConfig{}
120
+	}
121
+	err = manager.Push(ctx, repo, nil, auth, ioutil.Discard)
122
+	return errors.Wrap(err, "error pushing plugin")
123
+}
124
+
125
+func makePluginBundle(inPath string, opts ...CreateOpt) (io.ReadCloser, error) {
126
+	p := &types.PluginConfig{
127
+		Interface: types.PluginConfigInterface{
128
+			Socket: "basic.sock",
129
+			Types:  []types.PluginInterfaceType{{Capability: "docker.dummy/1.0"}},
130
+		},
131
+		Entrypoint: []string{"/basic"},
132
+	}
133
+	cfg := &Config{
134
+		PluginConfig: p,
135
+	}
136
+	for _, o := range opts {
137
+		o(cfg)
138
+	}
139
+	if cfg.binPath == "" {
140
+		binPath, err := ensureBasicPluginBin()
141
+		if err != nil {
142
+			return nil, err
143
+		}
144
+		cfg.binPath = binPath
145
+	}
146
+
147
+	configJSON, err := json.Marshal(p)
148
+	if err != nil {
149
+		return nil, err
150
+	}
151
+	if err := ioutil.WriteFile(filepath.Join(inPath, "config.json"), configJSON, 0644); err != nil {
152
+		return nil, err
153
+	}
154
+	if err := os.MkdirAll(filepath.Join(inPath, "rootfs", filepath.Dir(p.Entrypoint[0])), 0755); err != nil {
155
+		return nil, errors.Wrap(err, "error creating plugin rootfs dir")
156
+	}
157
+
158
+	// Ensure the mount target paths exist
159
+	for _, m := range p.Mounts {
160
+		var stat os.FileInfo
161
+		if m.Source != nil {
162
+			stat, err = os.Stat(*m.Source)
163
+			if err != nil && !os.IsNotExist(err) {
164
+				return nil, err
165
+			}
166
+		}
167
+
168
+		if stat == nil || stat.IsDir() {
169
+			var mode os.FileMode = 0755
170
+			if stat != nil {
171
+				mode = stat.Mode()
172
+			}
173
+			if err := os.MkdirAll(filepath.Join(inPath, "rootfs", m.Destination), mode); err != nil {
174
+				return nil, errors.Wrap(err, "error preparing plugin mount destination path")
175
+			}
176
+		} else {
177
+			if err := os.MkdirAll(filepath.Join(inPath, "rootfs", filepath.Dir(m.Destination)), 0755); err != nil {
178
+				return nil, errors.Wrap(err, "error preparing plugin mount destination dir")
179
+			}
180
+			f, err := os.Create(filepath.Join(inPath, "rootfs", m.Destination))
181
+			if err != nil && !os.IsExist(err) {
182
+				return nil, errors.Wrap(err, "error preparing plugin mount destination file")
183
+			}
184
+			if f != nil {
185
+				f.Close()
186
+			}
187
+		}
188
+	}
189
+	if err := archive.NewDefaultArchiver().CopyFileWithTar(cfg.binPath, filepath.Join(inPath, "rootfs", p.Entrypoint[0])); err != nil {
190
+		return nil, errors.Wrap(err, "error copying plugin binary to rootfs path")
191
+	}
192
+	tar, err := archive.Tar(inPath, archive.Uncompressed)
193
+	return tar, errors.Wrap(err, "error making plugin archive")
194
+}
195
+
196
+func ensureBasicPluginBin() (string, error) {
197
+	name := "docker-basic-plugin"
198
+	p, err := exec.LookPath(name)
199
+	if err == nil {
200
+		return p, nil
201
+	}
202
+
203
+	goBin, err := exec.LookPath("go")
204
+	if err != nil {
205
+		return "", err
206
+	}
207
+	installPath := filepath.Join(os.Getenv("GOPATH"), "bin", name)
208
+	sourcePath := filepath.Join("github.com", "docker", "docker", "internal", "test", "fixtures", "plugin", "basic")
209
+	cmd := exec.Command(goBin, "build", "-o", installPath, sourcePath)
210
+	cmd.Env = append(cmd.Env, "GOPATH="+os.Getenv("GOPATH"), "CGO_ENABLED=0")
211
+	if out, err := cmd.CombinedOutput(); err != nil {
212
+		return "", errors.Wrapf(err, "error building basic plugin bin: %s", string(out))
213
+	}
214
+	return installPath, nil
215
+}