@@ -19,7 +19,7 @@ import (
1919 "github.com/checkpoint-restore/go-criu/v7/crit"
2020 "github.com/containers/storage/pkg/archive"
2121 "github.com/olekukonko/tablewriter"
22- spec "github.com/opencontainers/runtime-spec/specs-go"
22+ specs "github.com/opencontainers/runtime-spec/specs-go"
2323)
2424
2525var pageSize = os .Getpagesize ()
@@ -41,20 +41,42 @@ type containerInfo struct {
4141
4242type checkpointInfo struct {
4343 containerInfo * containerInfo
44- specDump * spec .Spec
44+ specDump * specs .Spec
4545 configDump * metadata.ContainerConfig
4646 archiveSizes * archiveSizes
4747}
4848
49- func getPodmanInfo (containerConfig * metadata.ContainerConfig , _ * spec .Spec ) * containerInfo {
50- return & containerInfo {
49+ func getPodmanInfo (containerConfig * metadata.ContainerConfig , specDump * specs .Spec , task Task ) * containerInfo {
50+ info := & containerInfo {
5151 Name : containerConfig .Name ,
5252 Created : containerConfig .CreatedTime .Format (time .RFC3339 ),
5353 Engine : "Podman" ,
5454 }
55+
56+ // Try to get network information from network.status file
57+ if specDump .Annotations ["io.container.manager" ] == "libpod" {
58+ // Create temp dir for network status file
59+ tmpDir , err := os .MkdirTemp ("" , "network-status" )
60+ if err == nil {
61+ defer os .RemoveAll (tmpDir )
62+
63+ // Extract network.status file
64+ err = UntarFiles (task .CheckpointFilePath , tmpDir , []string {metadata .NetworkStatusFile })
65+ if err == nil {
66+ networkStatusFile := filepath .Join (tmpDir , metadata .NetworkStatusFile )
67+ ip , mac , err := getPodmanNetworkInfo (networkStatusFile )
68+ if err == nil {
69+ info .IP = ip
70+ info .MAC = mac
71+ }
72+ }
73+ }
74+ }
75+
76+ return info
5577}
5678
57- func getContainerdInfo (containerConfig * metadata.ContainerConfig , specDump * spec .Spec ) * containerInfo {
79+ func getContainerdInfo (containerConfig * metadata.ContainerConfig , specDump * specs .Spec ) * containerInfo {
5880 return & containerInfo {
5981 Name : specDump .Annotations ["io.kubernetes.cri.container-name" ],
6082 Created : containerConfig .CreatedTime .Format (time .RFC3339 ),
@@ -64,7 +86,7 @@ func getContainerdInfo(containerConfig *metadata.ContainerConfig, specDump *spec
6486 }
6587}
6688
67- func getCRIOInfo (_ * metadata.ContainerConfig , specDump * spec .Spec ) (* containerInfo , error ) {
89+ func getCRIOInfo (_ * metadata.ContainerConfig , specDump * specs .Spec ) (* containerInfo , error ) {
6890 cm := containerMetadata {}
6991 if err := json .Unmarshal ([]byte (specDump .Annotations ["io.kubernetes.cri-o.Metadata" ]), & cm ); err != nil {
7092 return nil , fmt .Errorf ("failed to read io.kubernetes.cri-o.Metadata: %w" , err )
@@ -86,14 +108,23 @@ func getCheckpointInfo(task Task) (*checkpointInfo, error) {
86108
87109 info .configDump , _ , err = metadata .ReadContainerCheckpointConfigDump (task .OutputDir )
88110 if err != nil {
89- return nil , err
111+ if strings .Contains (err .Error (), "unexpected end of JSON input" ) {
112+ return nil , fmt .Errorf ("config.dump: unexpected end of JSON input" )
113+ }
114+ return nil , fmt .Errorf ("config.dump: %w" , err )
90115 }
91116 info .specDump , _ , err = metadata .ReadContainerCheckpointSpecDump (task .OutputDir )
92117 if err != nil {
93- return nil , err
118+ if os .IsNotExist (err ) {
119+ return nil , fmt .Errorf ("spec.dump: no such file or directory" )
120+ }
121+ if strings .Contains (err .Error (), "unexpected end of JSON input" ) {
122+ return nil , fmt .Errorf ("spec.dump: unexpected end of JSON input" )
123+ }
124+ return nil , fmt .Errorf ("spec.dump: %w" , err )
94125 }
95126
96- info .containerInfo , err = getContainerInfo (info .specDump , info .configDump )
127+ info .containerInfo , err = getContainerInfo (info .specDump , info .configDump , task )
97128 if err != nil {
98129 return nil , err
99130 }
@@ -115,18 +146,25 @@ func ShowContainerCheckpoints(tasks []Task) error {
115146 "Runtime" ,
116147 "Created" ,
117148 "Engine" ,
118- }
119- // Set all columns in the table header upfront when displaying more than one checkpoint
120- if len ( tasks ) > 1 {
121- header = append ( header , "IP" , "MAC" , "CHKPT Size" , " Root Fs Diff Size")
149+ "IP" ,
150+ "MAC" ,
151+ "CHKPT Size" ,
152+ " Root FS Diff Size",
122153 }
123154
124155 for _ , task := range tasks {
125156 info , err := getCheckpointInfo (task )
126157 if err != nil {
158+ if strings .Contains (err .Error (), "Error: " ) {
159+ return fmt .Errorf ("%s" , strings .TrimPrefix (err .Error (), "Error: " ))
160+ }
127161 return err
128162 }
129163
164+ if len (tasks ) == 1 {
165+ fmt .Printf ("Displaying container checkpoint data from %s\n " , task .CheckpointFilePath )
166+ }
167+
130168 var row []string
131169 row = append (row , info .containerInfo .Name )
132170 row = append (row , info .configDump .RootfsImageName )
@@ -135,37 +173,13 @@ func ShowContainerCheckpoints(tasks []Task) error {
135173 } else {
136174 row = append (row , info .configDump .ID )
137175 }
138-
139176 row = append (row , info .configDump .OCIRuntime )
140177 row = append (row , info .containerInfo .Created )
141178 row = append (row , info .containerInfo .Engine )
142-
143- if len (tasks ) == 1 {
144- fmt .Printf ("\n Displaying container checkpoint data from %s\n \n " , task .CheckpointFilePath )
145-
146- if info .containerInfo .IP != "" {
147- header = append (header , "IP" )
148- row = append (row , info .containerInfo .IP )
149- }
150- if info .containerInfo .MAC != "" {
151- header = append (header , "MAC" )
152- row = append (row , info .containerInfo .MAC )
153- }
154-
155- header = append (header , "CHKPT Size" )
156- row = append (row , metadata .ByteToString (info .archiveSizes .checkpointSize ))
157-
158- // Display root fs diff size if available
159- if info .archiveSizes .rootFsDiffTarSize != 0 {
160- header = append (header , "Root Fs Diff Size" )
161- row = append (row , metadata .ByteToString (info .archiveSizes .rootFsDiffTarSize ))
162- }
163- } else {
164- row = append (row , info .containerInfo .IP )
165- row = append (row , info .containerInfo .MAC )
166- row = append (row , metadata .ByteToString (info .archiveSizes .checkpointSize ))
167- row = append (row , metadata .ByteToString (info .archiveSizes .rootFsDiffTarSize ))
168- }
179+ row = append (row , info .containerInfo .IP )
180+ row = append (row , info .containerInfo .MAC )
181+ row = append (row , metadata .ByteToString (info .archiveSizes .checkpointSize ))
182+ row = append (row , metadata .ByteToString (info .archiveSizes .rootFsDiffTarSize ))
169183
170184 table .Append (row )
171185 }
@@ -178,11 +192,11 @@ func ShowContainerCheckpoints(tasks []Task) error {
178192 return nil
179193}
180194
181- func getContainerInfo (specDump * spec .Spec , containerConfig * metadata.ContainerConfig ) (* containerInfo , error ) {
195+ func getContainerInfo (specDump * specs .Spec , containerConfig * metadata.ContainerConfig , task Task ) (* containerInfo , error ) {
182196 var ci * containerInfo
183197 switch m := specDump .Annotations ["io.container.manager" ]; m {
184198 case "libpod" :
185- ci = getPodmanInfo (containerConfig , specDump )
199+ ci = getPodmanInfo (containerConfig , specDump , task )
186200 case "cri-o" :
187201 var err error
188202 ci , err = getCRIOInfo (containerConfig , specDump )
@@ -266,7 +280,7 @@ func UntarFiles(src, dest string, files []string) error {
266280 }
267281 return nil
268282 }); err != nil {
269- return fmt . Errorf ( "unpacking of checkpoint archive failed: %w" , err )
283+ return err
270284 }
271285
272286 return nil
0 commit comments