From e2d5a1d0512abed12e0844ab33fdbf023f206c7c Mon Sep 17 00:00:00 2001
From: Daniel J Walsh <dwalsh@redhat.com>
Date: Wed, 17 Feb 2021 07:52:42 -0500
Subject: [PATCH] podman ps --format '{{ .Size }}' requires --size option

Podman -s crashes when the user specifies the '{{ .Size }}` format
on the podman ps command, without specifying the --size option.

This PR will stop the crash and print out a logrus.Error stating that
the caller should add the --size option.

Fixes: https://github.com/containers/podman/issues/9408

Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>
---
 cmd/podman/containers/ps.go |  6 ++++++
 test/e2e/ps_test.go         | 15 +++++++++++++++
 2 files changed, 21 insertions(+)

diff --git a/cmd/podman/containers/ps.go b/cmd/podman/containers/ps.go
index 51e7bf5b5e..55b53b4d9f 100644
--- a/cmd/podman/containers/ps.go
+++ b/cmd/podman/containers/ps.go
@@ -22,6 +22,7 @@ import (
 	"github.com/cri-o/ocicni/pkg/ocicni"
 	"github.com/docker/go-units"
 	"github.com/pkg/errors"
+	"github.com/sirupsen/logrus"
 	"github.com/spf13/cobra"
 )
 
@@ -390,6 +391,11 @@ func (l psReporter) Command() string {
 // Size returns the rootfs and virtual sizes in human duration in
 // and output form (string) suitable for ps
 func (l psReporter) Size() string {
+	if l.ListContainer.Size == nil {
+		logrus.Errorf("Size format requires --size option")
+		return ""
+	}
+
 	virt := units.HumanSizeWithPrecision(float64(l.ListContainer.Size.RootFsSize), 3)
 	s := units.HumanSizeWithPrecision(float64(l.ListContainer.Size.RwSize), 3)
 	return fmt.Sprintf("%s (virtual %s)", s, virt)
diff --git a/test/e2e/ps_test.go b/test/e2e/ps_test.go
index 225bd538ee..016b4c8cd9 100644
--- a/test/e2e/ps_test.go
+++ b/test/e2e/ps_test.go
@@ -350,6 +350,21 @@ var _ = Describe("Podman ps", func() {
 		Expect(session).To(ExitWithError())
 	})
 
+	It("podman --format by size", func() {
+		session := podmanTest.Podman([]string{"create", "busybox", "ls"})
+		session.WaitWithDefaultTimeout()
+		Expect(session.ExitCode()).To(Equal(0))
+
+		session = podmanTest.Podman([]string{"create", "-t", ALPINE, "top"})
+		session.WaitWithDefaultTimeout()
+		Expect(session.ExitCode()).To(Equal(0))
+
+		session = podmanTest.Podman([]string{"ps", "-a", "--format", "{{.Size}}"})
+		session.WaitWithDefaultTimeout()
+		Expect(session.ExitCode()).To(Equal(0))
+		Expect(session.ErrorToString()).To(ContainSubstring("Size format requires --size option"))
+	})
+
 	It("podman --sort by size", func() {
 		session := podmanTest.Podman([]string{"create", "busybox", "ls"})
 		session.WaitWithDefaultTimeout()