Files
podman/pkg/machine/e2e/list_test.go
Brent Baude 0f22c1c772 Provider obfuscation in command line
For Podman 6, we still have providers and will continue to have a default provider for each platform.  But where a platform has multiple providers, we want users to be able to cross provider boudnaries imposed in Podman 4/5.  The key change is to look up virtual machines by name, as before, but to then also iterate all possible providers.  As of this PR, init will still only create with the default provider, but a subsequent PR will introdouce an provider override.

I also removed the "--all-providers" command line option on `podman
machine ls` because it no longer makes sense. And I marked the all
provider list test to be skipped.

Signed-off-by: Brent Baude <bbaude@redhat.com>
2025-10-27 08:40:19 -05:00

239 lines
8.2 KiB
Go

package e2e_test
import (
"os"
"slices"
"strconv"
"strings"
"time"
"github.com/containers/podman/v6/pkg/domain/entities"
"github.com/containers/podman/v6/pkg/machine/define"
jsoniter "github.com/json-iterator/go"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
. "github.com/onsi/gomega/gexec"
)
var _ = Describe("podman machine list", func() {
It("list machine", func() {
list := new(listMachine)
firstList, err := mb.setCmd(list).run()
Expect(err).NotTo(HaveOccurred())
Expect(firstList).Should(Exit(0))
Expect(firstList.outputToStringSlice()).To(HaveLen(1)) // just the header
i := new(initMachine)
session, err := mb.setCmd(i.withImage(mb.imagePath)).run()
Expect(err).ToNot(HaveOccurred())
Expect(session).To(Exit(0))
secondList, err := mb.setCmd(list).run()
Expect(err).NotTo(HaveOccurred())
Expect(secondList).To(Exit(0))
Expect(secondList.outputToStringSlice()).To(HaveLen(2)) // one machine and the header
})
It("list machines with quiet or noheading", func() {
// Random names for machines to test list
name1 := randomString()
name2 := randomString()
list := new(listMachine)
firstList, err := mb.setCmd(list.withQuiet()).run()
Expect(err).NotTo(HaveOccurred())
Expect(firstList).Should(Exit(0))
Expect(firstList.outputToStringSlice()).To(BeEmpty()) // No header with quiet
noheaderSession, err := mb.setCmd(list.withNoHeading()).run() // noheader
Expect(err).NotTo(HaveOccurred())
Expect(noheaderSession).Should(Exit(0))
Expect(noheaderSession.outputToStringSlice()).To(BeEmpty())
i := new(initMachine)
session, err := mb.setName(name1).setCmd(i.withImage(mb.imagePath)).run()
Expect(err).ToNot(HaveOccurred())
Expect(session).To(Exit(0))
session2, err := mb.setName(name2).setCmd(i.withImage(mb.imagePath)).run()
Expect(err).ToNot(HaveOccurred())
Expect(session2).To(Exit(0))
secondList, err := mb.setCmd(list.withQuiet()).run()
Expect(err).NotTo(HaveOccurred())
Expect(secondList).To(Exit(0))
Expect(secondList.outputToStringSlice()).To(HaveLen(2)) // two machines, no header
listNames := secondList.outputToStringSlice()
stripAsterisk(listNames)
Expect(slices.Contains(listNames, name1)).To(BeTrue())
Expect(slices.Contains(listNames, name2)).To(BeTrue())
})
It("list machine: check if running while starting", func() {
skipIfWSL("the below logic does not work on WSL. #20978")
i := new(initMachine)
session, err := mb.setCmd(i.withImage(mb.imagePath)).run()
Expect(err).ToNot(HaveOccurred())
Expect(session).To(Exit(0))
l := new(listMachine)
listSession, err := mb.setCmd(l.withFormat("{{.LastUp}}")).run()
Expect(err).NotTo(HaveOccurred())
Expect(listSession).To(Exit(0))
Expect(listSession.outputToString()).To(Equal("Never"))
// The logic in this test stanza is seemingly invalid on WSL.
// issue #20978 reflects this change
s := new(startMachine)
startSession, err := mb.setCmd(s).runWithoutWait()
Expect(err).ToNot(HaveOccurred())
wait := 3
retries := (int)(mb.timeout/time.Second) / wait
for range retries {
listSession, err := mb.setCmd(l).run()
Expect(listSession).To(Exit(0))
Expect(err).ToNot(HaveOccurred())
if startSession.ExitCode() == -1 {
Expect(listSession.outputToString()).NotTo(ContainSubstring("Currently running"))
} else {
break
}
time.Sleep(time.Duration(wait) * time.Second)
}
Expect(startSession).To(Exit(0))
listSession, err = mb.setCmd(l).run()
Expect(listSession).To(Exit(0))
Expect(err).ToNot(HaveOccurred())
Expect(listSession.outputToString()).To(ContainSubstring("Currently running"))
Expect(listSession.outputToString()).NotTo(ContainSubstring("Less than a second ago")) // check to make sure time created is accurate
})
It("list with --format", func() {
// Random names for machines to test list
name1 := randomString()
i := new(initMachine)
session, err := mb.setName(name1).setCmd(i.withImage(mb.imagePath)).run()
Expect(err).ToNot(HaveOccurred())
Expect(session).To(Exit(0))
// go format
list := new(listMachine)
listSession, err := mb.setCmd(list.withFormat("{{.Name}}")).run()
Expect(err).NotTo(HaveOccurred())
Expect(listSession).To(Exit(0))
Expect(listSession.outputToStringSlice()).To(HaveLen(1))
listNames := listSession.outputToStringSlice()
stripAsterisk(listNames)
Expect(slices.Contains(listNames, name1)).To(BeTrue())
// --format json
list2 := new(listMachine)
list2 = list2.withFormat("json")
listSession2, err := mb.setCmd(list2).run()
Expect(err).ToNot(HaveOccurred())
Expect(listSession2).To(Exit(0))
Expect(listSession2.outputToString()).To(BeValidJSON())
var listResponse []*entities.ListReporter
err = jsoniter.Unmarshal(listSession2.Bytes(), &listResponse)
Expect(err).ToNot(HaveOccurred())
// table format includes the header
list = new(listMachine)
listSession3, err3 := mb.setCmd(list.withFormat("table {{.Name}}")).run()
Expect(err3).NotTo(HaveOccurred())
Expect(listSession3).To(Exit(0))
listNames3 := listSession3.outputToStringSlice()
Expect(listNames3).To(HaveLen(2))
})
It("list machine in machine-readable byte format", func() {
i := new(initMachine)
session, err := mb.setCmd(i.withImage(mb.imagePath)).run()
Expect(err).ToNot(HaveOccurred())
Expect(session).To(Exit(0))
list := new(listMachine)
list = list.withFormat(("json"))
listSession, err := mb.setCmd(list).run()
Expect(err).NotTo(HaveOccurred())
var listResponse []*entities.ListReporter
err = jsoniter.Unmarshal(listSession.Bytes(), &listResponse)
Expect(err).NotTo(HaveOccurred())
for _, reporter := range listResponse {
memory, err := strconv.Atoi(reporter.Memory)
Expect(err).NotTo(HaveOccurred())
Expect(memory).To(BeNumerically(">", 2000000000)) // 2GiB
diskSize, err := strconv.Atoi(reporter.DiskSize)
Expect(err).NotTo(HaveOccurred())
Expect(diskSize).To(BeNumerically(">", 11000000000)) // 11GiB
}
})
It("list machine in human-readable format", func() {
i := new(initMachine)
session, err := mb.setCmd(i.withImage(mb.imagePath)).run()
Expect(err).ToNot(HaveOccurred())
Expect(session).To(Exit(0))
list := new(listMachine)
listSession, err := mb.setCmd(list.withFormat("{{.Memory}} {{.DiskSize}}")).run()
Expect(err).NotTo(HaveOccurred())
Expect(listSession).To(Exit(0))
Expect(listSession.outputToString()).To(Equal("2GiB 11GiB"))
})
It("list machine from all providers", func() {
Skip("This test will be changed for when --provider is added to init")
// create machine on other provider
currprovider := os.Getenv("CONTAINERS_MACHINE_PROVIDER")
os.Setenv("CONTAINERS_MACHINE_PROVIDER", getOtherProvider())
defer os.Setenv("CONTAINERS_MACHINE_PROVIDER", currprovider)
othermach := new(initMachine)
if !isWSL() && !isVmtype(define.HyperVVirt) {
// This would need to fetch a new image as we cannot use the image from the other provider,
// to avoid big pulls which are slow and flaky use /dev/null which works on macos and qemu
// as we never run the image if we do not start it.
othermach.withImage(os.DevNull)
}
session, err := mb.setName("otherprovider").setCmd(othermach).run()
// make sure to remove machine from other provider later
defer func() {
os.Setenv("CONTAINERS_MACHINE_PROVIDER", getOtherProvider())
defer os.Setenv("CONTAINERS_MACHINE_PROVIDER", currprovider)
rm := new(rmMachine)
removed, err := mb.setName("otherprovider").setCmd(rm.withForce()).run()
Expect(err).ToNot(HaveOccurred())
Expect(removed).To(Exit(0))
}()
Expect(err).ToNot(HaveOccurred())
Expect(session).To(Exit(0))
// change back to current provider
os.Setenv("CONTAINERS_MACHINE_PROVIDER", currprovider)
name := randomString()
i := new(initMachine)
session, err = mb.setName(name).setCmd(i.withImage(mb.imagePath)).run()
Expect(err).ToNot(HaveOccurred())
Expect(session).To(Exit(0))
list := new(listMachine)
listSession, err := mb.setCmd(list.withAllProviders().withFormat("{{.Name}}")).run()
Expect(err).NotTo(HaveOccurred())
Expect(listSession).To(Exit(0))
listNames := listSession.outputToStringSlice()
stripAsterisk(listNames)
Expect(listNames).To(HaveLen(2))
Expect(listNames).To(ContainElements("otherprovider", name))
})
})
func stripAsterisk(sl []string) {
for idx, val := range sl {
sl[idx] = strings.TrimRight(val, "*")
}
}