forked from containerd/containerd
-
Notifications
You must be signed in to change notification settings - Fork 0
/
container_opts.go
129 lines (117 loc) · 3.9 KB
/
container_opts.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
package containerd
import (
"context"
"github.com/containerd/containerd/containers"
"github.com/containerd/containerd/errdefs"
"github.com/containerd/containerd/typeurl"
"github.com/gogo/protobuf/types"
"github.com/opencontainers/image-spec/identity"
"github.com/pkg/errors"
)
// NewContainerOpts allows the caller to set additional options when creating a container
type NewContainerOpts func(ctx context.Context, client *Client, c *containers.Container) error
// WithRuntime allows a user to specify the runtime name and additional options that should
// be used to create tasks for the container
func WithRuntime(name string, options interface{}) NewContainerOpts {
return func(ctx context.Context, client *Client, c *containers.Container) error {
var (
any *types.Any
err error
)
if options != nil {
any, err = typeurl.MarshalAny(options)
if err != nil {
return err
}
}
c.Runtime = containers.RuntimeInfo{
Name: name,
Options: any,
}
return nil
}
}
// WithImage sets the provided image as the base for the container
func WithImage(i Image) NewContainerOpts {
return func(ctx context.Context, client *Client, c *containers.Container) error {
c.Image = i.Name()
return nil
}
}
// WithContainerLabels adds the provided labels to the container
func WithContainerLabels(labels map[string]string) NewContainerOpts {
return func(_ context.Context, _ *Client, c *containers.Container) error {
c.Labels = labels
return nil
}
}
// WithSnapshotter sets the provided snapshotter for use by the container
//
// This option must appear before other snapshotter options to have an effect.
func WithSnapshotter(name string) NewContainerOpts {
return func(ctx context.Context, client *Client, c *containers.Container) error {
c.Snapshotter = name
return nil
}
}
// WithSnapshot uses an existing root filesystem for the container
func WithSnapshot(id string) NewContainerOpts {
return func(ctx context.Context, client *Client, c *containers.Container) error {
setSnapshotterIfEmpty(c)
// check that the snapshot exists, if not, fail on creation
if _, err := client.SnapshotService(c.Snapshotter).Mounts(ctx, id); err != nil {
return err
}
c.SnapshotKey = id
return nil
}
}
// WithNewSnapshot allocates a new snapshot to be used by the container as the
// root filesystem in read-write mode
func WithNewSnapshot(id string, i Image) NewContainerOpts {
return func(ctx context.Context, client *Client, c *containers.Container) error {
diffIDs, err := i.(*image).i.RootFS(ctx, client.ContentStore())
if err != nil {
return err
}
setSnapshotterIfEmpty(c)
if _, err := client.SnapshotService(c.Snapshotter).Prepare(ctx, id, identity.ChainID(diffIDs).String()); err != nil {
return err
}
c.SnapshotKey = id
c.Image = i.Name()
return nil
}
}
// WithSnapshotCleanup deletes the rootfs snapshot allocated for the container
func WithSnapshotCleanup(ctx context.Context, client *Client, c containers.Container) error {
if c.SnapshotKey != "" {
if c.Snapshotter == "" {
return errors.Wrapf(errdefs.ErrInvalidArgument, "container.Snapshotter must be set to cleanup rootfs snapshot")
}
return client.SnapshotService(c.Snapshotter).Remove(ctx, c.SnapshotKey)
}
return nil
}
// WithNewSnapshotView allocates a new snapshot to be used by the container as the
// root filesystem in read-only mode
func WithNewSnapshotView(id string, i Image) NewContainerOpts {
return func(ctx context.Context, client *Client, c *containers.Container) error {
diffIDs, err := i.(*image).i.RootFS(ctx, client.ContentStore())
if err != nil {
return err
}
setSnapshotterIfEmpty(c)
if _, err := client.SnapshotService(c.Snapshotter).View(ctx, id, identity.ChainID(diffIDs).String()); err != nil {
return err
}
c.SnapshotKey = id
c.Image = i.Name()
return nil
}
}
func setSnapshotterIfEmpty(c *containers.Container) {
if c.Snapshotter == "" {
c.Snapshotter = DefaultSnapshotter
}
}