12
. "github.com/containers/podman/v5/test/utils"
13
. "github.com/onsi/ginkgo/v2"
14
. "github.com/onsi/gomega"
15
. "github.com/onsi/gomega/gexec"
18
var _ = Describe("Podman Info", func() {
20
It("podman info --format json", func() {
30
{"{{json .}}", true, 0},
31
{"{{ json .}}", true, 0},
32
{"{{json . }}", true, 0},
33
{" {{ json . }} ", true, 0},
34
{"{{json }}", true, 0},
35
{"{{json .", false, 125},
36
{"json . }}", false, 0}, // without opening {{ template seen as string literal
38
for _, tt := range tests {
39
session := podmanTest.Podman([]string{"info", "--format", tt.input})
40
session.WaitWithDefaultTimeout()
42
desc := fmt.Sprintf("JSON test(%q)", tt.input)
43
Expect(session).Should(Exit(tt.exitCode), desc)
44
Expect(session.IsJSONOutputValid()).To(Equal(tt.success), desc)
48
It("podman info --format GO template", func() {
49
session := podmanTest.Podman([]string{"info", "--format", "{{.Store.GraphRoot}}"})
50
session.WaitWithDefaultTimeout()
51
Expect(session).Should(ExitCleanly())
54
It("podman info --format GO template", func() {
55
session := podmanTest.Podman([]string{"info", "--format", "{{.Registries}}"})
56
session.WaitWithDefaultTimeout()
57
Expect(session).Should(ExitCleanly())
58
Expect(session.OutputToString()).To(ContainSubstring("registry"))
61
It("podman info --format GO template plugins", func() {
62
session := podmanTest.Podman([]string{"info", "--format", "{{.Plugins}}"})
63
session.WaitWithDefaultTimeout()
64
Expect(session).Should(ExitCleanly())
65
Expect(session.OutputToString()).To(ContainSubstring("local"))
66
Expect(session.OutputToString()).To(ContainSubstring("journald"))
67
Expect(session.OutputToString()).To(ContainSubstring("bridge"))
70
It("podman info rootless storage path", func() {
71
SkipIfNotRootless("test of rootless_storage_path is only meaningful as rootless")
72
SkipIfRemote("Only tests storage on local client")
73
configPath := filepath.Join(podmanTest.TempDir, ".config", "containers", "storage.conf")
74
os.Setenv("CONTAINERS_STORAGE_CONF", configPath)
76
os.Unsetenv("CONTAINERS_STORAGE_CONF")
78
err := os.RemoveAll(filepath.Dir(configPath))
79
Expect(err).ToNot(HaveOccurred())
81
err = os.MkdirAll(filepath.Dir(configPath), os.ModePerm)
82
Expect(err).ToNot(HaveOccurred())
84
rootlessStoragePath := `"/tmp/$HOME/$USER/$UID/storage"`
86
storageConf := []byte(fmt.Sprintf("[storage]\ndriver=%s\nrootless_storage_path=%s\n[storage.options]\n", driver, rootlessStoragePath))
87
err = os.WriteFile(configPath, storageConf, os.ModePerm)
88
Expect(err).ToNot(HaveOccurred())
89
// Failures in this test are impossible to debug without breadcrumbs
90
GinkgoWriter.Printf("CONTAINERS_STORAGE_CONF=%s:\n%s\n", configPath, storageConf)
92
u, err := user.Current()
93
Expect(err).ToNot(HaveOccurred())
95
// Cannot use podmanTest.Podman() and test for storage path
96
expect := filepath.Join("/tmp", os.Getenv("HOME"), u.Username, u.Uid, "storage")
97
podmanPath := podmanTest.PodmanTest.PodmanBinary
98
cmd := exec.Command(podmanPath, "info", "--format", "{{.Store.GraphRoot -}}")
99
out, err := cmd.CombinedOutput()
100
GinkgoWriter.Printf("Running: podman info --format {{.Store.GraphRoot -}}\nOutput: %s\n", string(out))
101
Expect(err).ToNot(HaveOccurred(), "podman info")
102
Expect(string(out)).To(Equal(expect), "output from podman info")
105
It("check RemoteSocket ", func() {
106
session := podmanTest.Podman([]string{"info", "--format", "{{.Host.RemoteSocket.Path}}"})
107
session.WaitWithDefaultTimeout()
108
Expect(session).Should(ExitCleanly())
109
Expect(session.OutputToString()).To(MatchRegexp("/run/.*podman.*sock"))
111
session = podmanTest.Podman([]string{"info", "--format", "{{.Host.ServiceIsRemote}}"})
112
session.WaitWithDefaultTimeout()
113
Expect(session).Should(ExitCleanly())
114
if podmanTest.RemoteTest {
115
Expect(session.OutputToString()).To(Equal("true"))
117
Expect(session.OutputToString()).To(Equal("false"))
120
session = podmanTest.Podman([]string{"info", "--format", "{{.Host.RemoteSocket.Exists}}"})
121
session.WaitWithDefaultTimeout()
122
Expect(session).Should(ExitCleanly())
124
Expect(session.OutputToString()).To(ContainSubstring("true"))
126
Expect(session.OutputToString()).To(ContainSubstring("false"))
131
It("Podman info must contain cgroupControllers with RelevantControllers", func() {
132
SkipIfRootless("Hard to tell which controllers are going to be enabled for rootless")
133
SkipIfRootlessCgroupsV1("Disable cgroups not supported on cgroupv1 for rootless users")
134
session := podmanTest.Podman([]string{"info", "--format", "{{.Host.CgroupControllers}}"})
135
session.WaitWithDefaultTimeout()
136
Expect(session).To(ExitCleanly())
137
Expect(session.OutputToString()).To(ContainSubstring("memory"))
138
Expect(session.OutputToString()).To(ContainSubstring("pids"))
141
It("Podman info: check desired runtime", func() {
142
// defined in .cirrus.yml
143
want := os.Getenv("CI_DESIRED_RUNTIME")
145
if os.Getenv("CIRRUS_CI") == "" {
146
Skip("CI_DESIRED_RUNTIME is not set--this is OK because we're not running under Cirrus")
148
Fail("CIRRUS_CI is set, but CI_DESIRED_RUNTIME is not! See #14912")
150
session := podmanTest.Podman([]string{"info", "--format", "{{.Host.OCIRuntime.Name}}"})
151
session.WaitWithDefaultTimeout()
152
Expect(session).To(ExitCleanly())
153
Expect(session.OutputToString()).To(Equal(want))
156
It("Podman info: check desired network backend", func() {
157
session := podmanTest.Podman([]string{"info", "--format", "{{.Host.NetworkBackend}}"})
158
session.WaitWithDefaultTimeout()
159
Expect(session).To(ExitCleanly())
160
Expect(session.OutputToString()).To(Equal("netavark"))
162
session = podmanTest.Podman([]string{"info", "--format", "{{.Host.NetworkBackendInfo.Backend}}"})
163
session.WaitWithDefaultTimeout()
164
Expect(session).To(ExitCleanly())
165
Expect(session.OutputToString()).To(Equal("netavark"))
168
It("Podman info: check desired database backend", func() {
169
// defined in .cirrus.yml
170
want := os.Getenv("CI_DESIRED_DATABASE")
172
if os.Getenv("CIRRUS_CI") == "" {
173
Skip("CI_DESIRED_DATABASE is not set--this is OK because we're not running under Cirrus")
175
Fail("CIRRUS_CI is set, but CI_DESIRED_DATABASE is not! See #16389")
177
session := podmanTest.Podman([]string{"info", "--format", "{{.Host.DatabaseBackend}}"})
178
session.WaitWithDefaultTimeout()
179
Expect(session).To(ExitCleanly())
180
Expect(session.OutputToString()).To(Equal(want))
183
It("podman --db-backend info basic check", Serial, func() {
184
SkipIfRemote("--db-backend only supported on the local client")
186
const desiredDB = "CI_DESIRED_DATABASE"
188
type argWant struct {
192
backends := []argWant{
193
// default should be sqlite
194
{arg: "", want: "sqlite"},
195
{arg: "boltdb", want: "boltdb"},
196
// now because a boltdb exists it should use boltdb when default is requested
197
{arg: "", want: "boltdb"},
198
{arg: "sqlite", want: "sqlite"},
199
// just because we requested sqlite doesn't mean it stays that way.
200
// once a boltdb exists, podman will forevermore stick with it
201
{arg: "", want: "boltdb"},
204
for _, tt := range backends {
205
oldDesiredDB := os.Getenv(desiredDB)
206
if tt.arg == "boltdb" {
207
err := os.Setenv(desiredDB, "boltdb")
208
Expect(err).To(Not(HaveOccurred()))
209
defer os.Setenv(desiredDB, oldDesiredDB)
212
session := podmanTest.Podman([]string{"--db-backend", tt.arg, "--log-level=info", "info", "--format", "{{.Host.DatabaseBackend}}"})
213
session.WaitWithDefaultTimeout()
214
Expect(session).To(Exit(0))
215
Expect(session.OutputToString()).To(Equal(tt.want))
216
Expect(session.ErrorToString()).To(ContainSubstring("Using %s as database backend", tt.want))
218
if tt.arg == "boltdb" {
219
err := os.Setenv(desiredDB, oldDesiredDB)
220
Expect(err).To(Not(HaveOccurred()))
224
// make sure we get an error for bogus values
225
session := podmanTest.Podman([]string{"--db-backend", "bogus", "info", "--format", "{{.Host.DatabaseBackend}}"})
226
session.WaitWithDefaultTimeout()
227
Expect(session).To(Exit(125))
228
Expect(session.ErrorToString()).To(Equal("Error: unsupported database backend: \"bogus\""))
231
It("Podman info: check desired storage driver", func() {
232
// defined in .cirrus.yml
233
want := os.Getenv("CI_DESIRED_STORAGE")
235
if os.Getenv("CIRRUS_CI") == "" {
236
Skip("CI_DESIRED_STORAGE is not set--this is OK because we're not running under Cirrus")
238
Fail("CIRRUS_CI is set, but CI_DESIRED_STORAGE is not! See #20161")
240
session := podmanTest.Podman([]string{"info", "--format", "{{.Store.GraphDriverName}}"})
241
session.WaitWithDefaultTimeout()
242
Expect(session).To(ExitCleanly())
243
Expect(session.OutputToString()).To(Equal(want), ".Store.GraphDriverName from podman info")
246
It("Podman info: check lock count", Serial, func() {
247
// This should not run on architectures and OSes that use the file locks backend.
248
// Which, for now, is Linux + RISCV and FreeBSD, neither of which are in CI - so
250
info1 := podmanTest.Podman([]string{"info", "--format", "{{ .Host.FreeLocks }}"})
251
info1.WaitWithDefaultTimeout()
252
Expect(info1).To(ExitCleanly())
253
free1, err := strconv.Atoi(info1.OutputToString())
254
Expect(err).To(Not(HaveOccurred()))
256
ctr := podmanTest.Podman([]string{"create", ALPINE, "top"})
257
ctr.WaitWithDefaultTimeout()
258
Expect(ctr).To(ExitCleanly())
260
info2 := podmanTest.Podman([]string{"info", "--format", "{{ .Host.FreeLocks }}"})
261
info2.WaitWithDefaultTimeout()
262
Expect(info2).To(ExitCleanly())
263
free2, err := strconv.Atoi(info2.OutputToString())
264
Expect(err).To(Not(HaveOccurred()))
266
// Effectively, we are checking that 1 lock has been taken.
267
// We do this by comparing the number of locks after (plus 1), to the number of locks before.
268
// Don't check absolute numbers because there is a decent chance of contamination, containers that were never removed properly, etc.
269
Expect(free1).To(Equal(free2 + 1))
272
It("Podman info: check for client information when no system service", func() {
273
// the output for this information is not really something we can marshall
274
want := runtime.GOOS + "/" + runtime.GOARCH
275
podmanTest.StopRemoteService()
276
SkipIfNotRemote("Specifically testing a failed remote connection")
277
info := podmanTest.Podman([]string{"info"})
278
info.WaitWithDefaultTimeout()
279
Expect(info.OutputToString()).To(ContainSubstring(want))
280
Expect(info).ToNot(ExitCleanly())
281
podmanTest.StartRemoteService() // Start service again so teardown runs clean