podman

Форк
0
/
volume_plugin_test.go 
306 строк · 12.7 Кб
1
package integration
2

3
import (
4
	"fmt"
5
	"os"
6
	"path/filepath"
7

8
	. "github.com/containers/podman/v5/test/utils"
9
	"github.com/containers/storage/pkg/stringid"
10
	. "github.com/onsi/ginkgo/v2"
11
	. "github.com/onsi/gomega"
12
)
13

14
var _ = Describe("Podman volume plugins", func() {
15
	BeforeEach(func() {
16
		os.Setenv("CONTAINERS_CONF", "config/containers.conf")
17
		SkipIfRemote("Volume plugins only supported as local")
18
		SkipIfRootless("Root is required for volume plugin testing")
19
		err = os.MkdirAll("/run/docker/plugins", 0755)
20
		Expect(err).ToNot(HaveOccurred())
21
	})
22

23
	AfterEach(func() {
24
		podmanTest.CleanupVolume()
25
	})
26

27
	It("volume create with nonexistent plugin errors", func() {
28
		session := podmanTest.Podman([]string{"volume", "create", "--driver", "notexist", "test_volume_name"})
29
		session.WaitWithDefaultTimeout()
30
		Expect(session).To(ExitWithError())
31
	})
32

33
	It("volume create with not-running plugin does not error", func() {
34
		session := podmanTest.Podman([]string{"volume", "create", "--driver", "testvol0", "test_volume_name"})
35
		session.WaitWithDefaultTimeout()
36
		Expect(session).To(ExitWithError())
37
	})
38

39
	It("volume create and remove with running plugin succeeds", func() {
40
		podmanTest.AddImageToRWStore(volumeTest)
41

42
		pluginStatePath := filepath.Join(podmanTest.TempDir, "volumes")
43
		err := os.Mkdir(pluginStatePath, 0755)
44
		Expect(err).ToNot(HaveOccurred())
45

46
		// Keep this distinct within tests to avoid multiple tests using the same plugin.
47
		// This one verifies that the "image" plugin uses a volume plugin, not the "image" driver.
48
		pluginName := "image"
49
		plugin := podmanTest.Podman([]string{"run", "--security-opt", "label=disable", "-v", "/run/docker/plugins:/run/docker/plugins", "-v", fmt.Sprintf("%v:%v", pluginStatePath, pluginStatePath), "-d", volumeTest, "--sock-name", pluginName, "--path", pluginStatePath})
50
		plugin.WaitWithDefaultTimeout()
51
		Expect(plugin).Should(ExitCleanly())
52

53
		// Make sure the socket is available (see #17956)
54
		err = WaitForFile(fmt.Sprintf("/run/docker/plugins/%s.sock", pluginName))
55
		Expect(err).ToNot(HaveOccurred())
56

57
		volName := "testVolume1"
58
		create := podmanTest.Podman([]string{"volume", "create", "--driver", pluginName, volName})
59
		create.WaitWithDefaultTimeout()
60
		Expect(create).Should(ExitCleanly())
61

62
		ls1 := podmanTest.Podman([]string{"volume", "ls", "-q"})
63
		ls1.WaitWithDefaultTimeout()
64
		Expect(ls1).Should(ExitCleanly())
65
		arrOutput := ls1.OutputToStringArray()
66
		Expect(arrOutput).To(HaveLen(1))
67
		Expect(arrOutput[0]).To(ContainSubstring(volName))
68

69
		// Verify this is not an image volume.
70
		inspect := podmanTest.Podman([]string{"volume", "inspect", volName, "--format", "{{.StorageID}}"})
71
		inspect.WaitWithDefaultTimeout()
72
		Expect(inspect).Should(ExitCleanly())
73
		Expect(inspect.OutputToString()).To(BeEmpty())
74

75
		remove := podmanTest.Podman([]string{"volume", "rm", volName})
76
		remove.WaitWithDefaultTimeout()
77
		Expect(remove).Should(ExitCleanly())
78

79
		ls2 := podmanTest.Podman([]string{"volume", "ls", "-q"})
80
		ls2.WaitWithDefaultTimeout()
81
		Expect(ls2).Should(ExitCleanly())
82
		Expect(ls2.OutputToStringArray()).To(BeEmpty())
83
	})
84

85
	It("volume inspect with running plugin succeeds", func() {
86
		podmanTest.AddImageToRWStore(volumeTest)
87

88
		pluginStatePath := filepath.Join(podmanTest.TempDir, "volumes")
89
		err := os.Mkdir(pluginStatePath, 0755)
90
		Expect(err).ToNot(HaveOccurred())
91

92
		// Keep this distinct within tests to avoid multiple tests using the same plugin.
93
		pluginName := "testvol2"
94
		plugin := podmanTest.Podman([]string{"run", "--security-opt", "label=disable", "-v", "/run/docker/plugins:/run/docker/plugins", "-v", fmt.Sprintf("%v:%v", pluginStatePath, pluginStatePath), "-d", volumeTest, "--sock-name", pluginName, "--path", pluginStatePath})
95
		plugin.WaitWithDefaultTimeout()
96
		Expect(plugin).Should(ExitCleanly())
97

98
		// Make sure the socket is available (see #17956)
99
		err = WaitForFile(fmt.Sprintf("/run/docker/plugins/%s.sock", pluginName))
100
		Expect(err).ToNot(HaveOccurred())
101

102
		volName := "testVolume1"
103
		create := podmanTest.Podman([]string{"volume", "create", "--driver", pluginName, volName})
104
		create.WaitWithDefaultTimeout()
105
		Expect(create).Should(ExitCleanly())
106

107
		volInspect := podmanTest.Podman([]string{"volume", "inspect", "--format", "{{ .Driver }}", volName})
108
		volInspect.WaitWithDefaultTimeout()
109
		Expect(volInspect).Should(ExitCleanly())
110
		Expect(volInspect.OutputToString()).To(ContainSubstring(pluginName))
111
	})
112

113
	It("remove plugin with stopped plugin succeeds", func() {
114
		podmanTest.AddImageToRWStore(volumeTest)
115

116
		pluginStatePath := filepath.Join(podmanTest.TempDir, "volumes")
117
		err := os.Mkdir(pluginStatePath, 0755)
118
		Expect(err).ToNot(HaveOccurred())
119

120
		// Keep this distinct within tests to avoid multiple tests using the same plugin.
121
		pluginName := "testvol3"
122
		ctrName := "pluginCtr"
123
		plugin := podmanTest.Podman([]string{"run", "--name", ctrName, "--security-opt", "label=disable", "-v", "/run/docker/plugins:/run/docker/plugins", "-v", fmt.Sprintf("%v:%v", pluginStatePath, pluginStatePath), "-d", volumeTest, "--sock-name", pluginName, "--path", pluginStatePath})
124
		plugin.WaitWithDefaultTimeout()
125
		Expect(plugin).Should(ExitCleanly())
126

127
		// Make sure the socket is available (see #17956)
128
		err = WaitForFile(fmt.Sprintf("/run/docker/plugins/%s.sock", pluginName))
129
		Expect(err).ToNot(HaveOccurred())
130

131
		volName := "testVolume1"
132
		create := podmanTest.Podman([]string{"volume", "create", "--driver", pluginName, volName})
133
		create.WaitWithDefaultTimeout()
134
		Expect(create).Should(ExitCleanly())
135

136
		ls1 := podmanTest.Podman([]string{"volume", "ls", "-q"})
137
		ls1.WaitWithDefaultTimeout()
138
		Expect(ls1).Should(ExitCleanly())
139
		arrOutput := ls1.OutputToStringArray()
140
		Expect(arrOutput).To(HaveLen(1))
141
		Expect(arrOutput[0]).To(ContainSubstring(volName))
142

143
		podmanTest.StopContainer(ctrName)
144

145
		// Remove should exit non-zero because missing plugin
146
		remove := podmanTest.Podman([]string{"volume", "rm", volName})
147
		remove.WaitWithDefaultTimeout()
148
		Expect(remove).To(ExitWithError())
149

150
		// But the volume should still be gone
151
		ls2 := podmanTest.Podman([]string{"volume", "ls", "-q"})
152
		ls2.WaitWithDefaultTimeout()
153
		Expect(ls2).Should(ExitCleanly())
154
		Expect(ls2.OutputToStringArray()).To(BeEmpty())
155
	})
156

157
	It("use plugin in containers", func() {
158
		podmanTest.AddImageToRWStore(volumeTest)
159

160
		pluginStatePath := filepath.Join(podmanTest.TempDir, "volumes")
161
		err := os.Mkdir(pluginStatePath, 0755)
162
		Expect(err).ToNot(HaveOccurred())
163

164
		// Keep this distinct within tests to avoid multiple tests using the same plugin.
165
		pluginName := "testvol4"
166
		plugin := podmanTest.Podman([]string{"run", "--security-opt", "label=disable", "-v", "/run/docker/plugins:/run/docker/plugins", "-v", fmt.Sprintf("%v:%v", pluginStatePath, pluginStatePath), "-d", volumeTest, "--sock-name", pluginName, "--path", pluginStatePath})
167
		plugin.WaitWithDefaultTimeout()
168
		Expect(plugin).Should(ExitCleanly())
169

170
		// Make sure the socket is available (see #17956)
171
		err = WaitForFile(fmt.Sprintf("/run/docker/plugins/%s.sock", pluginName))
172
		Expect(err).ToNot(HaveOccurred())
173

174
		volName := "testVolume1"
175
		create := podmanTest.Podman([]string{"volume", "create", "--driver", pluginName, volName})
176
		create.WaitWithDefaultTimeout()
177
		Expect(create).Should(ExitCleanly())
178

179
		ctr1Name := "ctr1"
180
		ctr1 := podmanTest.Podman([]string{"run", "--security-opt", "label=disable", "--name", ctr1Name, "-v", fmt.Sprintf("%v:/test", volName), ALPINE, "sh", "-c", "touch /test/testfile && echo helloworld > /test/testfile"})
181
		ctr1.WaitWithDefaultTimeout()
182
		Expect(ctr1).Should(ExitCleanly())
183

184
		ctr2Name := "ctr2"
185
		ctr2 := podmanTest.Podman([]string{"run", "--security-opt", "label=disable", "--name", ctr2Name, "-v", fmt.Sprintf("%v:/test", volName), ALPINE, "cat", "/test/testfile"})
186
		ctr2.WaitWithDefaultTimeout()
187
		Expect(ctr2).Should(ExitCleanly())
188
		Expect(ctr2.OutputToString()).To(ContainSubstring("helloworld"))
189

190
		// HACK: `volume rm -f` is timing out trying to remove containers using the volume.
191
		// Solution: remove them manually...
192
		// TODO: fix this when I get back
193
		rmAll := podmanTest.Podman([]string{"rm", "-f", ctr2Name, ctr1Name})
194
		rmAll.WaitWithDefaultTimeout()
195
		Expect(rmAll).Should(ExitCleanly())
196
	})
197

198
	It("podman volume reload", func() {
199
		podmanTest.AddImageToRWStore(volumeTest)
200

201
		confFile := filepath.Join(podmanTest.TempDir, "containers.conf")
202
		err := os.WriteFile(confFile, []byte(`[engine]
203
[engine.volume_plugins]
204
testvol5 = "/run/docker/plugins/testvol5.sock"`), 0o644)
205
		Expect(err).ToNot(HaveOccurred())
206
		os.Setenv("CONTAINERS_CONF", confFile)
207

208
		pluginStatePath := filepath.Join(podmanTest.TempDir, "volumes")
209
		err = os.Mkdir(pluginStatePath, 0755)
210
		Expect(err).ToNot(HaveOccurred())
211

212
		// Keep this distinct within tests to avoid multiple tests using the same plugin.
213
		pluginName := "testvol5"
214
		ctrName := "pluginCtr"
215
		plugin := podmanTest.Podman([]string{"run", "--name", ctrName, "--security-opt", "label=disable", "-v", "/run/docker/plugins:/run/docker/plugins",
216
			"-v", fmt.Sprintf("%v:%v", pluginStatePath, pluginStatePath), "-d", volumeTest, "--sock-name", pluginName, "--path", pluginStatePath})
217
		plugin.WaitWithDefaultTimeout()
218
		Expect(plugin).Should(ExitCleanly())
219

220
		// Make sure the socket is available (see #17956)
221
		err = WaitForFile(fmt.Sprintf("/run/docker/plugins/%s.sock", pluginName))
222
		Expect(err).ToNot(HaveOccurred())
223

224
		localvol := "local-" + stringid.GenerateRandomID()
225
		// create local volume
226
		session := podmanTest.Podman([]string{"volume", "create", localvol})
227
		session.WaitWithDefaultTimeout()
228
		Expect(session).To(ExitCleanly())
229

230
		vol1 := "vol1-" + stringid.GenerateRandomID()
231
		session = podmanTest.Podman([]string{"volume", "create", "--driver", pluginName, vol1})
232
		session.WaitWithDefaultTimeout()
233
		Expect(session).To(ExitCleanly())
234

235
		// now create volume in plugin without podman
236
		vol2 := "vol2-" + stringid.GenerateRandomID()
237
		plugin = podmanTest.Podman([]string{"exec", ctrName, "/usr/local/bin/testvol", "--sock-name", pluginName, "create", vol2})
238
		plugin.WaitWithDefaultTimeout()
239
		Expect(plugin).Should(ExitCleanly())
240

241
		session = podmanTest.Podman([]string{"volume", "ls", "-q"})
242
		session.WaitWithDefaultTimeout()
243
		Expect(session).To(ExitCleanly())
244
		Expect(session.OutputToStringArray()).To(ContainElements(localvol, vol1))
245
		Expect(session.ErrorToString()).To(Equal("")) // make sure no errors are shown
246

247
		plugin = podmanTest.Podman([]string{"exec", ctrName, "/usr/local/bin/testvol", "--sock-name", pluginName, "remove", vol1})
248
		plugin.WaitWithDefaultTimeout()
249
		Expect(plugin).Should(ExitCleanly())
250

251
		// now reload volumes from plugins
252
		session = podmanTest.Podman([]string{"volume", "reload"})
253
		session.WaitWithDefaultTimeout()
254
		Expect(session).To(ExitCleanly())
255
		Expect(string(session.Out.Contents())).To(Equal(fmt.Sprintf(`Added:
256
%s
257
Removed:
258
%s
259
`, vol2, vol1)))
260
		Expect(session.ErrorToString()).To(Equal("")) // make sure no errors are shown
261

262
		session = podmanTest.Podman([]string{"volume", "ls", "-q"})
263
		session.WaitWithDefaultTimeout()
264
		Expect(session).To(ExitCleanly())
265
		Expect(session.OutputToStringArray()).To(ContainElements(localvol, vol2))
266
		Expect(session.ErrorToString()).To(Equal("")) // make no errors are shown
267
	})
268

269
	It("volume driver timeouts test", func() {
270
		podmanTest.AddImageToRWStore(volumeTest)
271

272
		pluginStatePath := filepath.Join(podmanTest.TempDir, "volumes")
273
		err := os.Mkdir(pluginStatePath, 0755)
274
		Expect(err).ToNot(HaveOccurred())
275

276
		// Keep this distinct within tests to avoid multiple tests using the same plugin.
277
		pluginName := "testvol6"
278
		plugin := podmanTest.Podman([]string{"run", "--security-opt", "label=disable", "-v", "/run/docker/plugins:/run/docker/plugins", "-v", fmt.Sprintf("%v:%v", pluginStatePath, pluginStatePath), "-d", volumeTest, "--sock-name", pluginName, "--path", pluginStatePath})
279
		plugin.WaitWithDefaultTimeout()
280
		Expect(plugin).Should(ExitCleanly())
281

282
		// Make sure the socket is available (see #17956)
283
		err = WaitForFile(fmt.Sprintf("/run/docker/plugins/%s.sock", pluginName))
284
		Expect(err).ToNot(HaveOccurred())
285

286
		volName := "testVolume1"
287
		create := podmanTest.Podman([]string{"volume", "create", "--driver", pluginName, volName})
288
		create.WaitWithDefaultTimeout()
289
		Expect(create).Should(ExitCleanly())
290

291
		volInspect := podmanTest.Podman([]string{"volume", "inspect", "--format", "{{ .Timeout }}", volName})
292
		volInspect.WaitWithDefaultTimeout()
293
		Expect(volInspect).Should(ExitCleanly())
294
		Expect(volInspect.OutputToString()).To(ContainSubstring("15"))
295

296
		volName2 := "testVolume2"
297
		create2 := podmanTest.Podman([]string{"volume", "create", "--driver", pluginName, "--opt", "o=timeout=3", volName2})
298
		create2.WaitWithDefaultTimeout()
299
		Expect(create2).Should(ExitCleanly())
300

301
		volInspect2 := podmanTest.Podman([]string{"volume", "inspect", "--format", "{{ .Timeout }}", volName2})
302
		volInspect2.WaitWithDefaultTimeout()
303
		Expect(volInspect2).Should(ExitCleanly())
304
		Expect(volInspect2.OutputToString()).To(ContainSubstring("3"))
305
	})
306
})
307

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.