Skip to content

Commit bd27bef

Browse files
committed
Move checkpoint and restore commands to new files
Signed-off-by: Michael Crosby <[email protected]>
1 parent f80d285 commit bd27bef

3 files changed

Lines changed: 198 additions & 146 deletions

File tree

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
/*
2+
Copyright The containerd Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package containers
18+
19+
import (
20+
"fmt"
21+
22+
"github.com/containerd/containerd"
23+
"github.com/containerd/containerd/cmd/ctr/commands"
24+
"github.com/containerd/containerd/errdefs"
25+
"github.com/pkg/errors"
26+
"github.com/urfave/cli"
27+
)
28+
29+
var checkpointCommand = cli.Command{
30+
Name: "checkpoint",
31+
Usage: "checkpoint a container",
32+
ArgsUsage: "CONTAINER REF",
33+
Flags: []cli.Flag{
34+
cli.BoolFlag{
35+
Name: "rw",
36+
Usage: "include the rw layer in the checkpoint",
37+
},
38+
cli.BoolFlag{
39+
Name: "image",
40+
Usage: "include the image in the checkpoint",
41+
},
42+
cli.BoolFlag{
43+
Name: "task",
44+
Usage: "checkpoint container task",
45+
},
46+
},
47+
Action: func(context *cli.Context) error {
48+
id := context.Args().First()
49+
if id == "" {
50+
return errors.New("container id must be provided")
51+
}
52+
ref := context.Args().Get(1)
53+
if ref == "" {
54+
return errors.New("ref must be provided")
55+
}
56+
client, ctx, cancel, err := commands.NewClient(context)
57+
if err != nil {
58+
return err
59+
}
60+
defer cancel()
61+
opts := []containerd.CheckpointOpts{
62+
containerd.WithCheckpointRuntime,
63+
}
64+
65+
if context.Bool("image") {
66+
opts = append(opts, containerd.WithCheckpointImage)
67+
}
68+
if context.Bool("rw") {
69+
opts = append(opts, containerd.WithCheckpointRW)
70+
}
71+
if context.Bool("task") {
72+
opts = append(opts, containerd.WithCheckpointTask)
73+
}
74+
container, err := client.LoadContainer(ctx, id)
75+
if err != nil {
76+
return err
77+
}
78+
task, err := container.Task(ctx, nil)
79+
if err != nil {
80+
if !errdefs.IsNotFound(err) {
81+
return err
82+
}
83+
}
84+
// pause if running
85+
if task != nil {
86+
if err := task.Pause(ctx); err != nil {
87+
return err
88+
}
89+
defer func() {
90+
if err := task.Resume(ctx); err != nil {
91+
fmt.Println(errors.Wrap(err, "error resuming task"))
92+
}
93+
}()
94+
}
95+
96+
if _, err := container.Checkpoint(ctx, ref, opts...); err != nil {
97+
return err
98+
}
99+
100+
return nil
101+
},
102+
}

cmd/ctr/commands/containers/containers.go

Lines changed: 0 additions & 146 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ import (
2828
"github.com/containerd/containerd/cmd/ctr/commands"
2929
"github.com/containerd/containerd/cmd/ctr/commands/run"
3030
"github.com/containerd/containerd/containers"
31-
"github.com/containerd/containerd/errdefs"
3231
"github.com/containerd/containerd/log"
3332
"github.com/containerd/typeurl"
3433
"github.com/pkg/errors"
@@ -285,148 +284,3 @@ var infoCommand = cli.Command{
285284
return nil
286285
},
287286
}
288-
289-
var checkpointCommand = cli.Command{
290-
Name: "checkpoint",
291-
Usage: "checkpoint a container",
292-
ArgsUsage: "CONTAINER REF",
293-
Flags: []cli.Flag{
294-
cli.BoolFlag{
295-
Name: "rw",
296-
Usage: "include the rw layer in the checkpoint",
297-
},
298-
cli.BoolFlag{
299-
Name: "image",
300-
Usage: "include the image in the checkpoint",
301-
},
302-
cli.BoolFlag{
303-
Name: "task",
304-
Usage: "checkpoint container task",
305-
},
306-
},
307-
Action: func(context *cli.Context) error {
308-
id := context.Args().First()
309-
if id == "" {
310-
return errors.New("container id must be provided")
311-
}
312-
ref := context.Args().Get(1)
313-
if ref == "" {
314-
return errors.New("ref must be provided")
315-
}
316-
client, ctx, cancel, err := commands.NewClient(context)
317-
if err != nil {
318-
return err
319-
}
320-
defer cancel()
321-
opts := []containerd.CheckpointOpts{
322-
containerd.WithCheckpointRuntime,
323-
}
324-
325-
if context.Bool("image") {
326-
opts = append(opts, containerd.WithCheckpointImage)
327-
}
328-
if context.Bool("rw") {
329-
opts = append(opts, containerd.WithCheckpointRW)
330-
}
331-
if context.Bool("task") {
332-
opts = append(opts, containerd.WithCheckpointTask)
333-
}
334-
container, err := client.LoadContainer(ctx, id)
335-
if err != nil {
336-
return err
337-
}
338-
task, err := container.Task(ctx, nil)
339-
if err != nil {
340-
if !errdefs.IsNotFound(err) {
341-
return err
342-
}
343-
}
344-
// pause if running
345-
if task != nil {
346-
if err := task.Pause(ctx); err != nil {
347-
return err
348-
}
349-
defer func() {
350-
if err := task.Resume(ctx); err != nil {
351-
fmt.Println(errors.Wrap(err, "error resuming task"))
352-
}
353-
}()
354-
}
355-
356-
if _, err := container.Checkpoint(ctx, ref, opts...); err != nil {
357-
return err
358-
}
359-
360-
return nil
361-
},
362-
}
363-
364-
var restoreCommand = cli.Command{
365-
Name: "restore",
366-
Usage: "restore a container from checkpoint",
367-
ArgsUsage: "CONTAINER REF",
368-
Flags: []cli.Flag{
369-
cli.BoolFlag{
370-
Name: "rw",
371-
Usage: "restore the rw layer from the checkpoint",
372-
},
373-
cli.BoolFlag{
374-
Name: "live",
375-
Usage: "restore the runtime and memory data from the checkpoint",
376-
},
377-
},
378-
Action: func(context *cli.Context) error {
379-
id := context.Args().First()
380-
if id == "" {
381-
return errors.New("container id must be provided")
382-
}
383-
ref := context.Args().Get(1)
384-
if ref == "" {
385-
return errors.New("ref must be provided")
386-
}
387-
client, ctx, cancel, err := commands.NewClient(context)
388-
if err != nil {
389-
return err
390-
}
391-
defer cancel()
392-
393-
checkpoint, err := client.GetImage(ctx, ref)
394-
if err != nil {
395-
if !errdefs.IsNotFound(err) {
396-
return err
397-
}
398-
// TODO (ehazlett): consider other options (always/never fetch)
399-
ck, err := client.Fetch(ctx, ref)
400-
if err != nil {
401-
return err
402-
}
403-
checkpoint = containerd.NewImage(client, ck)
404-
}
405-
406-
opts := []containerd.RestoreOpts{
407-
containerd.WithRestoreImage,
408-
containerd.WithRestoreSpec,
409-
containerd.WithRestoreRuntime,
410-
}
411-
if context.Bool("rw") {
412-
opts = append(opts, containerd.WithRestoreRW)
413-
}
414-
415-
ctr, err := client.Restore(ctx, id, checkpoint, opts...)
416-
if err != nil {
417-
return err
418-
}
419-
420-
topts := []containerd.NewTaskOpts{}
421-
if context.Bool("live") {
422-
topts = append(topts, containerd.WithTaskCheckpoint(checkpoint))
423-
}
424-
425-
task, err := ctr.NewTask(ctx, cio.NewCreator(cio.WithStdio), topts...)
426-
if err != nil {
427-
return err
428-
}
429-
430-
return task.Start(ctx)
431-
},
432-
}
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
/*
2+
Copyright The containerd Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package containers
18+
19+
import (
20+
"github.com/containerd/containerd"
21+
"github.com/containerd/containerd/cio"
22+
"github.com/containerd/containerd/cmd/ctr/commands"
23+
"github.com/containerd/containerd/errdefs"
24+
"github.com/pkg/errors"
25+
"github.com/urfave/cli"
26+
)
27+
28+
var restoreCommand = cli.Command{
29+
Name: "restore",
30+
Usage: "restore a container from checkpoint",
31+
ArgsUsage: "CONTAINER REF",
32+
Flags: []cli.Flag{
33+
cli.BoolFlag{
34+
Name: "rw",
35+
Usage: "restore the rw layer from the checkpoint",
36+
},
37+
cli.BoolFlag{
38+
Name: "live",
39+
Usage: "restore the runtime and memory data from the checkpoint",
40+
},
41+
},
42+
Action: func(context *cli.Context) error {
43+
id := context.Args().First()
44+
if id == "" {
45+
return errors.New("container id must be provided")
46+
}
47+
ref := context.Args().Get(1)
48+
if ref == "" {
49+
return errors.New("ref must be provided")
50+
}
51+
client, ctx, cancel, err := commands.NewClient(context)
52+
if err != nil {
53+
return err
54+
}
55+
defer cancel()
56+
57+
checkpoint, err := client.GetImage(ctx, ref)
58+
if err != nil {
59+
if !errdefs.IsNotFound(err) {
60+
return err
61+
}
62+
// TODO (ehazlett): consider other options (always/never fetch)
63+
ck, err := client.Fetch(ctx, ref)
64+
if err != nil {
65+
return err
66+
}
67+
checkpoint = containerd.NewImage(client, ck)
68+
}
69+
70+
opts := []containerd.RestoreOpts{
71+
containerd.WithRestoreImage,
72+
containerd.WithRestoreSpec,
73+
containerd.WithRestoreRuntime,
74+
}
75+
if context.Bool("rw") {
76+
opts = append(opts, containerd.WithRestoreRW)
77+
}
78+
79+
ctr, err := client.Restore(ctx, id, checkpoint, opts...)
80+
if err != nil {
81+
return err
82+
}
83+
84+
topts := []containerd.NewTaskOpts{}
85+
if context.Bool("live") {
86+
topts = append(topts, containerd.WithTaskCheckpoint(checkpoint))
87+
}
88+
89+
task, err := ctr.NewTask(ctx, cio.NewCreator(cio.WithStdio), topts...)
90+
if err != nil {
91+
return err
92+
}
93+
94+
return task.Start(ctx)
95+
},
96+
}

0 commit comments

Comments
 (0)