aboutsummaryrefslogtreecommitdiff
path: root/pkg
diff options
context:
space:
mode:
Diffstat (limited to 'pkg')
-rw-r--r--pkg/api/handlers/libpod/pods.go37
-rw-r--r--pkg/machine/config.go1
-rw-r--r--pkg/machine/e2e/config_info.go20
-rw-r--r--pkg/machine/e2e/info_test.go58
-rw-r--r--pkg/machine/qemu/machine.go5
-rw-r--r--pkg/machine/wsl/machine.go4
6 files changed, 122 insertions, 3 deletions
diff --git a/pkg/api/handlers/libpod/pods.go b/pkg/api/handlers/libpod/pods.go
index 92fd94390..8b1d456ec 100644
--- a/pkg/api/handlers/libpod/pods.go
+++ b/pkg/api/handlers/libpod/pods.go
@@ -530,8 +530,12 @@ func PodStats(w http.ResponseWriter, r *http.Request) {
query := struct {
NamesOrIDs []string `schema:"namesOrIDs"`
All bool `schema:"all"`
+ Stream bool `schema:"stream"`
+ Delay int `schema:"delay"`
}{
// default would go here
+ Delay: 5,
+ Stream: false,
}
if err := decoder.Decode(&query, r.URL.Query()); err != nil {
utils.Error(w, http.StatusBadRequest, fmt.Errorf("failed to parse parameters for %s: %w", r.URL.String(), err))
@@ -544,6 +548,10 @@ func PodStats(w http.ResponseWriter, r *http.Request) {
utils.InternalServerError(w, err)
}
+ var flush = func() {}
+ if flusher, ok := w.(http.Flusher); ok {
+ flush = flusher.Flush
+ }
// Collect the stats and send them over the wire.
containerEngine := abi.ContainerEngine{Libpod: runtime}
reports, err := containerEngine.PodStats(r.Context(), query.NamesOrIDs, options)
@@ -554,10 +562,35 @@ func PodStats(w http.ResponseWriter, r *http.Request) {
utils.Error(w, http.StatusNotFound, err)
return
}
-
utils.InternalServerError(w, err)
return
}
- utils.WriteResponse(w, http.StatusOK, reports)
+ w.Header().Set("Content-Type", "application/json")
+ coder := json.NewEncoder(w)
+ coder.SetEscapeHTML(true)
+
+ if err := coder.Encode(reports); err != nil {
+ logrus.Infof("Error from %s %q : %v", r.Method, r.URL, err)
+ }
+ flush()
+ if query.Stream {
+ for {
+ select {
+ case <-r.Context().Done():
+ return
+ default:
+ time.Sleep(time.Duration(query.Delay) * time.Second)
+ reports, err = containerEngine.PodStats(r.Context(), query.NamesOrIDs, options)
+ if err != nil {
+ return
+ }
+ if err := coder.Encode(reports); err != nil {
+ logrus.Infof("Error from %s %q : %v", r.Method, r.URL, err)
+ return
+ }
+ flush()
+ }
+ }
+ }
}
diff --git a/pkg/machine/config.go b/pkg/machine/config.go
index fcc129338..66fa6ab91 100644
--- a/pkg/machine/config.go
+++ b/pkg/machine/config.go
@@ -55,6 +55,7 @@ type Provider interface {
IsValidVMName(name string) (bool, error)
CheckExclusiveActiveVM() (bool, string, error)
RemoveAndCleanMachines() error
+ VMType() string
}
type RemoteConnectionType string
diff --git a/pkg/machine/e2e/config_info.go b/pkg/machine/e2e/config_info.go
new file mode 100644
index 000000000..410c7e518
--- /dev/null
+++ b/pkg/machine/e2e/config_info.go
@@ -0,0 +1,20 @@
+package e2e
+
+type infoMachine struct {
+ format string
+ cmd []string
+}
+
+func (i *infoMachine) buildCmd(m *machineTestBuilder) []string {
+ cmd := []string{"machine", "info"}
+ if len(i.format) > 0 {
+ cmd = append(cmd, "--format", i.format)
+ }
+ i.cmd = cmd
+ return cmd
+}
+
+func (i *infoMachine) withFormat(format string) *infoMachine {
+ i.format = format
+ return i
+}
diff --git a/pkg/machine/e2e/info_test.go b/pkg/machine/e2e/info_test.go
new file mode 100644
index 000000000..eeabb78af
--- /dev/null
+++ b/pkg/machine/e2e/info_test.go
@@ -0,0 +1,58 @@
+package e2e
+
+import (
+ "github.com/containers/podman/v4/cmd/podman/machine"
+ jsoniter "github.com/json-iterator/go"
+ . "github.com/onsi/ginkgo"
+ . "github.com/onsi/gomega"
+ . "github.com/onsi/gomega/gexec"
+)
+
+var _ = Describe("podman machine info", func() {
+ var (
+ mb *machineTestBuilder
+ testDir string
+ )
+
+ BeforeEach(func() {
+ testDir, mb = setup()
+ })
+ AfterEach(func() {
+ teardown(originalHomeDir, testDir, mb)
+ })
+
+ It("machine info", func() {
+ info := new(infoMachine)
+ infoSession, err := mb.setCmd(info).run()
+ Expect(err).NotTo(HaveOccurred())
+ Expect(infoSession).Should(Exit(0))
+
+ // Verify go template works and check for no running machines
+ info = new(infoMachine)
+ infoSession, err = mb.setCmd(info.withFormat("{{.Host.NumberOfMachines}}")).run()
+ Expect(err).NotTo(HaveOccurred())
+ Expect(infoSession).Should(Exit(0))
+ Expect(infoSession.outputToString()).To(Equal("0"))
+
+ // Create a machine and check if info has been updated
+ i := new(initMachine)
+ initSession, err := mb.setCmd(i.withImagePath(mb.imagePath)).run()
+ Expect(err).To(BeNil())
+ Expect(initSession).To(Exit(0))
+
+ info = new(infoMachine)
+ infoSession, err = mb.setCmd(info.withFormat("{{.Host.NumberOfMachines}}")).run()
+ Expect(err).NotTo(HaveOccurred())
+ Expect(infoSession).Should(Exit(0))
+ Expect(infoSession.outputToString()).To(Equal("1"))
+
+ // Check if json is in correct format
+ infoSession, err = mb.setCmd(info.withFormat("json")).run()
+ Expect(err).NotTo(HaveOccurred())
+ Expect(infoSession).Should(Exit(0))
+
+ infoReport := &machine.Info{}
+ err = jsoniter.Unmarshal(infoSession.Bytes(), infoReport)
+ Expect(err).To(BeNil())
+ })
+})
diff --git a/pkg/machine/qemu/machine.go b/pkg/machine/qemu/machine.go
index ca7947e34..d208b11eb 100644
--- a/pkg/machine/qemu/machine.go
+++ b/pkg/machine/qemu/machine.go
@@ -1701,6 +1701,9 @@ func isProcessAlive(pid int) bool {
if err == nil || err == unix.EPERM {
return true
}
-
return false
}
+
+func (p *Provider) VMType() string {
+ return vmtype
+}
diff --git a/pkg/machine/wsl/machine.go b/pkg/machine/wsl/machine.go
index 04215d545..492b66659 100644
--- a/pkg/machine/wsl/machine.go
+++ b/pkg/machine/wsl/machine.go
@@ -1655,3 +1655,7 @@ func (p *Provider) RemoveAndCleanMachines() error {
}
return prevErr
}
+
+func (p *Provider) VMType() string {
+ return vmtype
+}