Show rootfs sizes in image list
Replace the noisy rootfs path column in `banger image list` with the current rootfs file size so the table is easier to scan. Render a ROOTFS SIZE column from the on-disk image size, fall back to `-` when the artifact cannot be statted, and keep the existing image summary output unchanged. Add CLI coverage for both the formatted size case and the missing-file fallback, then rebuild and check the live command output.
This commit is contained in:
parent
14d8563f3c
commit
3b7e77a2de
2 changed files with 78 additions and 6 deletions
|
|
@ -809,12 +809,7 @@ func newImageListCommand() *cobra.Command {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
w := tabwriter.NewWriter(cmd.OutOrStdout(), 0, 8, 2, ' ', 0)
|
return printImageListTable(cmd.OutOrStdout(), result.Images)
|
||||||
fmt.Fprintln(w, "ID\tNAME\tMANAGED\tROOTFS\tCREATED")
|
|
||||||
for _, image := range result.Images {
|
|
||||||
fmt.Fprintf(w, "%s\t%s\t%t\t%s\t%s\n", shortID(image.ID), image.Name, image.Managed, image.RootfsPath, relativeTime(image.CreatedAt))
|
|
||||||
}
|
|
||||||
return w.Flush()
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1318,6 +1313,38 @@ func printImageSummary(out anyWriter, image model.Image) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func printImageListTable(out anyWriter, images []model.Image) error {
|
||||||
|
w := tabwriter.NewWriter(out, 0, 8, 2, ' ', 0)
|
||||||
|
if _, err := fmt.Fprintln(w, "ID\tNAME\tMANAGED\tROOTFS SIZE\tCREATED"); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for _, image := range images {
|
||||||
|
if _, err := fmt.Fprintf(
|
||||||
|
w,
|
||||||
|
"%s\t%s\t%t\t%s\t%s\n",
|
||||||
|
shortID(image.ID),
|
||||||
|
image.Name,
|
||||||
|
image.Managed,
|
||||||
|
rootfsSizeLabel(image.RootfsPath),
|
||||||
|
relativeTime(image.CreatedAt),
|
||||||
|
); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return w.Flush()
|
||||||
|
}
|
||||||
|
|
||||||
|
func rootfsSizeLabel(path string) string {
|
||||||
|
info, err := os.Stat(path)
|
||||||
|
if err != nil {
|
||||||
|
return "-"
|
||||||
|
}
|
||||||
|
if info.Size() <= 0 {
|
||||||
|
return "0"
|
||||||
|
}
|
||||||
|
return model.FormatSizeBytes(info.Size())
|
||||||
|
}
|
||||||
|
|
||||||
func printVMPortsTable(out anyWriter, result api.VMPortsResult) error {
|
func printVMPortsTable(out anyWriter, result api.VMPortsResult) error {
|
||||||
type portRow struct {
|
type portRow struct {
|
||||||
Proto string
|
Proto string
|
||||||
|
|
|
||||||
|
|
@ -474,6 +474,51 @@ func TestAbsolutizeImageRegisterPaths(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestPrintImageListTableShowsRootfsSizes(t *testing.T) {
|
||||||
|
rootfs := filepath.Join(t.TempDir(), "rootfs.ext4")
|
||||||
|
if err := os.WriteFile(rootfs, nil, 0o644); err != nil {
|
||||||
|
t.Fatalf("WriteFile(%s): %v", rootfs, err)
|
||||||
|
}
|
||||||
|
if err := os.Truncate(rootfs, 8*1024); err != nil {
|
||||||
|
t.Fatalf("Truncate(%s): %v", rootfs, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var out bytes.Buffer
|
||||||
|
err := printImageListTable(&out, []model.Image{
|
||||||
|
{
|
||||||
|
ID: "0123456789abcdef",
|
||||||
|
Name: "alpine",
|
||||||
|
Managed: true,
|
||||||
|
RootfsPath: rootfs,
|
||||||
|
CreatedAt: time.Now().Add(-1 * time.Hour),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "fedcba9876543210",
|
||||||
|
Name: "missing",
|
||||||
|
Managed: false,
|
||||||
|
RootfsPath: filepath.Join(t.TempDir(), "missing.ext4"),
|
||||||
|
CreatedAt: time.Now().Add(-2 * time.Hour),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("printImageListTable() error = %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
output := out.String()
|
||||||
|
if !strings.Contains(output, "ROOTFS SIZE") {
|
||||||
|
t.Fatalf("output = %q, want rootfs size header", output)
|
||||||
|
}
|
||||||
|
if !strings.Contains(output, "alpine") || !strings.Contains(output, "8K") {
|
||||||
|
t.Fatalf("output = %q, want alpine row with 8K size", output)
|
||||||
|
}
|
||||||
|
if strings.Contains(output, rootfs) {
|
||||||
|
t.Fatalf("output = %q, should not include rootfs path", output)
|
||||||
|
}
|
||||||
|
if !strings.Contains(output, "missing") || !strings.Contains(output, "-") {
|
||||||
|
t.Fatalf("output = %q, want fallback size for missing image", output)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestPrintVMPortsTableSortsAndRendersURLEndpoints(t *testing.T) {
|
func TestPrintVMPortsTableSortsAndRendersURLEndpoints(t *testing.T) {
|
||||||
result := api.VMPortsResult{
|
result := api.VMPortsResult{
|
||||||
Name: "alpha",
|
Name: "alpha",
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue