mirror of
https://github.com/containers/podman.git
synced 2025-11-29 17:48:05 +08:00
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>
239 lines
8.2 KiB
Go
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, "*")
|
|
}
|
|
}
|