Skip to content

Commit

Permalink
reduce code duplication between table and tree rendering functions
Browse files Browse the repository at this point in the history
This commit reduces code duplication between the table and the tree
rendering logics. The duplicated logic for retrieving checkpoint
information has been extracted into a reusable function:
`getCheckpointInfo`.

Signed-off-by: Kouame Behouba Manasse <[email protected]>
  • Loading branch information
behouba committed Jul 1, 2023
1 parent 841c90f commit c87413c
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 74 deletions.
2 changes: 1 addition & 1 deletion checkpointctl.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ func setupInspect() *cobra.Command {
&format,
"format",
"tree",
"Format the output using a tree or json format",
"Specify the output format [tree (default), json]",
)

err := flags.MarkHidden("print-stats")
Expand Down
90 changes: 53 additions & 37 deletions container.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,13 @@ type containerInfo struct {
Engine string
}

type checkpointInfo struct {
containerInfo *containerInfo
specDump *spec.Spec
configDump *metadata.ContainerConfig
archiveSizes *archiveSizes
}

func getPodmanInfo(containerConfig *metadata.ContainerConfig, _ *spec.Spec) *containerInfo {
return &containerInfo{
Name: containerConfig.Name,
Expand Down Expand Up @@ -64,6 +71,32 @@ func getCRIOInfo(_ *metadata.ContainerConfig, specDump *spec.Spec) (*containerIn
}, nil
}

func getCheckpointInfo(task task) (*checkpointInfo, error) {
info := &checkpointInfo{}
var err error

info.configDump, _, err = metadata.ReadContainerCheckpointConfigDump(task.outputDir)
if err != nil {
return nil, err
}
info.specDump, _, err = metadata.ReadContainerCheckpointSpecDump(task.outputDir)
if err != nil {
return nil, err
}

info.containerInfo, err = getContainerInfo(task.outputDir, info.specDump, info.configDump)
if err != nil {
return nil, err
}

info.archiveSizes, err = getArchiveSizes(task.checkpointFilePath)
if err != nil {
return nil, err
}

return info, nil
}

func showContainerCheckpoints(tasks []task) error {
table := tablewriter.NewWriter(os.Stdout)
header := []string{
Expand All @@ -79,67 +112,50 @@ func showContainerCheckpoints(tasks []task) error {
header = append(header, "IP", "MAC", "CHKPT Size", "Root Fs Diff Size")
}

var specDump *spec.Spec
var ci *containerInfo

for _, task := range tasks {
containerConfig, _, err := metadata.ReadContainerCheckpointConfigDump(task.outputDir)
if err != nil {
return err
}
specDump, _, err = metadata.ReadContainerCheckpointSpecDump(task.outputDir)
if err != nil {
return err
}

ci, err = getContainerInfo(task.outputDir, specDump, containerConfig)
if err != nil {
return err
}

archiveSizes, err := getArchiveSizes(task.checkpointFilePath)
info, err := getCheckpointInfo(task)
if err != nil {
return err
}

var row []string
row = append(row, ci.Name)
row = append(row, containerConfig.RootfsImageName)
if len(containerConfig.ID) > 12 {
row = append(row, containerConfig.ID[:12])
row = append(row, info.containerInfo.Name)
row = append(row, info.configDump.RootfsImageName)
if len(info.configDump.ID) > 12 {
row = append(row, info.configDump.ID[:12])
} else {
row = append(row, containerConfig.ID)
row = append(row, info.configDump.ID)
}

row = append(row, containerConfig.OCIRuntime)
row = append(row, ci.Created)
row = append(row, ci.Engine)
row = append(row, info.configDump.OCIRuntime)
row = append(row, info.containerInfo.Created)
row = append(row, info.containerInfo.Engine)

if len(tasks) == 1 {
fmt.Printf("\nDisplaying container checkpoint data from %s\n\n", task.checkpointFilePath)

if ci.IP != "" {
if info.containerInfo.IP != "" {
header = append(header, "IP")
row = append(row, ci.IP)
row = append(row, info.containerInfo.IP)
}
if ci.MAC != "" {
if info.containerInfo.MAC != "" {
header = append(header, "MAC")
row = append(row, ci.MAC)
row = append(row, info.containerInfo.MAC)
}

header = append(header, "CHKPT Size")
row = append(row, metadata.ByteToString(archiveSizes.checkpointSize))
row = append(row, metadata.ByteToString(info.archiveSizes.checkpointSize))

// Display root fs diff size if available
if archiveSizes.rootFsDiffTarSize != 0 {
if info.archiveSizes.rootFsDiffTarSize != 0 {
header = append(header, "Root Fs Diff Size")
row = append(row, metadata.ByteToString(archiveSizes.rootFsDiffTarSize))
row = append(row, metadata.ByteToString(info.archiveSizes.rootFsDiffTarSize))
}
} else {
row = append(row, ci.IP)
row = append(row, ci.MAC)
row = append(row, metadata.ByteToString(archiveSizes.checkpointSize))
row = append(row, metadata.ByteToString(archiveSizes.rootFsDiffTarSize))
row = append(row, info.containerInfo.IP)
row = append(row, info.containerInfo.MAC)
row = append(row, metadata.ByteToString(info.archiveSizes.checkpointSize))
row = append(row, metadata.ByteToString(info.archiveSizes.rootFsDiffTarSize))
}

table.Append(row)
Expand Down
23 changes: 5 additions & 18 deletions test/checkpointctl.bats
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,6 @@ function teardown() {
@test "Run checkpointctl show with tar file from containerd with valid config.dump and valid spec.dump and checkpoint directory" {
cp data/config.dump "$TEST_TMP_DIR1"
mkdir "$TEST_TMP_DIR1"/checkpoint
echo "{}" > "$TEST_TMP_DIR1"/status
echo "{}" > "$TEST_TMP_DIR1"/spec.dump
( cd "$TEST_TMP_DIR1" && tar cf "$TEST_TMP_DIR2"/test.tar . )
checkpointctl show "$TEST_TMP_DIR2"/test.tar
Expand Down Expand Up @@ -184,7 +183,7 @@ function teardown() {
touch "$TEST_TMP_DIR1"/config.dump
mkdir "$TEST_TMP_DIR1"/checkpoint
( cd "$TEST_TMP_DIR1" && tar cf "$TEST_TMP_DIR2"/test.tar . )
checkpointctl inspect "$TEST_TMP_DIR2"/test.tar --format=xml
checkpointctl inspect "$TEST_TMP_DIR2"/test.tar --format=invalid
[ "$status" -eq 1 ]
[[ ${lines[0]} == *"invalid output format"* ]]
}
Expand Down Expand Up @@ -263,16 +262,14 @@ function teardown() {
[[ ${lines[10]} == *"proc"* ]]
}

@test "Run checkpointctl inspect with tar file and --mounts and --full-paths and valid spec.dump" {
@test "Run checkpointctl inspect with tar file and --ps-tree and missing pstree.img" {
cp data/config.dump "$TEST_TMP_DIR1"
cp data/spec.dump "$TEST_TMP_DIR1"
mkdir "$TEST_TMP_DIR1"/checkpoint
( cd "$TEST_TMP_DIR1" && tar cf "$TEST_TMP_DIR2"/test.tar . )
checkpointctl inspect "$TEST_TMP_DIR2"/test.tar --mounts --full-paths
[ "$status" -eq 0 ]
[[ ${lines[8]} == *"Overview of Mounts"* ]]
[[ ${lines[9]} == *"Destination"* ]]
[[ ${lines[10]} == *"proc"* ]]
checkpointctl inspect "$TEST_TMP_DIR2"/test.tar --ps-tree
[ "$status" -eq 1 ]
[[ ${lines[0]} == *"failed to get process tree"* ]]
}

@test "Run checkpointctl inspect with tar file and --all and valid spec.dump and valid stats-dump" {
Expand All @@ -296,16 +293,6 @@ function teardown() {
[[ ${lines[23]} == *"piggie"* ]]
}

@test "Run checkpointctl inspect with tar file and missing --mounts/--all and --full-paths" {
cp data/config.dump "$TEST_TMP_DIR1"
cp data/spec.dump "$TEST_TMP_DIR1"
mkdir "$TEST_TMP_DIR1"/checkpoint
( cd "$TEST_TMP_DIR1" && tar cf "$TEST_TMP_DIR2"/test.tar . )
checkpointctl inspect "$TEST_TMP_DIR2"/test.tar --full-paths
[ "$status" -eq 1 ]
[[ ${lines[0]} == *"Error: cannot use --full-paths without --mounts/--all option"* ]]
}

@test "Run checkpointctl inspect with tar file with valid config.dump and valid spec.dump and no checkpoint directory" {
cp data/config.dump "$TEST_TMP_DIR1"
cp data/spec.dump "$TEST_TMP_DIR1"
Expand Down
21 changes: 3 additions & 18 deletions tree.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,30 +13,15 @@ import (

func renderTreeView(tasks []task) error {
for _, task := range tasks {
containerConfig, _, err := metadata.ReadContainerCheckpointConfigDump(task.outputDir)
info, err := getCheckpointInfo(task)
if err != nil {
return err
}

specDump, _, err := metadata.ReadContainerCheckpointSpecDump(task.outputDir)
if err != nil {
return err
}

ci, err := getContainerInfo(task.outputDir, specDump, containerConfig)
if err != nil {
return err
}

archiveSizes, err := getArchiveSizes(task.checkpointFilePath)
if err != nil {
return err
}

tree := buildTree(ci, containerConfig, archiveSizes)
tree := buildTree(info.containerInfo, info.configDump, info.archiveSizes)

if mounts {
addMountsToTree(tree, specDump)
addMountsToTree(tree, info.specDump)
}

if stats {
Expand Down

0 comments on commit c87413c

Please sign in to comment.