Skip to content

Commit 40caece

Browse files
committed
update tests
Signed-off-by: Evan Hazlett <[email protected]>
1 parent 4fdf720 commit 40caece

6 files changed

+84
-109
lines changed

cmd/ctr/commands/commands.go

-4
Original file line numberDiff line numberDiff line change
@@ -71,10 +71,6 @@ var (
7171
Name: "config,c",
7272
Usage: "path to the runtime-specific spec config file",
7373
},
74-
cli.StringFlag{
75-
Name: "checkpoint",
76-
Usage: "provide the checkpoint digest to restore the container",
77-
},
7874
cli.StringFlag{
7975
Name: "cwd",
8076
Usage: "specify the working directory of the process",

cmd/ctr/commands/run/run_unix.go

-8
Original file line numberDiff line numberDiff line change
@@ -44,14 +44,6 @@ func NewContainer(ctx gocontext.Context, client *containerd.Client, context *cli
4444
id = context.Args().Get(1)
4545
}
4646

47-
if raw := context.String("checkpoint"); raw != "" {
48-
im, err := client.GetImage(ctx, raw)
49-
if err != nil {
50-
return nil, err
51-
}
52-
return client.NewContainer(ctx, id, containerd.WithCheckpoint(im, id), containerd.WithRuntime(context.String("runtime"), nil))
53-
}
54-
5547
var (
5648
opts []oci.SpecOpts
5749
cOpts []containerd.NewContainerOpts

container_checkpoint_opts.go

+6
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,12 @@ func WithCheckpointRW(ctx context.Context, client *Client, c *containers.Contain
124124
return nil
125125
}
126126

127+
// WithCheckpointTaskExit causes the task to exit after checkpoint
128+
func WithCheckpointTaskExit(ctx context.Context, client *Client, c *containers.Container, index *imagespec.Index, copts *options.CheckpointOptions) error {
129+
copts.Exit = true
130+
return nil
131+
}
132+
127133
// GetIndexByMediaType returns the index in a manifest for the specified media type
128134
func GetIndexByMediaType(index *imagespec.Index, mt string) (*imagespec.Descriptor, error) {
129135
for _, d := range index.Manifests {

container_checkpoint_test.go

+77-27
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,11 @@ import (
2828
"testing"
2929

3030
"github.com/containerd/containerd/oci"
31-
"github.com/containerd/containerd/runtime/linux/runctypes"
32-
"github.com/containerd/containerd/runtime/v2/runc/options"
31+
)
32+
33+
const (
34+
v1runtime = "io.containerd.runtime.v1.linux"
35+
testCheckpointName = "checkpoint-test:latest"
3336
)
3437

3538
func TestCheckpointRestorePTY(t *testing.T) {
@@ -41,6 +44,9 @@ func TestCheckpointRestorePTY(t *testing.T) {
4144
t.Fatal(err)
4245
}
4346
defer client.Close()
47+
if client.runtime == v1runtime {
48+
t.Skip()
49+
}
4450

4551
var (
4652
ctx, cancel = testContext()
@@ -56,7 +62,8 @@ func TestCheckpointRestorePTY(t *testing.T) {
5662
WithNewSnapshot(id, image),
5763
WithNewSpec(oci.WithImageConfig(image),
5864
oci.WithProcessArgs("sh", "-c", "read A; echo z${A}z"),
59-
oci.WithTTY))
65+
oci.WithTTY),
66+
)
6067
if err != nil {
6168
t.Fatal(err)
6269
}
@@ -83,7 +90,12 @@ func TestCheckpointRestorePTY(t *testing.T) {
8390
t.Fatal(err)
8491
}
8592

86-
checkpoint, err := task.Checkpoint(ctx, withExit(client))
93+
checkpoint, err := container.Checkpoint(ctx, testCheckpointName+"withpty", []CheckpointOpts{
94+
WithCheckpointRuntime,
95+
WithCheckpointRW,
96+
WithCheckpointTaskExit,
97+
WithCheckpointTask,
98+
}...)
8799
if err != nil {
88100
t.Fatal(err)
89101
}
@@ -94,6 +106,10 @@ func TestCheckpointRestorePTY(t *testing.T) {
94106
t.Fatal(err)
95107
}
96108
direct.Delete()
109+
if err := container.Delete(ctx, WithSnapshotCleanup); err != nil {
110+
t.Fatal(err)
111+
}
112+
97113
direct, err = newDirectIO(ctx, true)
98114
if err != nil {
99115
t.Fatal(err)
@@ -109,6 +125,15 @@ func TestCheckpointRestorePTY(t *testing.T) {
109125
io.Copy(buf, direct.Stdout)
110126
}()
111127

128+
if container, err = client.Restore(ctx, id, checkpoint, []RestoreOpts{
129+
WithRestoreImage,
130+
WithRestoreSpec,
131+
WithRestoreSnapshot,
132+
WithRestoreRuntime,
133+
WithRestoreRW,
134+
}...); err != nil {
135+
t.Fatal(err)
136+
}
112137
if task, err = container.NewTask(ctx, direct.IOCreate,
113138
WithTaskCheckpoint(checkpoint)); err != nil {
114139
t.Fatal(err)
@@ -146,6 +171,9 @@ func TestCheckpointRestore(t *testing.T) {
146171
t.Fatal(err)
147172
}
148173
defer client.Close()
174+
if client.runtime == v1runtime {
175+
t.Skip()
176+
}
149177

150178
var (
151179
ctx, cancel = testContext()
@@ -157,7 +185,7 @@ func TestCheckpointRestore(t *testing.T) {
157185
if err != nil {
158186
t.Fatal(err)
159187
}
160-
container, err := client.NewContainer(ctx, id, WithNewSnapshot(id, image), WithNewSpec(oci.WithImageConfig(image), oci.WithProcessArgs("sleep", "100")))
188+
container, err := client.NewContainer(ctx, id, WithNewSnapshot(id, image), WithNewSpec(oci.WithImageConfig(image), oci.WithProcessArgs("sleep", "10")))
161189
if err != nil {
162190
t.Fatal(err)
163191
}
@@ -178,7 +206,11 @@ func TestCheckpointRestore(t *testing.T) {
178206
t.Fatal(err)
179207
}
180208

181-
checkpoint, err := task.Checkpoint(ctx, withExit(client))
209+
checkpoint, err := container.Checkpoint(ctx, testCheckpointName+"restore", []CheckpointOpts{
210+
WithCheckpointRuntime,
211+
WithCheckpointRW,
212+
WithCheckpointTask,
213+
}...)
182214
if err != nil {
183215
t.Fatal(err)
184216
}
@@ -188,6 +220,19 @@ func TestCheckpointRestore(t *testing.T) {
188220
if _, err := task.Delete(ctx); err != nil {
189221
t.Fatal(err)
190222
}
223+
if err := container.Delete(ctx, WithSnapshotCleanup); err != nil {
224+
t.Fatal(err)
225+
}
226+
227+
if container, err = client.Restore(ctx, id, checkpoint, []RestoreOpts{
228+
WithRestoreImage,
229+
WithRestoreSpec,
230+
WithRestoreSnapshot,
231+
WithRestoreRuntime,
232+
WithRestoreRW,
233+
}...); err != nil {
234+
t.Fatal(err)
235+
}
191236
if task, err = container.NewTask(ctx, empty(), WithTaskCheckpoint(checkpoint)); err != nil {
192237
t.Fatal(err)
193238
}
@@ -217,6 +262,9 @@ func TestCheckpointRestoreNewContainer(t *testing.T) {
217262
t.Fatal(err)
218263
}
219264
defer client.Close()
265+
if client.runtime == v1runtime {
266+
t.Skip()
267+
}
220268

221269
id := t.Name()
222270
ctx, cancel := testContext()
@@ -226,7 +274,7 @@ func TestCheckpointRestoreNewContainer(t *testing.T) {
226274
if err != nil {
227275
t.Fatal(err)
228276
}
229-
container, err := client.NewContainer(ctx, id, WithNewSnapshot(id, image), WithNewSpec(oci.WithImageConfig(image), oci.WithProcessArgs("sleep", "100")))
277+
container, err := client.NewContainer(ctx, id, WithNewSnapshot(id, image), WithNewSpec(oci.WithImageConfig(image), oci.WithProcessArgs("sleep", "5")))
230278
if err != nil {
231279
t.Fatal(err)
232280
}
@@ -247,7 +295,11 @@ func TestCheckpointRestoreNewContainer(t *testing.T) {
247295
t.Fatal(err)
248296
}
249297

250-
checkpoint, err := task.Checkpoint(ctx, withExit(client))
298+
checkpoint, err := container.Checkpoint(ctx, testCheckpointName+"newcontainer", []CheckpointOpts{
299+
WithCheckpointRuntime,
300+
WithCheckpointRW,
301+
WithCheckpointTask,
302+
}...)
251303
if err != nil {
252304
t.Fatal(err)
253305
}
@@ -260,7 +312,13 @@ func TestCheckpointRestoreNewContainer(t *testing.T) {
260312
if err := container.Delete(ctx, WithSnapshotCleanup); err != nil {
261313
t.Fatal(err)
262314
}
263-
if container, err = client.NewContainer(ctx, id, WithCheckpoint(checkpoint, id)); err != nil {
315+
if container, err = client.Restore(ctx, id, checkpoint, []RestoreOpts{
316+
WithRestoreImage,
317+
WithRestoreSpec,
318+
WithRestoreSnapshot,
319+
WithRestoreRuntime,
320+
WithRestoreRW,
321+
}...); err != nil {
264322
t.Fatal(err)
265323
}
266324
if task, err = container.NewTask(ctx, empty(), WithTaskCheckpoint(checkpoint)); err != nil {
@@ -290,11 +348,14 @@ func TestCheckpointLeaveRunning(t *testing.T) {
290348
if !supportsCriu {
291349
t.Skip("system does not have criu installed")
292350
}
293-
client, err := New(address)
351+
client, err := newClient(t, address)
294352
if err != nil {
295353
t.Fatal(err)
296354
}
297355
defer client.Close()
356+
if client.runtime == v1runtime {
357+
t.Skip()
358+
}
298359

299360
var (
300361
ctx, cancel = testContext()
@@ -327,7 +388,12 @@ func TestCheckpointLeaveRunning(t *testing.T) {
327388
t.Fatal(err)
328389
}
329390

330-
if _, err := task.Checkpoint(ctx); err != nil {
391+
// checkpoint
392+
if _, err := container.Checkpoint(ctx, testCheckpointName+"leaverunning", []CheckpointOpts{
393+
WithCheckpointRuntime,
394+
WithCheckpointRW,
395+
WithCheckpointTask,
396+
}...); err != nil {
331397
t.Fatal(err)
332398
}
333399

@@ -345,19 +411,3 @@ func TestCheckpointLeaveRunning(t *testing.T) {
345411

346412
<-statusC
347413
}
348-
349-
func withExit(client *Client) CheckpointTaskOpts {
350-
return func(r *CheckpointTaskInfo) error {
351-
switch client.runtime {
352-
case "io.containerd.runc.v1":
353-
r.Options = &options.CheckpointOptions{
354-
Exit: true,
355-
}
356-
default:
357-
r.Options = &runctypes.CheckpointOptions{
358-
Exit: true,
359-
}
360-
}
361-
return nil
362-
}
363-
}

container_opts_unix.go

-69
Original file line numberDiff line numberDiff line change
@@ -26,81 +26,12 @@ import (
2626
"syscall"
2727

2828
"github.com/containerd/containerd/containers"
29-
"github.com/containerd/containerd/content"
3029
"github.com/containerd/containerd/errdefs"
31-
"github.com/containerd/containerd/images"
3230
"github.com/containerd/containerd/mount"
3331
"github.com/containerd/containerd/platforms"
34-
"github.com/gogo/protobuf/proto"
35-
protobuf "github.com/gogo/protobuf/types"
3632
"github.com/opencontainers/image-spec/identity"
37-
"github.com/opencontainers/image-spec/specs-go/v1"
38-
"github.com/pkg/errors"
3933
)
4034

41-
// WithCheckpoint allows a container to be created from the checkpointed information
42-
// provided by the descriptor. The image, snapshot, and runtime specifications are
43-
// restored on the container
44-
func WithCheckpoint(im Image, snapshotKey string) NewContainerOpts {
45-
// set image and rw, and spec
46-
return func(ctx context.Context, client *Client, c *containers.Container) error {
47-
var (
48-
desc = im.Target()
49-
store = client.ContentStore()
50-
)
51-
index, err := decodeIndex(ctx, store, desc)
52-
if err != nil {
53-
return err
54-
}
55-
var rw *v1.Descriptor
56-
for _, m := range index.Manifests {
57-
switch m.MediaType {
58-
case v1.MediaTypeImageLayer:
59-
fk := m
60-
rw = &fk
61-
case images.MediaTypeDockerSchema2Manifest, images.MediaTypeDockerSchema2ManifestList:
62-
config, err := images.Config(ctx, store, m, platforms.Default())
63-
if err != nil {
64-
return errors.Wrap(err, "unable to resolve image config")
65-
}
66-
diffIDs, err := images.RootFS(ctx, store, config)
67-
if err != nil {
68-
return errors.Wrap(err, "unable to get rootfs")
69-
}
70-
setSnapshotterIfEmpty(c)
71-
if _, err := client.SnapshotService(c.Snapshotter).Prepare(ctx, snapshotKey, identity.ChainID(diffIDs).String()); err != nil {
72-
if !errdefs.IsAlreadyExists(err) {
73-
return err
74-
}
75-
}
76-
c.Image = index.Annotations["image.name"]
77-
case images.MediaTypeContainerd1CheckpointConfig:
78-
data, err := content.ReadBlob(ctx, store, m)
79-
if err != nil {
80-
return errors.Wrap(err, "unable to read checkpoint config")
81-
}
82-
var any protobuf.Any
83-
if err := proto.Unmarshal(data, &any); err != nil {
84-
return err
85-
}
86-
c.Spec = &any
87-
}
88-
}
89-
if rw != nil {
90-
// apply the rw snapshot to the new rw layer
91-
mounts, err := client.SnapshotService(c.Snapshotter).Mounts(ctx, snapshotKey)
92-
if err != nil {
93-
return errors.Wrapf(err, "unable to get mounts for %s", snapshotKey)
94-
}
95-
if _, err := client.DiffService().Apply(ctx, *rw, mounts); err != nil {
96-
return errors.Wrap(err, "unable to apply rw diff")
97-
}
98-
}
99-
c.SnapshotKey = snapshotKey
100-
return nil
101-
}
102-
}
103-
10435
// WithRemappedSnapshot creates a new snapshot and remaps the uid/gid for the
10536
// filesystem to be used by a container with user namespaces
10637
func WithRemappedSnapshot(id string, i Image, uid, gid uint32) NewContainerOpts {

container_restore_opts.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ func WithRestoreSnapshot(ctx context.Context, id string, client *Client, checkpo
138138
}
139139
}
140140

141-
// WithRestoreSnapshot restores the snapshot from the checkpoint for the container
141+
// WithRestoreRW restores the rw layer from the checkpoint for the container
142142
func WithRestoreRW(ctx context.Context, id string, client *Client, checkpoint Image, index *imagespec.Index) NewContainerOpts {
143143
return func(ctx context.Context, client *Client, c *containers.Container) error {
144144
// apply rw layer

0 commit comments

Comments
 (0)