Update containerd to a6ce1ef2a1
Signed-off-by: Lantao Liu <lantaol@google.com>
This commit is contained in:
27
vendor/github.com/containerd/containerd/README.md
generated
vendored
27
vendor/github.com/containerd/containerd/README.md
generated
vendored
@@ -60,25 +60,25 @@ image, err := client.Pull(context, "docker.io/library/redis:latest")
|
||||
err := client.Push(context, "docker.io/library/redis:latest", image.Target())
|
||||
```
|
||||
|
||||
### OCI Runtime Specification
|
||||
|
||||
containerd fully supports the OCI runtime specification for running containers. We have built in functions to help you generate runtime specifications based on images as well as custom parameters.
|
||||
|
||||
```go
|
||||
spec, err := containerd.GenerateSpec(containerd.WithImageConfig(context, image))
|
||||
```
|
||||
|
||||
### Containers
|
||||
|
||||
In containerd, a container is a metadata object. Resources such as an OCI runtime specification, image, root filesystem, and other metadata can be attached to a container.
|
||||
|
||||
```go
|
||||
redis, err := client.NewContainer(context, "redis-master",
|
||||
containerd.WithSpec(spec),
|
||||
)
|
||||
redis, err := client.NewContainer(context, "redis-master")
|
||||
defer redis.Delete(context)
|
||||
```
|
||||
|
||||
### OCI Runtime Specification
|
||||
|
||||
containerd fully supports the OCI runtime specification for running containers. We have built in functions to help you generate runtime specifications based on images as well as custom parameters.
|
||||
|
||||
You can specify options when creating a container about how to modify the specification.
|
||||
|
||||
```go
|
||||
redis, err := client.NewContainer(context, "redis-master", containerd.WithNewSpec(containerd.WithImageConfig(image)))
|
||||
```
|
||||
|
||||
## Root Filesystems
|
||||
|
||||
containerd allows you to use overlay or snapshot filesystems with your containers. It comes with builtin support for overlayfs and btrfs.
|
||||
@@ -89,16 +89,17 @@ image, err := client.Pull(context, "docker.io/library/redis:latest", containerd.
|
||||
|
||||
// allocate a new RW root filesystem for a container based on the image
|
||||
redis, err := client.NewContainer(context, "redis-master",
|
||||
containerd.WithSpec(spec),
|
||||
containerd.WithNewSnapshot("redis-rootfs", image),
|
||||
containerd.WithNewSpec(containerd.WithImageConfig(image)),
|
||||
|
||||
)
|
||||
|
||||
// use a readonly filesystem with multiple containers
|
||||
for i := 0; i < 10; i++ {
|
||||
id := fmt.Sprintf("id-%s", i)
|
||||
container, err := client.NewContainer(ctx, id,
|
||||
containerd.WithSpec(spec),
|
||||
containerd.WithNewSnapshotView(id, image),
|
||||
containerd.WithNewSpec(containerd.WithImageConfig(image)),
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
9
vendor/github.com/containerd/containerd/apparmor.go
generated
vendored
9
vendor/github.com/containerd/containerd/apparmor.go
generated
vendored
@@ -2,11 +2,16 @@
|
||||
|
||||
package containerd
|
||||
|
||||
import specs "github.com/opencontainers/runtime-spec/specs-go"
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/containerd/containerd/containers"
|
||||
specs "github.com/opencontainers/runtime-spec/specs-go"
|
||||
)
|
||||
|
||||
// WithApparmor sets the provided apparmor profile to the spec
|
||||
func WithApparmorProfile(profile string) SpecOpts {
|
||||
return func(s *specs.Spec) error {
|
||||
return func(_ context.Context, _ *Client, _ *containers.Container, s *specs.Spec) error {
|
||||
s.Process.ApparmorProfile = profile
|
||||
return nil
|
||||
}
|
||||
|
||||
11
vendor/github.com/containerd/containerd/spec.go
generated
vendored
11
vendor/github.com/containerd/containerd/spec.go
generated
vendored
@@ -1,16 +1,21 @@
|
||||
package containerd
|
||||
|
||||
import specs "github.com/opencontainers/runtime-spec/specs-go"
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/containerd/containerd/containers"
|
||||
specs "github.com/opencontainers/runtime-spec/specs-go"
|
||||
)
|
||||
|
||||
// GenerateSpec will generate a default spec from the provided image
|
||||
// for use as a containerd container
|
||||
func GenerateSpec(opts ...SpecOpts) (*specs.Spec, error) {
|
||||
func GenerateSpec(ctx context.Context, client *Client, c *containers.Container, opts ...SpecOpts) (*specs.Spec, error) {
|
||||
s, err := createDefaultSpec()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, o := range opts {
|
||||
if err := o(s); err != nil {
|
||||
if err := o(ctx, client, c, s); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
52
vendor/github.com/containerd/containerd/spec_opts.go
generated
vendored
52
vendor/github.com/containerd/containerd/spec_opts.go
generated
vendored
@@ -1,13 +1,19 @@
|
||||
package containerd
|
||||
|
||||
import specs "github.com/opencontainers/runtime-spec/specs-go"
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/containerd/containerd/containers"
|
||||
"github.com/containerd/containerd/typeurl"
|
||||
specs "github.com/opencontainers/runtime-spec/specs-go"
|
||||
)
|
||||
|
||||
// SpecOpts sets spec specific information to a newly generated OCI spec
|
||||
type SpecOpts func(s *specs.Spec) error
|
||||
type SpecOpts func(context.Context, *Client, *containers.Container, *specs.Spec) error
|
||||
|
||||
// WithProcessArgs replaces the args on the generated spec
|
||||
func WithProcessArgs(args ...string) SpecOpts {
|
||||
return func(s *specs.Spec) error {
|
||||
return func(_ context.Context, _ *Client, _ *containers.Container, s *specs.Spec) error {
|
||||
s.Process.Args = args
|
||||
return nil
|
||||
}
|
||||
@@ -15,8 +21,46 @@ func WithProcessArgs(args ...string) SpecOpts {
|
||||
|
||||
// WithHostname sets the container's hostname
|
||||
func WithHostname(name string) SpecOpts {
|
||||
return func(s *specs.Spec) error {
|
||||
return func(_ context.Context, _ *Client, _ *containers.Container, s *specs.Spec) error {
|
||||
s.Hostname = name
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithNewSpec generates a new spec for a new container
|
||||
func WithNewSpec(opts ...SpecOpts) NewContainerOpts {
|
||||
return func(ctx context.Context, client *Client, c *containers.Container) error {
|
||||
s, err := createDefaultSpec()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, o := range opts {
|
||||
if err := o(ctx, client, c, s); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
any, err := typeurl.MarshalAny(s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c.Spec = any
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithSpec sets the provided spec on the container
|
||||
func WithSpec(s *specs.Spec, opts ...SpecOpts) NewContainerOpts {
|
||||
return func(ctx context.Context, client *Client, c *containers.Container) error {
|
||||
for _, o := range opts {
|
||||
if err := o(ctx, client, c, s); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
any, err := typeurl.MarshalAny(s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c.Spec = any
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
111
vendor/github.com/containerd/containerd/spec_opts_unix.go
generated
vendored
111
vendor/github.com/containerd/containerd/spec_opts_unix.go
generated
vendored
@@ -6,23 +6,28 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
|
||||
"github.com/containerd/containerd/containers"
|
||||
"github.com/containerd/containerd/content"
|
||||
"github.com/containerd/containerd/images"
|
||||
"github.com/containerd/containerd/namespaces"
|
||||
"github.com/containerd/containerd/typeurl"
|
||||
"github.com/opencontainers/image-spec/identity"
|
||||
"github.com/opencontainers/image-spec/specs-go/v1"
|
||||
"github.com/opencontainers/runc/libcontainer/user"
|
||||
specs "github.com/opencontainers/runtime-spec/specs-go"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// WithTTY sets the information on the spec as well as the environment variables for
|
||||
// using a TTY
|
||||
func WithTTY(s *specs.Spec) error {
|
||||
func WithTTY(_ context.Context, _ *Client, _ *containers.Container, s *specs.Spec) error {
|
||||
s.Process.Terminal = true
|
||||
s.Process.Env = append(s.Process.Env, "TERM=xterm")
|
||||
return nil
|
||||
@@ -30,7 +35,7 @@ func WithTTY(s *specs.Spec) error {
|
||||
|
||||
// WithHostNamespace allows a task to run inside the host's linux namespace
|
||||
func WithHostNamespace(ns specs.LinuxNamespaceType) SpecOpts {
|
||||
return func(s *specs.Spec) error {
|
||||
return func(_ context.Context, _ *Client, _ *containers.Container, s *specs.Spec) error {
|
||||
for i, n := range s.Linux.Namespaces {
|
||||
if n.Type == ns {
|
||||
s.Linux.Namespaces = append(s.Linux.Namespaces[:i], s.Linux.Namespaces[i+1:]...)
|
||||
@@ -44,7 +49,7 @@ func WithHostNamespace(ns specs.LinuxNamespaceType) SpecOpts {
|
||||
// WithLinuxNamespace uses the passed in namespace for the spec. If a namespace of the same type already exists in the
|
||||
// spec, the existing namespace is replaced by the one provided.
|
||||
func WithLinuxNamespace(ns specs.LinuxNamespace) SpecOpts {
|
||||
return func(s *specs.Spec) error {
|
||||
return func(_ context.Context, _ *Client, _ *containers.Container, s *specs.Spec) error {
|
||||
for i, n := range s.Linux.Namespaces {
|
||||
if n.Type == ns.Type {
|
||||
before := s.Linux.Namespaces[:i]
|
||||
@@ -60,11 +65,11 @@ func WithLinuxNamespace(ns specs.LinuxNamespace) SpecOpts {
|
||||
}
|
||||
|
||||
// WithImageConfig configures the spec to from the configuration of an Image
|
||||
func WithImageConfig(ctx context.Context, i Image) SpecOpts {
|
||||
return func(s *specs.Spec) error {
|
||||
func WithImageConfig(i Image) SpecOpts {
|
||||
return func(ctx context.Context, client *Client, c *containers.Container, s *specs.Spec) error {
|
||||
var (
|
||||
image = i.(*image)
|
||||
store = image.client.ContentStore()
|
||||
store = client.ContentStore()
|
||||
)
|
||||
ic, err := image.i.Config(ctx, store)
|
||||
if err != nil {
|
||||
@@ -100,6 +105,10 @@ func WithImageConfig(ctx context.Context, i Image) SpecOpts {
|
||||
case 1:
|
||||
v, err := strconv.ParseUint(parts[0], 0, 10)
|
||||
if err != nil {
|
||||
// if we cannot parse as a uint they try to see if it is a username
|
||||
if err := WithUsername(config.User)(ctx, client, c, s); err != nil {
|
||||
return err
|
||||
}
|
||||
return err
|
||||
}
|
||||
uid, gid = uint32(v), uint32(v)
|
||||
@@ -129,7 +138,7 @@ func WithImageConfig(ctx context.Context, i Image) SpecOpts {
|
||||
|
||||
// WithRootFSPath specifies unmanaged rootfs path.
|
||||
func WithRootFSPath(path string, readonly bool) SpecOpts {
|
||||
return func(s *specs.Spec) error {
|
||||
return func(_ context.Context, _ *Client, _ *containers.Container, s *specs.Spec) error {
|
||||
s.Root = &specs.Root{
|
||||
Path: path,
|
||||
Readonly: readonly,
|
||||
@@ -139,18 +148,6 @@ func WithRootFSPath(path string, readonly bool) SpecOpts {
|
||||
}
|
||||
}
|
||||
|
||||
// WithSpec sets the provided spec for a new container
|
||||
func WithSpec(spec *specs.Spec) NewContainerOpts {
|
||||
return func(ctx context.Context, client *Client, c *containers.Container) error {
|
||||
any, err := typeurl.MarshalAny(spec)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c.Spec = any
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithResources sets the provided resources on the spec for task updates
|
||||
func WithResources(resources *specs.LinuxResources) UpdateTaskOpts {
|
||||
return func(ctx context.Context, client *Client, r *UpdateTaskInfo) error {
|
||||
@@ -160,13 +157,13 @@ func WithResources(resources *specs.LinuxResources) UpdateTaskOpts {
|
||||
}
|
||||
|
||||
// WithNoNewPrivileges sets no_new_privileges on the process for the container
|
||||
func WithNoNewPrivileges(s *specs.Spec) error {
|
||||
func WithNoNewPrivileges(_ context.Context, _ *Client, _ *containers.Container, s *specs.Spec) error {
|
||||
s.Process.NoNewPrivileges = true
|
||||
return nil
|
||||
}
|
||||
|
||||
// WithHostHostsFile bind-mounts the host's /etc/hosts into the container as readonly
|
||||
func WithHostHostsFile(s *specs.Spec) error {
|
||||
func WithHostHostsFile(_ context.Context, _ *Client, _ *containers.Container, s *specs.Spec) error {
|
||||
s.Mounts = append(s.Mounts, specs.Mount{
|
||||
Destination: "/etc/hosts",
|
||||
Type: "bind",
|
||||
@@ -177,7 +174,7 @@ func WithHostHostsFile(s *specs.Spec) error {
|
||||
}
|
||||
|
||||
// WithHostResolvconf bind-mounts the host's /etc/resolv.conf into the container as readonly
|
||||
func WithHostResolvconf(s *specs.Spec) error {
|
||||
func WithHostResolvconf(_ context.Context, _ *Client, _ *containers.Container, s *specs.Spec) error {
|
||||
s.Mounts = append(s.Mounts, specs.Mount{
|
||||
Destination: "/etc/resolv.conf",
|
||||
Type: "bind",
|
||||
@@ -188,7 +185,7 @@ func WithHostResolvconf(s *specs.Spec) error {
|
||||
}
|
||||
|
||||
// WithHostLocaltime bind-mounts the host's /etc/localtime into the container as readonly
|
||||
func WithHostLocaltime(s *specs.Spec) error {
|
||||
func WithHostLocaltime(_ context.Context, _ *Client, _ *containers.Container, s *specs.Spec) error {
|
||||
s.Mounts = append(s.Mounts, specs.Mount{
|
||||
Destination: "/etc/localtime",
|
||||
Type: "bind",
|
||||
@@ -201,7 +198,7 @@ func WithHostLocaltime(s *specs.Spec) error {
|
||||
// WithUserNamespace sets the uid and gid mappings for the task
|
||||
// this can be called multiple times to add more mappings to the generated spec
|
||||
func WithUserNamespace(container, host, size uint32) SpecOpts {
|
||||
return func(s *specs.Spec) error {
|
||||
return func(_ context.Context, _ *Client, _ *containers.Container, s *specs.Spec) error {
|
||||
var hasUserns bool
|
||||
for _, ns := range s.Linux.Namespaces {
|
||||
if ns.Type == specs.UserNamespace {
|
||||
@@ -271,7 +268,7 @@ func WithRemappedSnapshot(id string, i Image, uid, gid uint32) NewContainerOpts
|
||||
|
||||
// WithCgroup sets the container's cgroup path
|
||||
func WithCgroup(path string) SpecOpts {
|
||||
return func(s *specs.Spec) error {
|
||||
return func(_ context.Context, _ *Client, _ *containers.Container, s *specs.Spec) error {
|
||||
s.Linux.CgroupsPath = path
|
||||
return nil
|
||||
}
|
||||
@@ -279,13 +276,69 @@ func WithCgroup(path string) SpecOpts {
|
||||
|
||||
// WithNamespacedCgroup uses the namespace set on the context to create a
|
||||
// root directory for containers in the cgroup with the id as the subcgroup
|
||||
func WithNamespacedCgroup(ctx context.Context, id string) SpecOpts {
|
||||
return func(s *specs.Spec) error {
|
||||
func WithNamespacedCgroup() SpecOpts {
|
||||
return func(ctx context.Context, _ *Client, c *containers.Container, s *specs.Spec) error {
|
||||
namespace, err := namespaces.NamespaceRequired(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
s.Linux.CgroupsPath = filepath.Join("/", namespace, id)
|
||||
s.Linux.CgroupsPath = filepath.Join("/", namespace, c.ID)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithUserIDs allows the UID and GID for the Process to be set
|
||||
func WithUserIDs(uid, gid uint32) SpecOpts {
|
||||
return func(_ context.Context, _ *Client, _ *containers.Container, s *specs.Spec) error {
|
||||
s.Process.User.UID = uid
|
||||
s.Process.User.GID = gid
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithUsername sets the correct UID and GID for the container
|
||||
// based on the the image's /etc/passwd contents.
|
||||
// id is the snapshot id that is used
|
||||
func WithUsername(username string) SpecOpts {
|
||||
return func(ctx context.Context, client *Client, c *containers.Container, s *specs.Spec) error {
|
||||
if c.Snapshotter == "" {
|
||||
return errors.Errorf("no snapshotter set for container")
|
||||
}
|
||||
if c.RootFS == "" {
|
||||
return errors.Errorf("rootfs not created for container")
|
||||
}
|
||||
snapshotter := client.SnapshotService(c.Snapshotter)
|
||||
mounts, err := snapshotter.Mounts(ctx, c.RootFS)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
root, err := ioutil.TempDir("", "ctd-username")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer os.RemoveAll(root)
|
||||
for _, m := range mounts {
|
||||
if err := m.Mount(root); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
defer unix.Unmount(root, 0)
|
||||
f, err := os.Open(filepath.Join(root, "/etc/passwd"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
users, err := user.ParsePasswdFilter(f, func(u user.User) bool {
|
||||
return u.Name == username
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(users) == 0 {
|
||||
return errors.Errorf("no users found for %s", username)
|
||||
}
|
||||
u := users[0]
|
||||
s.Process.User.UID, s.Process.User.GID = uint32(u.Uid), uint32(u.Gid)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
20
vendor/github.com/containerd/containerd/spec_opts_windows.go
generated
vendored
20
vendor/github.com/containerd/containerd/spec_opts_windows.go
generated
vendored
@@ -10,16 +10,15 @@ import (
|
||||
"github.com/containerd/containerd/containers"
|
||||
"github.com/containerd/containerd/content"
|
||||
"github.com/containerd/containerd/images"
|
||||
"github.com/containerd/containerd/typeurl"
|
||||
"github.com/opencontainers/image-spec/specs-go/v1"
|
||||
specs "github.com/opencontainers/runtime-spec/specs-go"
|
||||
)
|
||||
|
||||
func WithImageConfig(ctx context.Context, i Image) SpecOpts {
|
||||
return func(s *specs.Spec) error {
|
||||
func WithImageConfig(i Image) SpecOpts {
|
||||
return func(ctx context.Context, client *Client, _ *containers.Container, s *specs.Spec) error {
|
||||
var (
|
||||
image = i.(*image)
|
||||
store = image.client.ContentStore()
|
||||
store = client.ContentStore()
|
||||
)
|
||||
ic, err := image.i.Config(ctx, store)
|
||||
if err != nil {
|
||||
@@ -52,7 +51,7 @@ func WithImageConfig(ctx context.Context, i Image) SpecOpts {
|
||||
}
|
||||
|
||||
func WithTTY(width, height int) SpecOpts {
|
||||
return func(s *specs.Spec) error {
|
||||
return func(_ context.Context, _ *Client, _ *containers.Container, s *specs.Spec) error {
|
||||
s.Process.Terminal = true
|
||||
s.Process.ConsoleSize.Width = uint(width)
|
||||
s.Process.ConsoleSize.Height = uint(height)
|
||||
@@ -60,17 +59,6 @@ func WithTTY(width, height int) SpecOpts {
|
||||
}
|
||||
}
|
||||
|
||||
func WithSpec(spec *specs.Spec) NewContainerOpts {
|
||||
return func(ctx context.Context, client *Client, c *containers.Container) error {
|
||||
any, err := typeurl.MarshalAny(spec)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c.Spec = any
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func WithResources(resources *specs.WindowsResources) UpdateTaskOpts {
|
||||
return func(ctx context.Context, client *Client, r *UpdateTaskInfo) error {
|
||||
r.Resources = resources
|
||||
|
||||
Reference in New Issue
Block a user