Use container'd oci opts for spec generation
This bumps the containerd and sys packages in CRI Signed-off-by: Michael Crosby <crosbymichael@gmail.com> Remove runtime-tools Signed-off-by: Michael Crosby <crosbymichael@gmail.com> Update tests for oci opts package Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
This commit is contained in:
parent
eb27e526f5
commit
5eddc1a2cc
@ -18,16 +18,41 @@ package opts
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"sort"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/containerd/containerd/containers"
|
"github.com/containerd/containerd/containers"
|
||||||
|
"github.com/containerd/containerd/mount"
|
||||||
"github.com/containerd/containerd/oci"
|
"github.com/containerd/containerd/oci"
|
||||||
|
osinterface "github.com/containerd/cri/pkg/os"
|
||||||
|
"github.com/containerd/cri/pkg/util"
|
||||||
|
imagespec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||||
|
"github.com/opencontainers/runc/libcontainer/devices"
|
||||||
runtimespec "github.com/opencontainers/runtime-spec/specs-go"
|
runtimespec "github.com/opencontainers/runtime-spec/specs-go"
|
||||||
|
"github.com/opencontainers/selinux/go-selinux/label"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
|
"golang.org/x/sys/unix"
|
||||||
|
runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// DefaultSandboxCPUshares is default cpu shares for sandbox container.
|
||||||
|
DefaultSandboxCPUshares = 2
|
||||||
)
|
)
|
||||||
|
|
||||||
// WithAdditionalGIDs adds any additional groups listed for a particular user in the
|
// WithAdditionalGIDs adds any additional groups listed for a particular user in the
|
||||||
// /etc/groups file of the image's root filesystem to the OCI spec's additionalGids array.
|
// /etc/groups file of the image's root filesystem to the OCI spec's additionalGids array.
|
||||||
func WithAdditionalGIDs(userstr string) oci.SpecOpts {
|
func WithAdditionalGIDs(userstr string) oci.SpecOpts {
|
||||||
return func(ctx context.Context, client oci.Client, c *containers.Container, s *runtimespec.Spec) (err error) {
|
return func(ctx context.Context, client oci.Client, c *containers.Container, s *runtimespec.Spec) (err error) {
|
||||||
|
if s.Process == nil {
|
||||||
|
s.Process = &runtimespec.Process{}
|
||||||
|
}
|
||||||
gids := s.Process.User.AdditionalGids
|
gids := s.Process.User.AdditionalGids
|
||||||
if err := oci.WithAdditionalGIDs(userstr)(ctx, client, c, s); err != nil {
|
if err := oci.WithAdditionalGIDs(userstr)(ctx, client, c, s); err != nil {
|
||||||
return err
|
return err
|
||||||
@ -49,3 +74,665 @@ func mergeGids(gids1, gids2 []uint32) []uint32 {
|
|||||||
}
|
}
|
||||||
return append(gids1, gids2...)
|
return append(gids1, gids2...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithoutRunMount removes the `/run` inside the spec
|
||||||
|
func WithoutRunMount(_ context.Context, _ oci.Client, c *containers.Container, s *runtimespec.Spec) error {
|
||||||
|
var (
|
||||||
|
mounts []runtimespec.Mount
|
||||||
|
currnet = s.Mounts
|
||||||
|
)
|
||||||
|
for _, m := range currnet {
|
||||||
|
if filepath.Clean(m.Destination) == "/run" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
mounts = append(mounts, m)
|
||||||
|
}
|
||||||
|
s.Mounts = mounts
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithoutDefaultSecuritySettings removes the default security settings generated on a spec
|
||||||
|
func WithoutDefaultSecuritySettings(_ context.Context, _ oci.Client, c *containers.Container, s *runtimespec.Spec) error {
|
||||||
|
if s.Process == nil {
|
||||||
|
s.Process = &runtimespec.Process{}
|
||||||
|
}
|
||||||
|
// Make sure no default seccomp/apparmor is specified
|
||||||
|
s.Process.ApparmorProfile = ""
|
||||||
|
if s.Linux != nil {
|
||||||
|
s.Linux.Seccomp = nil
|
||||||
|
}
|
||||||
|
// Remove default rlimits (See issue #515)
|
||||||
|
s.Process.Rlimits = nil
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithRelativeRoot sets the root for the container
|
||||||
|
func WithRelativeRoot(root string) oci.SpecOpts {
|
||||||
|
return func(ctx context.Context, client oci.Client, c *containers.Container, s *runtimespec.Spec) (err error) {
|
||||||
|
if s.Root == nil {
|
||||||
|
s.Root = &runtimespec.Root{}
|
||||||
|
}
|
||||||
|
s.Root.Path = root
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithProcessArgs sets the process args on the spec based on the image and runtime config
|
||||||
|
func WithProcessArgs(config *runtime.ContainerConfig, image *imagespec.ImageConfig) oci.SpecOpts {
|
||||||
|
return func(ctx context.Context, client oci.Client, c *containers.Container, s *runtimespec.Spec) (err error) {
|
||||||
|
command, args := config.GetCommand(), config.GetArgs()
|
||||||
|
// The following logic is migrated from https://github.com/moby/moby/blob/master/daemon/commit.go
|
||||||
|
// TODO(random-liu): Clearly define the commands overwrite behavior.
|
||||||
|
if len(command) == 0 {
|
||||||
|
// Copy array to avoid data race.
|
||||||
|
if len(args) == 0 {
|
||||||
|
args = append([]string{}, image.Cmd...)
|
||||||
|
}
|
||||||
|
if command == nil {
|
||||||
|
command = append([]string{}, image.Entrypoint...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(command) == 0 && len(args) == 0 {
|
||||||
|
return errors.New("no command specified")
|
||||||
|
}
|
||||||
|
return oci.WithProcessArgs(append(command, args...)...)(ctx, client, c, s)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithMounts sorts and adds runtime and CRI mounts to the spec
|
||||||
|
func WithMounts(osi osinterface.OS, config *runtime.ContainerConfig, extra []*runtime.Mount, mountLabel string) oci.SpecOpts {
|
||||||
|
return func(ctx context.Context, client oci.Client, _ *containers.Container, s *runtimespec.Spec) (err error) {
|
||||||
|
// mergeMounts merge CRI mounts with extra mounts. If a mount destination
|
||||||
|
// is mounted by both a CRI mount and an extra mount, the CRI mount will
|
||||||
|
// be kept.
|
||||||
|
var (
|
||||||
|
criMounts = config.GetMounts()
|
||||||
|
mounts = append([]*runtime.Mount{}, criMounts...)
|
||||||
|
)
|
||||||
|
// Copy all mounts from extra mounts, except for mounts overriden by CRI.
|
||||||
|
for _, e := range extra {
|
||||||
|
found := false
|
||||||
|
for _, c := range criMounts {
|
||||||
|
if filepath.Clean(e.ContainerPath) == filepath.Clean(c.ContainerPath) {
|
||||||
|
found = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !found {
|
||||||
|
mounts = append(mounts, e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ---
|
||||||
|
|
||||||
|
// Sort mounts in number of parts. This ensures that high level mounts don't
|
||||||
|
// shadow other mounts.
|
||||||
|
sort.Sort(orderedMounts(mounts))
|
||||||
|
|
||||||
|
// Mount cgroup into the container as readonly, which inherits docker's behavior.
|
||||||
|
s.Mounts = append(s.Mounts, runtimespec.Mount{
|
||||||
|
Source: "cgroup",
|
||||||
|
Destination: "/sys/fs/cgroup",
|
||||||
|
Type: "cgroup",
|
||||||
|
Options: []string{"nosuid", "noexec", "nodev", "relatime", "ro"},
|
||||||
|
})
|
||||||
|
|
||||||
|
// Copy all mounts from default mounts, except for
|
||||||
|
// - mounts overriden by supplied mount;
|
||||||
|
// - all mounts under /dev if a supplied /dev is present.
|
||||||
|
mountSet := make(map[string]struct{})
|
||||||
|
for _, m := range mounts {
|
||||||
|
mountSet[filepath.Clean(m.ContainerPath)] = struct{}{}
|
||||||
|
}
|
||||||
|
|
||||||
|
defaultMounts := s.Mounts
|
||||||
|
s.Mounts = nil
|
||||||
|
|
||||||
|
for _, m := range defaultMounts {
|
||||||
|
dst := filepath.Clean(m.Destination)
|
||||||
|
if _, ok := mountSet[dst]; ok {
|
||||||
|
// filter out mount overridden by a supplied mount
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if _, mountDev := mountSet["/dev"]; mountDev && strings.HasPrefix(dst, "/dev/") {
|
||||||
|
// filter out everything under /dev if /dev is a supplied mount
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
s.Mounts = append(s.Mounts, m)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, mount := range mounts {
|
||||||
|
var (
|
||||||
|
dst = mount.GetContainerPath()
|
||||||
|
src = mount.GetHostPath()
|
||||||
|
)
|
||||||
|
// Create the host path if it doesn't exist.
|
||||||
|
// TODO(random-liu): Add CRI validation test for this case.
|
||||||
|
if _, err := osi.Stat(src); err != nil {
|
||||||
|
if !os.IsNotExist(err) {
|
||||||
|
return errors.Wrapf(err, "failed to stat %q", src)
|
||||||
|
}
|
||||||
|
if err := osi.MkdirAll(src, 0755); err != nil {
|
||||||
|
return errors.Wrapf(err, "failed to mkdir %q", src)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// TODO(random-liu): Add cri-containerd integration test or cri validation test
|
||||||
|
// for this.
|
||||||
|
src, err := osi.ResolveSymbolicLink(src)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrapf(err, "failed to resolve symlink %q", src)
|
||||||
|
}
|
||||||
|
if s.Linux == nil {
|
||||||
|
s.Linux = &runtimespec.Linux{}
|
||||||
|
}
|
||||||
|
options := []string{"rbind"}
|
||||||
|
switch mount.GetPropagation() {
|
||||||
|
case runtime.MountPropagation_PROPAGATION_PRIVATE:
|
||||||
|
options = append(options, "rprivate")
|
||||||
|
// Since default root propogation in runc is rprivate ignore
|
||||||
|
// setting the root propagation
|
||||||
|
case runtime.MountPropagation_PROPAGATION_BIDIRECTIONAL:
|
||||||
|
if err := ensureShared(src, osi.LookupMount); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
options = append(options, "rshared")
|
||||||
|
s.Linux.RootfsPropagation = "rshared"
|
||||||
|
case runtime.MountPropagation_PROPAGATION_HOST_TO_CONTAINER:
|
||||||
|
if err := ensureSharedOrSlave(src, osi.LookupMount); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
options = append(options, "rslave")
|
||||||
|
if s.Linux.RootfsPropagation != "rshared" &&
|
||||||
|
s.Linux.RootfsPropagation != "rslave" {
|
||||||
|
s.Linux.RootfsPropagation = "rslave"
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
logrus.Warnf("Unknown propagation mode for hostPath %q", mount.HostPath)
|
||||||
|
options = append(options, "rprivate")
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE(random-liu): we don't change all mounts to `ro` when root filesystem
|
||||||
|
// is readonly. This is different from docker's behavior, but make more sense.
|
||||||
|
if mount.GetReadonly() {
|
||||||
|
options = append(options, "ro")
|
||||||
|
} else {
|
||||||
|
options = append(options, "rw")
|
||||||
|
}
|
||||||
|
|
||||||
|
if mount.GetSelinuxRelabel() {
|
||||||
|
if err := label.Relabel(src, mountLabel, true); err != nil && err != unix.ENOTSUP {
|
||||||
|
return errors.Wrapf(err, "relabel %q with %q failed", src, mountLabel)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s.Mounts = append(s.Mounts, runtimespec.Mount{
|
||||||
|
Source: src,
|
||||||
|
Destination: dst,
|
||||||
|
Type: "bind",
|
||||||
|
Options: options,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// mounts defines how to sort runtime.Mount.
|
||||||
|
// This is the same with the Docker implementation:
|
||||||
|
// https://github.com/moby/moby/blob/17.05.x/daemon/volumes.go#L26
|
||||||
|
type orderedMounts []*runtime.Mount
|
||||||
|
|
||||||
|
// Len returns the number of mounts. Used in sorting.
|
||||||
|
func (m orderedMounts) Len() int {
|
||||||
|
return len(m)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Less returns true if the number of parts (a/b/c would be 3 parts) in the
|
||||||
|
// mount indexed by parameter 1 is less than that of the mount indexed by
|
||||||
|
// parameter 2. Used in sorting.
|
||||||
|
func (m orderedMounts) Less(i, j int) bool {
|
||||||
|
return m.parts(i) < m.parts(j)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Swap swaps two items in an array of mounts. Used in sorting
|
||||||
|
func (m orderedMounts) Swap(i, j int) {
|
||||||
|
m[i], m[j] = m[j], m[i]
|
||||||
|
}
|
||||||
|
|
||||||
|
// parts returns the number of parts in the destination of a mount. Used in sorting.
|
||||||
|
func (m orderedMounts) parts(i int) int {
|
||||||
|
return strings.Count(filepath.Clean(m[i].ContainerPath), string(os.PathSeparator))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure mount point on which path is mounted, is shared.
|
||||||
|
func ensureShared(path string, lookupMount func(string) (mount.Info, error)) error {
|
||||||
|
mountInfo, err := lookupMount(path)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure source mount point is shared.
|
||||||
|
optsSplit := strings.Split(mountInfo.Optional, " ")
|
||||||
|
for _, opt := range optsSplit {
|
||||||
|
if strings.HasPrefix(opt, "shared:") {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return errors.Errorf("path %q is mounted on %q but it is not a shared mount", path, mountInfo.Mountpoint)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ensure mount point on which path is mounted, is either shared or slave.
|
||||||
|
func ensureSharedOrSlave(path string, lookupMount func(string) (mount.Info, error)) error {
|
||||||
|
mountInfo, err := lookupMount(path)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// Make sure source mount point is shared.
|
||||||
|
optsSplit := strings.Split(mountInfo.Optional, " ")
|
||||||
|
for _, opt := range optsSplit {
|
||||||
|
if strings.HasPrefix(opt, "shared:") {
|
||||||
|
return nil
|
||||||
|
} else if strings.HasPrefix(opt, "master:") {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return errors.Errorf("path %q is mounted on %q but it is not a shared or slave mount", path, mountInfo.Mountpoint)
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithPrivilegedDevices allows all host devices inside the container
|
||||||
|
func WithPrivilegedDevices(_ context.Context, _ oci.Client, _ *containers.Container, s *runtimespec.Spec) error {
|
||||||
|
if s.Linux == nil {
|
||||||
|
s.Linux = &runtimespec.Linux{}
|
||||||
|
}
|
||||||
|
if s.Linux.Resources == nil {
|
||||||
|
s.Linux.Resources = &runtimespec.LinuxResources{}
|
||||||
|
}
|
||||||
|
hostDevices, err := devices.HostDevices()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for _, hostDevice := range hostDevices {
|
||||||
|
rd := runtimespec.LinuxDevice{
|
||||||
|
Path: hostDevice.Path,
|
||||||
|
Type: string(hostDevice.Type),
|
||||||
|
Major: hostDevice.Major,
|
||||||
|
Minor: hostDevice.Minor,
|
||||||
|
UID: &hostDevice.Uid,
|
||||||
|
GID: &hostDevice.Gid,
|
||||||
|
}
|
||||||
|
if hostDevice.Major == 0 && hostDevice.Minor == 0 {
|
||||||
|
// Invalid device, most likely a symbolic link, skip it.
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
addDevice(s, rd)
|
||||||
|
}
|
||||||
|
s.Linux.Resources.Devices = []runtimespec.LinuxDeviceCgroup{
|
||||||
|
{
|
||||||
|
Allow: true,
|
||||||
|
Access: "rwm",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func addDevice(s *runtimespec.Spec, rd runtimespec.LinuxDevice) {
|
||||||
|
for i, dev := range s.Linux.Devices {
|
||||||
|
if dev.Path == rd.Path {
|
||||||
|
s.Linux.Devices[i] = rd
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s.Linux.Devices = append(s.Linux.Devices, rd)
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithDevices sets the provided devices onto the container spec
|
||||||
|
func WithDevices(osi osinterface.OS, config *runtime.ContainerConfig) oci.SpecOpts {
|
||||||
|
return func(ctx context.Context, client oci.Client, c *containers.Container, s *runtimespec.Spec) (err error) {
|
||||||
|
if s.Linux == nil {
|
||||||
|
s.Linux = &runtimespec.Linux{}
|
||||||
|
}
|
||||||
|
if s.Linux.Resources == nil {
|
||||||
|
s.Linux.Resources = &runtimespec.LinuxResources{}
|
||||||
|
}
|
||||||
|
for _, device := range config.GetDevices() {
|
||||||
|
path, err := osi.ResolveSymbolicLink(device.HostPath)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
dev, err := devices.DeviceFromPath(path, device.Permissions)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
rd := runtimespec.LinuxDevice{
|
||||||
|
Path: device.ContainerPath,
|
||||||
|
Type: string(dev.Type),
|
||||||
|
Major: dev.Major,
|
||||||
|
Minor: dev.Minor,
|
||||||
|
UID: &dev.Uid,
|
||||||
|
GID: &dev.Gid,
|
||||||
|
}
|
||||||
|
|
||||||
|
addDevice(s, rd)
|
||||||
|
|
||||||
|
s.Linux.Resources.Devices = append(s.Linux.Resources.Devices, runtimespec.LinuxDeviceCgroup{
|
||||||
|
Allow: true,
|
||||||
|
Type: string(dev.Type),
|
||||||
|
Major: &dev.Major,
|
||||||
|
Minor: &dev.Minor,
|
||||||
|
Access: dev.Permissions,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithCapabilities sets the provided capabilties from the security context
|
||||||
|
func WithCapabilities(sc *runtime.LinuxContainerSecurityContext) oci.SpecOpts {
|
||||||
|
capabilities := sc.GetCapabilities()
|
||||||
|
if capabilities == nil {
|
||||||
|
return nullOpt
|
||||||
|
}
|
||||||
|
|
||||||
|
var opts []oci.SpecOpts
|
||||||
|
// Add/drop all capabilities if "all" is specified, so that
|
||||||
|
// following individual add/drop could still work. E.g.
|
||||||
|
// AddCapabilities: []string{"ALL"}, DropCapabilities: []string{"CHOWN"}
|
||||||
|
// will be all capabilities without `CAP_CHOWN`.
|
||||||
|
if util.InStringSlice(capabilities.GetAddCapabilities(), "ALL") {
|
||||||
|
opts = append(opts, oci.WithAllCapabilities)
|
||||||
|
}
|
||||||
|
if util.InStringSlice(capabilities.GetDropCapabilities(), "ALL") {
|
||||||
|
opts = append(opts, oci.WithCapabilities(nil))
|
||||||
|
}
|
||||||
|
|
||||||
|
var caps []string
|
||||||
|
for _, c := range capabilities.GetAddCapabilities() {
|
||||||
|
if strings.ToUpper(c) == "ALL" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
// Capabilities in CRI doesn't have `CAP_` prefix, so add it.
|
||||||
|
caps = append(caps, "CAP_"+strings.ToUpper(c))
|
||||||
|
}
|
||||||
|
opts = append(opts, oci.WithAddedCapabilities(caps))
|
||||||
|
|
||||||
|
caps = []string{}
|
||||||
|
for _, c := range capabilities.GetDropCapabilities() {
|
||||||
|
if strings.ToUpper(c) == "ALL" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
caps = append(caps, "CAP_"+strings.ToUpper(c))
|
||||||
|
}
|
||||||
|
opts = append(opts, oci.WithDroppedCapabilities(caps))
|
||||||
|
return oci.Compose(opts...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithoutAmbientCaps removes the ambient caps from the spec
|
||||||
|
func WithoutAmbientCaps(_ context.Context, _ oci.Client, c *containers.Container, s *runtimespec.Spec) error {
|
||||||
|
if s.Process == nil {
|
||||||
|
s.Process = &runtimespec.Process{}
|
||||||
|
}
|
||||||
|
if s.Process.Capabilities == nil {
|
||||||
|
s.Process.Capabilities = &runtimespec.LinuxCapabilities{}
|
||||||
|
}
|
||||||
|
s.Process.Capabilities.Ambient = nil
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithDisabledCgroups clears the Cgroups Path from the spec
|
||||||
|
func WithDisabledCgroups(_ context.Context, _ oci.Client, c *containers.Container, s *runtimespec.Spec) error {
|
||||||
|
if s.Linux == nil {
|
||||||
|
s.Linux = &runtimespec.Linux{}
|
||||||
|
}
|
||||||
|
s.Linux.CgroupsPath = ""
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithSelinuxLabels sets the mount and process labels
|
||||||
|
func WithSelinuxLabels(process, mount string) oci.SpecOpts {
|
||||||
|
return func(ctx context.Context, client oci.Client, c *containers.Container, s *runtimespec.Spec) (err error) {
|
||||||
|
if s.Linux == nil {
|
||||||
|
s.Linux = &runtimespec.Linux{}
|
||||||
|
}
|
||||||
|
if s.Process == nil {
|
||||||
|
s.Process = &runtimespec.Process{}
|
||||||
|
}
|
||||||
|
s.Linux.MountLabel = mount
|
||||||
|
s.Process.SelinuxLabel = process
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithResources sets the provided resource restrictions
|
||||||
|
func WithResources(resources *runtime.LinuxContainerResources) oci.SpecOpts {
|
||||||
|
return func(ctx context.Context, client oci.Client, c *containers.Container, s *runtimespec.Spec) (err error) {
|
||||||
|
if resources == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if s.Linux == nil {
|
||||||
|
s.Linux = &runtimespec.Linux{}
|
||||||
|
}
|
||||||
|
if s.Linux.Resources == nil {
|
||||||
|
s.Linux.Resources = &runtimespec.LinuxResources{}
|
||||||
|
}
|
||||||
|
if s.Linux.Resources.CPU == nil {
|
||||||
|
s.Linux.Resources.CPU = &runtimespec.LinuxCPU{}
|
||||||
|
}
|
||||||
|
if s.Linux.Resources.Memory == nil {
|
||||||
|
s.Linux.Resources.Memory = &runtimespec.LinuxMemory{}
|
||||||
|
}
|
||||||
|
var (
|
||||||
|
p = uint64(resources.GetCpuPeriod())
|
||||||
|
q = resources.GetCpuQuota()
|
||||||
|
shares = uint64(resources.GetCpuShares())
|
||||||
|
limit = resources.GetMemoryLimitInBytes()
|
||||||
|
)
|
||||||
|
|
||||||
|
if p != 0 {
|
||||||
|
s.Linux.Resources.CPU.Period = &p
|
||||||
|
}
|
||||||
|
if q != 0 {
|
||||||
|
s.Linux.Resources.CPU.Quota = &q
|
||||||
|
}
|
||||||
|
if shares != 0 {
|
||||||
|
s.Linux.Resources.CPU.Shares = &shares
|
||||||
|
}
|
||||||
|
if cpus := resources.GetCpusetCpus(); cpus != "" {
|
||||||
|
s.Linux.Resources.CPU.Cpus = cpus
|
||||||
|
}
|
||||||
|
if mems := resources.GetCpusetMems(); mems != "" {
|
||||||
|
s.Linux.Resources.CPU.Mems = resources.GetCpusetMems()
|
||||||
|
}
|
||||||
|
if limit != 0 {
|
||||||
|
s.Linux.Resources.Memory.Limit = &limit
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithOOMScoreAdj sets the oom score
|
||||||
|
func WithOOMScoreAdj(config *runtime.ContainerConfig, restrict bool) oci.SpecOpts {
|
||||||
|
return func(ctx context.Context, client oci.Client, c *containers.Container, s *runtimespec.Spec) error {
|
||||||
|
if s.Process == nil {
|
||||||
|
s.Process = &runtimespec.Process{}
|
||||||
|
}
|
||||||
|
|
||||||
|
resources := config.GetLinux().GetResources()
|
||||||
|
if resources == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
adj := int(resources.GetOomScoreAdj())
|
||||||
|
if restrict {
|
||||||
|
var err error
|
||||||
|
adj, err = restrictOOMScoreAdj(adj)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s.Process.OOMScoreAdj = &adj
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithSysctls sets the provided sysctls onto the spec
|
||||||
|
func WithSysctls(sysctls map[string]string) oci.SpecOpts {
|
||||||
|
return func(ctx context.Context, client oci.Client, c *containers.Container, s *runtimespec.Spec) error {
|
||||||
|
if s.Linux == nil {
|
||||||
|
s.Linux = &runtimespec.Linux{}
|
||||||
|
}
|
||||||
|
if s.Linux.Sysctl == nil {
|
||||||
|
s.Linux.Sysctl = make(map[string]string)
|
||||||
|
}
|
||||||
|
for k, v := range sysctls {
|
||||||
|
s.Linux.Sysctl[k] = v
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithPodOOMScoreAdj sets the oom score for the pod sandbox
|
||||||
|
func WithPodOOMScoreAdj(adj int, restrict bool) oci.SpecOpts {
|
||||||
|
return func(ctx context.Context, client oci.Client, c *containers.Container, s *runtimespec.Spec) error {
|
||||||
|
if s.Process == nil {
|
||||||
|
s.Process = &runtimespec.Process{}
|
||||||
|
}
|
||||||
|
if restrict {
|
||||||
|
var err error
|
||||||
|
adj, err = restrictOOMScoreAdj(adj)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s.Process.OOMScoreAdj = &adj
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithSupplementalGroups sets the supplemental groups for the process
|
||||||
|
func WithSupplementalGroups(groups []int64) oci.SpecOpts {
|
||||||
|
return func(ctx context.Context, client oci.Client, c *containers.Container, s *runtimespec.Spec) error {
|
||||||
|
if s.Process == nil {
|
||||||
|
s.Process = &runtimespec.Process{}
|
||||||
|
}
|
||||||
|
var guids []uint32
|
||||||
|
for _, g := range groups {
|
||||||
|
guids = append(guids, uint32(g))
|
||||||
|
}
|
||||||
|
s.Process.User.AdditionalGids = mergeGids(s.Process.User.AdditionalGids, guids)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithAnnotation sets the provided annotation
|
||||||
|
func WithAnnotation(k, v string) oci.SpecOpts {
|
||||||
|
return func(ctx context.Context, client oci.Client, c *containers.Container, s *runtimespec.Spec) error {
|
||||||
|
if s.Annotations == nil {
|
||||||
|
s.Annotations = make(map[string]string)
|
||||||
|
}
|
||||||
|
s.Annotations[k] = v
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithPodNamespaces sets the pod namespaces for the container
|
||||||
|
func WithPodNamespaces(config *runtime.LinuxContainerSecurityContext, pid uint32) oci.SpecOpts {
|
||||||
|
namespaces := config.GetNamespaceOptions()
|
||||||
|
|
||||||
|
opts := []oci.SpecOpts{
|
||||||
|
oci.WithLinuxNamespace(runtimespec.LinuxNamespace{Type: runtimespec.NetworkNamespace, Path: GetNetworkNamespace(pid)}),
|
||||||
|
oci.WithLinuxNamespace(runtimespec.LinuxNamespace{Type: runtimespec.IPCNamespace, Path: GetIPCNamespace(pid)}),
|
||||||
|
oci.WithLinuxNamespace(runtimespec.LinuxNamespace{Type: runtimespec.UTSNamespace, Path: GetUTSNamespace(pid)}),
|
||||||
|
}
|
||||||
|
if namespaces.GetPid() != runtime.NamespaceMode_CONTAINER {
|
||||||
|
opts = append(opts, oci.WithLinuxNamespace(runtimespec.LinuxNamespace{Type: runtimespec.PIDNamespace, Path: GetPIDNamespace(pid)}))
|
||||||
|
}
|
||||||
|
return oci.Compose(opts...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithDefaultSandboxShares sets the default sandbox CPU shares
|
||||||
|
func WithDefaultSandboxShares(ctx context.Context, client oci.Client, c *containers.Container, s *runtimespec.Spec) error {
|
||||||
|
if s.Linux == nil {
|
||||||
|
s.Linux = &runtimespec.Linux{}
|
||||||
|
}
|
||||||
|
if s.Linux.Resources == nil {
|
||||||
|
s.Linux.Resources = &runtimespec.LinuxResources{}
|
||||||
|
}
|
||||||
|
if s.Linux.Resources.CPU == nil {
|
||||||
|
s.Linux.Resources.CPU = &runtimespec.LinuxCPU{}
|
||||||
|
}
|
||||||
|
i := uint64(DefaultSandboxCPUshares)
|
||||||
|
s.Linux.Resources.CPU.Shares = &i
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithoutNamespace removes the provided namespace
|
||||||
|
func WithoutNamespace(t runtimespec.LinuxNamespaceType) oci.SpecOpts {
|
||||||
|
return func(ctx context.Context, client oci.Client, c *containers.Container, s *runtimespec.Spec) error {
|
||||||
|
if s.Linux == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
for i, ns := range s.Linux.Namespaces {
|
||||||
|
if ns.Type == t {
|
||||||
|
s.Linux.Namespaces = append(s.Linux.Namespaces[:i], s.Linux.Namespaces[i+1:]...)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func nullOpt(_ context.Context, _ oci.Client, _ *containers.Container, _ *runtimespec.Spec) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func getCurrentOOMScoreAdj() (int, error) {
|
||||||
|
b, err := ioutil.ReadFile("/proc/self/oom_score_adj")
|
||||||
|
if err != nil {
|
||||||
|
return 0, errors.Wrap(err, "could not get the daemon oom_score_adj")
|
||||||
|
}
|
||||||
|
s := strings.TrimSpace(string(b))
|
||||||
|
i, err := strconv.Atoi(s)
|
||||||
|
if err != nil {
|
||||||
|
return 0, errors.Wrap(err, "could not get the daemon oom_score_adj")
|
||||||
|
}
|
||||||
|
return i, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func restrictOOMScoreAdj(preferredOOMScoreAdj int) (int, error) {
|
||||||
|
currentOOMScoreAdj, err := getCurrentOOMScoreAdj()
|
||||||
|
if err != nil {
|
||||||
|
return preferredOOMScoreAdj, err
|
||||||
|
}
|
||||||
|
if preferredOOMScoreAdj < currentOOMScoreAdj {
|
||||||
|
return currentOOMScoreAdj, nil
|
||||||
|
}
|
||||||
|
return preferredOOMScoreAdj, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
// netNSFormat is the format of network namespace of a process.
|
||||||
|
netNSFormat = "/proc/%v/ns/net"
|
||||||
|
// ipcNSFormat is the format of ipc namespace of a process.
|
||||||
|
ipcNSFormat = "/proc/%v/ns/ipc"
|
||||||
|
// utsNSFormat is the format of uts namespace of a process.
|
||||||
|
utsNSFormat = "/proc/%v/ns/uts"
|
||||||
|
// pidNSFormat is the format of pid namespace of a process.
|
||||||
|
pidNSFormat = "/proc/%v/ns/pid"
|
||||||
|
)
|
||||||
|
|
||||||
|
// GetNetworkNamespace returns the network namespace of a process.
|
||||||
|
func GetNetworkNamespace(pid uint32) string {
|
||||||
|
return fmt.Sprintf(netNSFormat, pid)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetIPCNamespace returns the ipc namespace of a process.
|
||||||
|
func GetIPCNamespace(pid uint32) string {
|
||||||
|
return fmt.Sprintf(ipcNSFormat, pid)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetUTSNamespace returns the uts namespace of a process.
|
||||||
|
func GetUTSNamespace(pid uint32) string {
|
||||||
|
return fmt.Sprintf(utsNSFormat, pid)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetPIDNamespace returns the pid namespace of a process.
|
||||||
|
func GetPIDNamespace(pid uint32) string {
|
||||||
|
return fmt.Sprintf(pidNSFormat, pid)
|
||||||
|
}
|
||||||
|
@ -17,9 +17,12 @@ limitations under the License.
|
|||||||
package opts
|
package opts
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"sort"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestMergeGids(t *testing.T) {
|
func TestMergeGids(t *testing.T) {
|
||||||
@ -27,3 +30,41 @@ func TestMergeGids(t *testing.T) {
|
|||||||
gids2 := []uint32{2, 3, 4}
|
gids2 := []uint32{2, 3, 4}
|
||||||
assert.Equal(t, []uint32{3, 2, 1, 4}, mergeGids(gids1, gids2))
|
assert.Equal(t, []uint32{3, 2, 1, 4}, mergeGids(gids1, gids2))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestOrderedMounts(t *testing.T) {
|
||||||
|
mounts := []*runtime.Mount{
|
||||||
|
{ContainerPath: "/a/b/c"},
|
||||||
|
{ContainerPath: "/a/b"},
|
||||||
|
{ContainerPath: "/a/b/c/d"},
|
||||||
|
{ContainerPath: "/a"},
|
||||||
|
{ContainerPath: "/b"},
|
||||||
|
{ContainerPath: "/b/c"},
|
||||||
|
}
|
||||||
|
expected := []*runtime.Mount{
|
||||||
|
{ContainerPath: "/a"},
|
||||||
|
{ContainerPath: "/b"},
|
||||||
|
{ContainerPath: "/a/b"},
|
||||||
|
{ContainerPath: "/b/c"},
|
||||||
|
{ContainerPath: "/a/b/c"},
|
||||||
|
{ContainerPath: "/a/b/c/d"},
|
||||||
|
}
|
||||||
|
sort.Stable(orderedMounts(mounts))
|
||||||
|
assert.Equal(t, expected, mounts)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRestrictOOMScoreAdj(t *testing.T) {
|
||||||
|
current, err := getCurrentOOMScoreAdj()
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
got, err := restrictOOMScoreAdj(current - 1)
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.Equal(t, got, current)
|
||||||
|
|
||||||
|
got, err = restrictOOMScoreAdj(current)
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.Equal(t, got, current)
|
||||||
|
|
||||||
|
got, err = restrictOOMScoreAdj(current + 1)
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.Equal(t, got, current+1)
|
||||||
|
}
|
||||||
|
@ -17,9 +17,7 @@ limitations under the License.
|
|||||||
package server
|
package server
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"sort"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
@ -28,20 +26,14 @@ import (
|
|||||||
"github.com/containerd/containerd/containers"
|
"github.com/containerd/containerd/containers"
|
||||||
"github.com/containerd/containerd/contrib/apparmor"
|
"github.com/containerd/containerd/contrib/apparmor"
|
||||||
"github.com/containerd/containerd/contrib/seccomp"
|
"github.com/containerd/containerd/contrib/seccomp"
|
||||||
"github.com/containerd/containerd/mount"
|
|
||||||
"github.com/containerd/containerd/oci"
|
"github.com/containerd/containerd/oci"
|
||||||
"github.com/containerd/typeurl"
|
"github.com/containerd/typeurl"
|
||||||
"github.com/davecgh/go-spew/spew"
|
"github.com/davecgh/go-spew/spew"
|
||||||
imagespec "github.com/opencontainers/image-spec/specs-go/v1"
|
imagespec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||||
"github.com/opencontainers/runc/libcontainer/devices"
|
|
||||||
runtimespec "github.com/opencontainers/runtime-spec/specs-go"
|
runtimespec "github.com/opencontainers/runtime-spec/specs-go"
|
||||||
"github.com/opencontainers/runtime-tools/validate"
|
|
||||||
"github.com/opencontainers/selinux/go-selinux/label"
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"github.com/syndtr/gocapability/capability"
|
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
"golang.org/x/sys/unix"
|
|
||||||
runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
|
runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
|
||||||
|
|
||||||
"github.com/containerd/cri/pkg/annotations"
|
"github.com/containerd/cri/pkg/annotations"
|
||||||
@ -317,52 +309,45 @@ func (c *criService) CreateContainer(ctx context.Context, r *runtime.CreateConta
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *criService) generateContainerSpec(id string, sandboxID string, sandboxPid uint32, config *runtime.ContainerConfig,
|
func (c *criService) generateContainerSpec(id string, sandboxID string, sandboxPid uint32, config *runtime.ContainerConfig,
|
||||||
sandboxConfig *runtime.PodSandboxConfig, imageConfig *imagespec.ImageConfig, extraMounts []*runtime.Mount,
|
sandboxConfig *runtime.PodSandboxConfig, imageConfig *imagespec.ImageConfig, extraMounts []*runtime.Mount, runtimePodAnnotations []string) (*runtimespec.Spec, error) {
|
||||||
runtimePodAnnotations []string) (*runtimespec.Spec, error) {
|
|
||||||
// Creates a spec Generator with the default spec.
|
specOpts := []oci.SpecOpts{
|
||||||
spec, err := defaultRuntimeSpec(id)
|
customopts.WithoutRunMount,
|
||||||
if err != nil {
|
customopts.WithoutDefaultSecuritySettings,
|
||||||
return nil, err
|
customopts.WithRelativeRoot(relativeRootfsPath),
|
||||||
|
customopts.WithProcessArgs(config, imageConfig),
|
||||||
|
// this will be set based on the security context below
|
||||||
|
oci.WithNewPrivileges,
|
||||||
}
|
}
|
||||||
g := newSpecGenerator(spec)
|
|
||||||
|
|
||||||
// Set the relative path to the rootfs of the container from containerd's
|
|
||||||
// pre-defined directory.
|
|
||||||
g.SetRootPath(relativeRootfsPath)
|
|
||||||
|
|
||||||
if err := setOCIProcessArgs(&g, config, imageConfig); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if config.GetWorkingDir() != "" {
|
if config.GetWorkingDir() != "" {
|
||||||
g.SetProcessCwd(config.GetWorkingDir())
|
specOpts = append(specOpts, oci.WithProcessCwd(config.GetWorkingDir()))
|
||||||
} else if imageConfig.WorkingDir != "" {
|
} else if imageConfig.WorkingDir != "" {
|
||||||
g.SetProcessCwd(imageConfig.WorkingDir)
|
specOpts = append(specOpts, oci.WithProcessCwd(imageConfig.WorkingDir))
|
||||||
}
|
}
|
||||||
|
|
||||||
g.SetProcessTerminal(config.GetTty())
|
|
||||||
if config.GetTty() {
|
if config.GetTty() {
|
||||||
g.AddProcessEnv("TERM", "xterm")
|
specOpts = append(specOpts, oci.WithTTY)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add HOSTNAME env.
|
// Add HOSTNAME env.
|
||||||
hostname := sandboxConfig.GetHostname()
|
var (
|
||||||
if sandboxConfig.GetHostname() == "" {
|
err error
|
||||||
hostname, err = c.os.Hostname()
|
hostname = sandboxConfig.GetHostname()
|
||||||
if err != nil {
|
)
|
||||||
|
if hostname == "" {
|
||||||
|
if hostname, err = c.os.Hostname(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
g.AddProcessEnv(hostnameEnv, hostname)
|
specOpts = append(specOpts, oci.WithEnv([]string{hostnameEnv + "=" + hostname}))
|
||||||
|
|
||||||
// Apply envs from image config first, so that envs from container config
|
// Apply envs from image config first, so that envs from container config
|
||||||
// can override them.
|
// can override them.
|
||||||
if err := addImageEnvs(&g, imageConfig.Env); err != nil {
|
env := imageConfig.Env
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
for _, e := range config.GetEnvs() {
|
for _, e := range config.GetEnvs() {
|
||||||
g.AddProcessEnv(e.GetKey(), e.GetValue())
|
env = append(env, e.GetKey()+"="+e.GetValue())
|
||||||
}
|
}
|
||||||
|
specOpts = append(specOpts, oci.WithEnv(env))
|
||||||
|
|
||||||
securityContext := config.GetLinux().GetSecurityContext()
|
securityContext := config.GetLinux().GetSecurityContext()
|
||||||
selinuxOpt := securityContext.GetSelinuxOptions()
|
selinuxOpt := securityContext.GetSelinuxOptions()
|
||||||
@ -370,97 +355,78 @@ func (c *criService) generateContainerSpec(id string, sandboxID string, sandboxP
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(err, "failed to init selinux options %+v", securityContext.GetSelinuxOptions())
|
return nil, errors.Wrapf(err, "failed to init selinux options %+v", securityContext.GetSelinuxOptions())
|
||||||
}
|
}
|
||||||
|
specOpts = append(specOpts, customopts.WithMounts(c.os, config, extraMounts, mountLabel))
|
||||||
// Merge extra mounts and CRI mounts.
|
|
||||||
mounts := mergeMounts(config.GetMounts(), extraMounts)
|
|
||||||
if err := c.addOCIBindMounts(&g, mounts, mountLabel); err != nil {
|
|
||||||
return nil, errors.Wrapf(err, "failed to set OCI bind mounts %+v", mounts)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Apply masked paths if specified.
|
// Apply masked paths if specified.
|
||||||
// When `MaskedPaths` is not specified, keep runtime default for backward compatibility;
|
// When `MaskedPaths` is not specified, keep runtime default for backward compatibility;
|
||||||
// When `MaskedPaths` is specified, but length is zero, clear masked path list.
|
// When `MaskedPaths` is specified, but length is zero, clear masked path list.
|
||||||
// Note: If the container is privileged, then we clear any masked paths later on in the call to setOCIPrivileged()
|
// Note: If the container is privileged, then we clear any masked paths later on in the call to setOCIPrivileged()
|
||||||
if securityContext.GetMaskedPaths() != nil {
|
if maskedPaths := securityContext.GetMaskedPaths(); maskedPaths != nil {
|
||||||
g.Config.Linux.MaskedPaths = nil
|
specOpts = append(specOpts, oci.WithMaskedPaths(maskedPaths))
|
||||||
for _, path := range securityContext.GetMaskedPaths() {
|
|
||||||
g.AddLinuxMaskedPaths(path)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply readonly paths if specified.
|
// Apply readonly paths if specified.
|
||||||
// Note: If the container is privileged, then we clear any readonly paths later on in the call to setOCIPrivileged()
|
// Note: If the container is privileged, then we clear any readonly paths later on in the call to setOCIPrivileged()
|
||||||
if securityContext.GetReadonlyPaths() != nil {
|
|
||||||
g.Config.Linux.ReadonlyPaths = nil
|
// Apply readonly paths if specified.
|
||||||
for _, path := range securityContext.GetReadonlyPaths() {
|
if roPaths := securityContext.GetReadonlyPaths(); roPaths != nil {
|
||||||
g.AddLinuxReadonlyPaths(path)
|
specOpts = append(specOpts, oci.WithReadonlyPaths(roPaths))
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if securityContext.GetPrivileged() {
|
if securityContext.GetPrivileged() {
|
||||||
if !sandboxConfig.GetLinux().GetSecurityContext().GetPrivileged() {
|
if !sandboxConfig.GetLinux().GetSecurityContext().GetPrivileged() {
|
||||||
return nil, errors.New("no privileged container allowed in sandbox")
|
return nil, errors.New("no privileged container allowed in sandbox")
|
||||||
}
|
}
|
||||||
if err := setOCIPrivileged(&g, config); err != nil {
|
specOpts = append(specOpts, oci.WithPrivileged, customopts.WithPrivilegedDevices)
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
} else { // not privileged
|
} else { // not privileged
|
||||||
if err := c.addOCIDevices(&g, config.GetDevices()); err != nil {
|
specOpts = append(specOpts, customopts.WithDevices(c.os, config), customopts.WithCapabilities(securityContext))
|
||||||
return nil, errors.Wrapf(err, "failed to set devices mapping %+v", config.GetDevices())
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := setOCICapabilities(&g, securityContext.GetCapabilities()); err != nil {
|
|
||||||
return nil, errors.Wrapf(err, "failed to set capabilities %+v",
|
|
||||||
securityContext.GetCapabilities())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear all ambient capabilities. The implication of non-root + caps
|
// Clear all ambient capabilities. The implication of non-root + caps
|
||||||
// is not clearly defined in Kubernetes.
|
// is not clearly defined in Kubernetes.
|
||||||
// See https://github.com/kubernetes/kubernetes/issues/56374
|
// See https://github.com/kubernetes/kubernetes/issues/56374
|
||||||
// Keep docker's behavior for now.
|
// Keep docker's behavior for now.
|
||||||
g.Config.Process.Capabilities.Ambient = []string{}
|
specOpts = append(specOpts,
|
||||||
|
customopts.WithoutAmbientCaps,
|
||||||
g.SetProcessSelinuxLabel(processLabel)
|
customopts.WithSelinuxLabels(processLabel, mountLabel),
|
||||||
g.SetLinuxMountLabel(mountLabel)
|
)
|
||||||
|
|
||||||
// TODO: Figure out whether we should set no new privilege for sandbox container by default
|
// TODO: Figure out whether we should set no new privilege for sandbox container by default
|
||||||
g.SetProcessNoNewPrivileges(securityContext.GetNoNewPrivs())
|
if securityContext.GetNoNewPrivs() {
|
||||||
|
specOpts = append(specOpts, oci.WithNoNewPrivileges)
|
||||||
|
}
|
||||||
// TODO(random-liu): [P1] Set selinux options (privileged or not).
|
// TODO(random-liu): [P1] Set selinux options (privileged or not).
|
||||||
|
if securityContext.GetReadonlyRootfs() {
|
||||||
g.SetRootReadonly(securityContext.GetReadonlyRootfs())
|
specOpts = append(specOpts, oci.WithRootFSReadonly())
|
||||||
|
}
|
||||||
|
|
||||||
if c.config.DisableCgroup {
|
if c.config.DisableCgroup {
|
||||||
g.SetLinuxCgroupsPath("")
|
specOpts = append(specOpts, customopts.WithDisabledCgroups)
|
||||||
} else {
|
} else {
|
||||||
setOCILinuxResourceCgroup(&g, config.GetLinux().GetResources())
|
specOpts = append(specOpts, customopts.WithResources(config.GetLinux().GetResources()))
|
||||||
if sandboxConfig.GetLinux().GetCgroupParent() != "" {
|
if sandboxConfig.GetLinux().GetCgroupParent() != "" {
|
||||||
cgroupsPath := getCgroupsPath(sandboxConfig.GetLinux().GetCgroupParent(), id,
|
cgroupsPath := getCgroupsPath(sandboxConfig.GetLinux().GetCgroupParent(), id,
|
||||||
c.config.SystemdCgroup)
|
c.config.SystemdCgroup)
|
||||||
g.SetLinuxCgroupsPath(cgroupsPath)
|
specOpts = append(specOpts, oci.WithCgroup(cgroupsPath))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if err := setOCILinuxResourceOOMScoreAdj(&g, config.GetLinux().GetResources(), c.config.RestrictOOMScoreAdj); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set namespaces, share namespace with sandbox container.
|
|
||||||
setOCINamespaces(&g, securityContext.GetNamespaceOptions(), sandboxPid)
|
|
||||||
|
|
||||||
supplementalGroups := securityContext.GetSupplementalGroups()
|
supplementalGroups := securityContext.GetSupplementalGroups()
|
||||||
for _, group := range supplementalGroups {
|
|
||||||
g.AddProcessAdditionalGid(uint32(group))
|
|
||||||
}
|
|
||||||
|
|
||||||
for pKey, pValue := range getPassthroughAnnotations(sandboxConfig.Annotations,
|
for pKey, pValue := range getPassthroughAnnotations(sandboxConfig.Annotations,
|
||||||
runtimePodAnnotations) {
|
runtimePodAnnotations) {
|
||||||
g.AddAnnotation(pKey, pValue)
|
specOpts = append(specOpts, customopts.WithAnnotation(pKey, pValue))
|
||||||
}
|
}
|
||||||
|
|
||||||
g.AddAnnotation(annotations.ContainerType, annotations.ContainerTypeContainer)
|
specOpts = append(specOpts,
|
||||||
g.AddAnnotation(annotations.SandboxID, sandboxID)
|
customopts.WithOOMScoreAdj(config, c.config.RestrictOOMScoreAdj),
|
||||||
|
customopts.WithPodNamespaces(securityContext, sandboxPid),
|
||||||
|
customopts.WithSupplementalGroups(supplementalGroups),
|
||||||
|
customopts.WithAnnotation(annotations.ContainerType, annotations.ContainerTypeContainer),
|
||||||
|
customopts.WithAnnotation(annotations.SandboxID, sandboxID),
|
||||||
|
)
|
||||||
|
|
||||||
return g.Config, nil
|
return runtimeSpec(id, specOpts...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// generateVolumeMounts sets up image volumes for container. Rely on the removal of container
|
// generateVolumeMounts sets up image volumes for container. Rely on the removal of container
|
||||||
@ -545,410 +511,14 @@ func (c *criService) generateContainerMounts(sandboxID string, config *runtime.C
|
|||||||
return mounts
|
return mounts
|
||||||
}
|
}
|
||||||
|
|
||||||
// setOCIProcessArgs sets process args. It returns error if the final arg list
|
// runtimeSpec returns a default runtime spec used in cri-containerd.
|
||||||
// is empty.
|
func runtimeSpec(id string, opts ...oci.SpecOpts) (*runtimespec.Spec, error) {
|
||||||
func setOCIProcessArgs(g *generator, config *runtime.ContainerConfig, imageConfig *imagespec.ImageConfig) error {
|
|
||||||
command, args := config.GetCommand(), config.GetArgs()
|
|
||||||
// The following logic is migrated from https://github.com/moby/moby/blob/master/daemon/commit.go
|
|
||||||
// TODO(random-liu): Clearly define the commands overwrite behavior.
|
|
||||||
if len(command) == 0 {
|
|
||||||
// Copy array to avoid data race.
|
|
||||||
if len(args) == 0 {
|
|
||||||
args = append([]string{}, imageConfig.Cmd...)
|
|
||||||
}
|
|
||||||
if command == nil {
|
|
||||||
command = append([]string{}, imageConfig.Entrypoint...)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if len(command) == 0 && len(args) == 0 {
|
|
||||||
return errors.New("no command specified")
|
|
||||||
}
|
|
||||||
g.SetProcessArgs(append(command, args...))
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// addImageEnvs adds environment variables from image config. It returns error if
|
|
||||||
// an invalid environment variable is encountered.
|
|
||||||
func addImageEnvs(g *generator, imageEnvs []string) error {
|
|
||||||
for _, e := range imageEnvs {
|
|
||||||
kv := strings.SplitN(e, "=", 2)
|
|
||||||
if len(kv) != 2 {
|
|
||||||
return errors.Errorf("invalid environment variable %q", e)
|
|
||||||
}
|
|
||||||
g.AddProcessEnv(kv[0], kv[1])
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func setOCIPrivileged(g *generator, config *runtime.ContainerConfig) error {
|
|
||||||
// Add all capabilities in privileged mode.
|
|
||||||
g.SetupPrivileged(true)
|
|
||||||
setOCIBindMountsPrivileged(g)
|
|
||||||
if err := setOCIDevicesPrivileged(g); err != nil {
|
|
||||||
return errors.Wrapf(err, "failed to set devices mapping %+v", config.GetDevices())
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func clearReadOnly(m *runtimespec.Mount) {
|
|
||||||
var opt []string
|
|
||||||
for _, o := range m.Options {
|
|
||||||
if o != "ro" {
|
|
||||||
opt = append(opt, o)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
m.Options = append(opt, "rw")
|
|
||||||
}
|
|
||||||
|
|
||||||
// addDevices set device mapping without privilege.
|
|
||||||
func (c *criService) addOCIDevices(g *generator, devs []*runtime.Device) error {
|
|
||||||
spec := g.Config
|
|
||||||
for _, device := range devs {
|
|
||||||
path, err := c.os.ResolveSymbolicLink(device.HostPath)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
dev, err := devices.DeviceFromPath(path, device.Permissions)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
rd := runtimespec.LinuxDevice{
|
|
||||||
Path: device.ContainerPath,
|
|
||||||
Type: string(dev.Type),
|
|
||||||
Major: dev.Major,
|
|
||||||
Minor: dev.Minor,
|
|
||||||
UID: &dev.Uid,
|
|
||||||
GID: &dev.Gid,
|
|
||||||
}
|
|
||||||
g.AddDevice(rd)
|
|
||||||
spec.Linux.Resources.Devices = append(spec.Linux.Resources.Devices, runtimespec.LinuxDeviceCgroup{
|
|
||||||
Allow: true,
|
|
||||||
Type: string(dev.Type),
|
|
||||||
Major: &dev.Major,
|
|
||||||
Minor: &dev.Minor,
|
|
||||||
Access: dev.Permissions,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// addDevices set device mapping with privilege.
|
|
||||||
func setOCIDevicesPrivileged(g *generator) error {
|
|
||||||
spec := g.Config
|
|
||||||
hostDevices, err := devices.HostDevices()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
for _, hostDevice := range hostDevices {
|
|
||||||
rd := runtimespec.LinuxDevice{
|
|
||||||
Path: hostDevice.Path,
|
|
||||||
Type: string(hostDevice.Type),
|
|
||||||
Major: hostDevice.Major,
|
|
||||||
Minor: hostDevice.Minor,
|
|
||||||
UID: &hostDevice.Uid,
|
|
||||||
GID: &hostDevice.Gid,
|
|
||||||
}
|
|
||||||
if hostDevice.Major == 0 && hostDevice.Minor == 0 {
|
|
||||||
// Invalid device, most likely a symbolic link, skip it.
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
g.AddDevice(rd)
|
|
||||||
}
|
|
||||||
spec.Linux.Resources.Devices = []runtimespec.LinuxDeviceCgroup{
|
|
||||||
{
|
|
||||||
Allow: true,
|
|
||||||
Access: "rwm",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// addOCIBindMounts adds bind mounts.
|
|
||||||
func (c *criService) addOCIBindMounts(g *generator, mounts []*runtime.Mount, mountLabel string) error {
|
|
||||||
// Sort mounts in number of parts. This ensures that high level mounts don't
|
|
||||||
// shadow other mounts.
|
|
||||||
sort.Sort(orderedMounts(mounts))
|
|
||||||
|
|
||||||
// Mount cgroup into the container as readonly, which inherits docker's behavior.
|
|
||||||
g.AddMount(runtimespec.Mount{
|
|
||||||
Source: "cgroup",
|
|
||||||
Destination: "/sys/fs/cgroup",
|
|
||||||
Type: "cgroup",
|
|
||||||
Options: []string{"nosuid", "noexec", "nodev", "relatime", "ro"},
|
|
||||||
})
|
|
||||||
|
|
||||||
// Copy all mounts from default mounts, except for
|
|
||||||
// - mounts overriden by supplied mount;
|
|
||||||
// - all mounts under /dev if a supplied /dev is present.
|
|
||||||
mountSet := make(map[string]struct{})
|
|
||||||
for _, m := range mounts {
|
|
||||||
mountSet[filepath.Clean(m.ContainerPath)] = struct{}{}
|
|
||||||
}
|
|
||||||
defaultMounts := g.Mounts()
|
|
||||||
g.ClearMounts()
|
|
||||||
for _, m := range defaultMounts {
|
|
||||||
dst := filepath.Clean(m.Destination)
|
|
||||||
if _, ok := mountSet[dst]; ok {
|
|
||||||
// filter out mount overridden by a supplied mount
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if _, mountDev := mountSet["/dev"]; mountDev && strings.HasPrefix(dst, "/dev/") {
|
|
||||||
// filter out everything under /dev if /dev is a supplied mount
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
g.AddMount(m)
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, mount := range mounts {
|
|
||||||
dst := mount.GetContainerPath()
|
|
||||||
src := mount.GetHostPath()
|
|
||||||
// Create the host path if it doesn't exist.
|
|
||||||
// TODO(random-liu): Add CRI validation test for this case.
|
|
||||||
if _, err := c.os.Stat(src); err != nil {
|
|
||||||
if !os.IsNotExist(err) {
|
|
||||||
return errors.Wrapf(err, "failed to stat %q", src)
|
|
||||||
}
|
|
||||||
if err := c.os.MkdirAll(src, 0755); err != nil {
|
|
||||||
return errors.Wrapf(err, "failed to mkdir %q", src)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// TODO(random-liu): Add cri-containerd integration test or cri validation test
|
|
||||||
// for this.
|
|
||||||
src, err := c.os.ResolveSymbolicLink(src)
|
|
||||||
if err != nil {
|
|
||||||
return errors.Wrapf(err, "failed to resolve symlink %q", src)
|
|
||||||
}
|
|
||||||
|
|
||||||
options := []string{"rbind"}
|
|
||||||
switch mount.GetPropagation() {
|
|
||||||
case runtime.MountPropagation_PROPAGATION_PRIVATE:
|
|
||||||
options = append(options, "rprivate")
|
|
||||||
// Since default root propogation in runc is rprivate ignore
|
|
||||||
// setting the root propagation
|
|
||||||
case runtime.MountPropagation_PROPAGATION_BIDIRECTIONAL:
|
|
||||||
if err := ensureShared(src, c.os.LookupMount); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
options = append(options, "rshared")
|
|
||||||
g.SetLinuxRootPropagation("rshared") // nolint: errcheck
|
|
||||||
case runtime.MountPropagation_PROPAGATION_HOST_TO_CONTAINER:
|
|
||||||
if err := ensureSharedOrSlave(src, c.os.LookupMount); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
options = append(options, "rslave")
|
|
||||||
if g.Config.Linux.RootfsPropagation != "rshared" &&
|
|
||||||
g.Config.Linux.RootfsPropagation != "rslave" {
|
|
||||||
g.SetLinuxRootPropagation("rslave") // nolint: errcheck
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
logrus.Warnf("Unknown propagation mode for hostPath %q", mount.HostPath)
|
|
||||||
options = append(options, "rprivate")
|
|
||||||
}
|
|
||||||
|
|
||||||
// NOTE(random-liu): we don't change all mounts to `ro` when root filesystem
|
|
||||||
// is readonly. This is different from docker's behavior, but make more sense.
|
|
||||||
if mount.GetReadonly() {
|
|
||||||
options = append(options, "ro")
|
|
||||||
} else {
|
|
||||||
options = append(options, "rw")
|
|
||||||
}
|
|
||||||
|
|
||||||
if mount.GetSelinuxRelabel() {
|
|
||||||
if err := label.Relabel(src, mountLabel, true); err != nil && err != unix.ENOTSUP {
|
|
||||||
return errors.Wrapf(err, "relabel %q with %q failed", src, mountLabel)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
g.AddMount(runtimespec.Mount{
|
|
||||||
Source: src,
|
|
||||||
Destination: dst,
|
|
||||||
Type: "bind",
|
|
||||||
Options: options,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func setOCIBindMountsPrivileged(g *generator) {
|
|
||||||
spec := g.Config
|
|
||||||
// clear readonly for /sys and cgroup
|
|
||||||
for i, m := range spec.Mounts {
|
|
||||||
if filepath.Clean(spec.Mounts[i].Destination) == "/sys" {
|
|
||||||
clearReadOnly(&spec.Mounts[i])
|
|
||||||
}
|
|
||||||
if m.Type == "cgroup" {
|
|
||||||
clearReadOnly(&spec.Mounts[i])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
spec.Linux.ReadonlyPaths = nil
|
|
||||||
spec.Linux.MaskedPaths = nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// setOCILinuxResourceCgroup set container cgroup resource limit.
|
|
||||||
func setOCILinuxResourceCgroup(g *generator, resources *runtime.LinuxContainerResources) {
|
|
||||||
if resources == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
g.SetLinuxResourcesCPUPeriod(uint64(resources.GetCpuPeriod()))
|
|
||||||
g.SetLinuxResourcesCPUQuota(resources.GetCpuQuota())
|
|
||||||
g.SetLinuxResourcesCPUShares(uint64(resources.GetCpuShares()))
|
|
||||||
g.SetLinuxResourcesMemoryLimit(resources.GetMemoryLimitInBytes())
|
|
||||||
g.SetLinuxResourcesCPUCpus(resources.GetCpusetCpus())
|
|
||||||
g.SetLinuxResourcesCPUMems(resources.GetCpusetMems())
|
|
||||||
}
|
|
||||||
|
|
||||||
// setOCILinuxResourceOOMScoreAdj set container OOMScoreAdj resource limit.
|
|
||||||
func setOCILinuxResourceOOMScoreAdj(g *generator, resources *runtime.LinuxContainerResources, restrictOOMScoreAdjFlag bool) error {
|
|
||||||
if resources == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
adj := int(resources.GetOomScoreAdj())
|
|
||||||
if restrictOOMScoreAdjFlag {
|
|
||||||
var err error
|
|
||||||
adj, err = restrictOOMScoreAdj(adj)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
g.SetProcessOOMScoreAdj(adj)
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// getOCICapabilitiesList returns a list of all available capabilities.
|
|
||||||
func getOCICapabilitiesList() []string {
|
|
||||||
var caps []string
|
|
||||||
for _, cap := range capability.List() {
|
|
||||||
if cap > validate.LastCap() {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
caps = append(caps, "CAP_"+strings.ToUpper(cap.String()))
|
|
||||||
}
|
|
||||||
return caps
|
|
||||||
}
|
|
||||||
|
|
||||||
// Adds capabilities to all sets relevant to root (bounding, permitted, effective, inheritable)
|
|
||||||
func addProcessRootCapability(g *generator, c string) error {
|
|
||||||
if err := g.AddProcessCapabilityBounding(c); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := g.AddProcessCapabilityPermitted(c); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := g.AddProcessCapabilityEffective(c); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := g.AddProcessCapabilityInheritable(c); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Drops capabilities to all sets relevant to root (bounding, permitted, effective, inheritable)
|
|
||||||
func dropProcessRootCapability(g *generator, c string) error {
|
|
||||||
if err := g.DropProcessCapabilityBounding(c); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := g.DropProcessCapabilityPermitted(c); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := g.DropProcessCapabilityEffective(c); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := g.DropProcessCapabilityInheritable(c); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// setOCICapabilities adds/drops process capabilities.
|
|
||||||
func setOCICapabilities(g *generator, capabilities *runtime.Capability) error {
|
|
||||||
if capabilities == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add/drop all capabilities if "all" is specified, so that
|
|
||||||
// following individual add/drop could still work. E.g.
|
|
||||||
// AddCapabilities: []string{"ALL"}, DropCapabilities: []string{"CHOWN"}
|
|
||||||
// will be all capabilities without `CAP_CHOWN`.
|
|
||||||
if util.InStringSlice(capabilities.GetAddCapabilities(), "ALL") {
|
|
||||||
for _, c := range getOCICapabilitiesList() {
|
|
||||||
if err := addProcessRootCapability(g, c); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if util.InStringSlice(capabilities.GetDropCapabilities(), "ALL") {
|
|
||||||
for _, c := range getOCICapabilitiesList() {
|
|
||||||
if err := dropProcessRootCapability(g, c); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, c := range capabilities.GetAddCapabilities() {
|
|
||||||
if strings.ToUpper(c) == "ALL" {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
// Capabilities in CRI doesn't have `CAP_` prefix, so add it.
|
|
||||||
if err := addProcessRootCapability(g, "CAP_"+strings.ToUpper(c)); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, c := range capabilities.GetDropCapabilities() {
|
|
||||||
if strings.ToUpper(c) == "ALL" {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if err := dropProcessRootCapability(g, "CAP_"+strings.ToUpper(c)); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// setOCINamespaces sets namespaces.
|
|
||||||
func setOCINamespaces(g *generator, namespaces *runtime.NamespaceOption, sandboxPid uint32) {
|
|
||||||
g.AddOrReplaceLinuxNamespace(string(runtimespec.NetworkNamespace), getNetworkNamespace(sandboxPid)) // nolint: errcheck
|
|
||||||
g.AddOrReplaceLinuxNamespace(string(runtimespec.IPCNamespace), getIPCNamespace(sandboxPid)) // nolint: errcheck
|
|
||||||
g.AddOrReplaceLinuxNamespace(string(runtimespec.UTSNamespace), getUTSNamespace(sandboxPid)) // nolint: errcheck
|
|
||||||
// Do not share pid namespace if namespace mode is CONTAINER.
|
|
||||||
if namespaces.GetPid() != runtime.NamespaceMode_CONTAINER {
|
|
||||||
g.AddOrReplaceLinuxNamespace(string(runtimespec.PIDNamespace), getPIDNamespace(sandboxPid)) // nolint: errcheck
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// defaultRuntimeSpec returns a default runtime spec used in cri-containerd.
|
|
||||||
func defaultRuntimeSpec(id string) (*runtimespec.Spec, error) {
|
|
||||||
// GenerateSpec needs namespace.
|
// GenerateSpec needs namespace.
|
||||||
ctx := ctrdutil.NamespacedContext()
|
ctx := ctrdutil.NamespacedContext()
|
||||||
spec, err := oci.GenerateSpec(ctx, nil, &containers.Container{ID: id})
|
spec, err := oci.GenerateSpec(ctx, nil, &containers.Container{ID: id}, opts...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove `/run` mount
|
|
||||||
// TODO(random-liu): Mount tmpfs for /run and handle copy-up.
|
|
||||||
var mounts []runtimespec.Mount
|
|
||||||
for _, mount := range spec.Mounts {
|
|
||||||
if filepath.Clean(mount.Destination) == "/run" {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
mounts = append(mounts, mount)
|
|
||||||
}
|
|
||||||
spec.Mounts = mounts
|
|
||||||
|
|
||||||
// Make sure no default seccomp/apparmor is specified
|
|
||||||
if spec.Process != nil {
|
|
||||||
spec.Process.ApparmorProfile = ""
|
|
||||||
}
|
|
||||||
if spec.Linux != nil {
|
|
||||||
spec.Linux.Seccomp = nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove default rlimits (See issue #515)
|
|
||||||
spec.Process.Rlimits = nil
|
|
||||||
|
|
||||||
return spec, nil
|
return spec, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1017,42 +587,6 @@ func generateApparmorSpecOpts(apparmorProf string, privileged, apparmorEnabled b
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure mount point on which path is mounted, is shared.
|
|
||||||
func ensureShared(path string, lookupMount func(string) (mount.Info, error)) error {
|
|
||||||
mountInfo, err := lookupMount(path)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make sure source mount point is shared.
|
|
||||||
optsSplit := strings.Split(mountInfo.Optional, " ")
|
|
||||||
for _, opt := range optsSplit {
|
|
||||||
if strings.HasPrefix(opt, "shared:") {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return errors.Errorf("path %q is mounted on %q but it is not a shared mount", path, mountInfo.Mountpoint)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ensure mount point on which path is mounted, is either shared or slave.
|
|
||||||
func ensureSharedOrSlave(path string, lookupMount func(string) (mount.Info, error)) error {
|
|
||||||
mountInfo, err := lookupMount(path)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
// Make sure source mount point is shared.
|
|
||||||
optsSplit := strings.Split(mountInfo.Optional, " ")
|
|
||||||
for _, opt := range optsSplit {
|
|
||||||
if strings.HasPrefix(opt, "shared:") {
|
|
||||||
return nil
|
|
||||||
} else if strings.HasPrefix(opt, "master:") {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return errors.Errorf("path %q is mounted on %q but it is not a shared or slave mount", path, mountInfo.Mountpoint)
|
|
||||||
}
|
|
||||||
|
|
||||||
// generateUserString generates valid user string based on OCI Image Spec v1.0.0.
|
// generateUserString generates valid user string based on OCI Image Spec v1.0.0.
|
||||||
// TODO(random-liu): Add group name support in CRI.
|
// TODO(random-liu): Add group name support in CRI.
|
||||||
func generateUserString(username string, uid, gid *runtime.Int64Value) (string, error) {
|
func generateUserString(username string, uid, gid *runtime.Int64Value) (string, error) {
|
||||||
@ -1077,25 +611,3 @@ func generateUserString(username string, uid, gid *runtime.Int64Value) (string,
|
|||||||
}
|
}
|
||||||
return userstr, nil
|
return userstr, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// mergeMounts merge CRI mounts with extra mounts. If a mount destination
|
|
||||||
// is mounted by both a CRI mount and an extra mount, the CRI mount will
|
|
||||||
// be kept.
|
|
||||||
func mergeMounts(criMounts, extraMounts []*runtime.Mount) []*runtime.Mount {
|
|
||||||
var mounts []*runtime.Mount
|
|
||||||
mounts = append(mounts, criMounts...)
|
|
||||||
// Copy all mounts from extra mounts, except for mounts overriden by CRI.
|
|
||||||
for _, e := range extraMounts {
|
|
||||||
found := false
|
|
||||||
for _, c := range criMounts {
|
|
||||||
if filepath.Clean(e.ContainerPath) == filepath.Clean(c.ContainerPath) {
|
|
||||||
found = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if !found {
|
|
||||||
mounts = append(mounts, e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return mounts
|
|
||||||
}
|
|
||||||
|
@ -29,13 +29,13 @@ import (
|
|||||||
"github.com/containerd/containerd/oci"
|
"github.com/containerd/containerd/oci"
|
||||||
imagespec "github.com/opencontainers/image-spec/specs-go/v1"
|
imagespec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||||
runtimespec "github.com/opencontainers/runtime-spec/specs-go"
|
runtimespec "github.com/opencontainers/runtime-spec/specs-go"
|
||||||
"github.com/opencontainers/runtime-tools/generate"
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
|
runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
|
||||||
|
|
||||||
"github.com/containerd/cri/pkg/annotations"
|
"github.com/containerd/cri/pkg/annotations"
|
||||||
|
"github.com/containerd/cri/pkg/containerd/opts"
|
||||||
ostesting "github.com/containerd/cri/pkg/os/testing"
|
ostesting "github.com/containerd/cri/pkg/os/testing"
|
||||||
"github.com/containerd/cri/pkg/util"
|
"github.com/containerd/cri/pkg/util"
|
||||||
)
|
)
|
||||||
@ -118,7 +118,8 @@ func getCreateContainerTestData() (*runtime.ContainerConfig, *runtime.PodSandbox
|
|||||||
},
|
},
|
||||||
Annotations: map[string]string{"c": "d"},
|
Annotations: map[string]string{"c": "d"},
|
||||||
Linux: &runtime.LinuxPodSandboxConfig{
|
Linux: &runtime.LinuxPodSandboxConfig{
|
||||||
CgroupParent: "/test/cgroup/parent",
|
CgroupParent: "/test/cgroup/parent",
|
||||||
|
SecurityContext: &runtime.LinuxSandboxSecurityContext{},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
imageConfig := &imagespec.ImageConfig{
|
imageConfig := &imagespec.ImageConfig{
|
||||||
@ -163,19 +164,19 @@ func getCreateContainerTestData() (*runtime.ContainerConfig, *runtime.PodSandbox
|
|||||||
t.Logf("Check namespaces")
|
t.Logf("Check namespaces")
|
||||||
assert.Contains(t, spec.Linux.Namespaces, runtimespec.LinuxNamespace{
|
assert.Contains(t, spec.Linux.Namespaces, runtimespec.LinuxNamespace{
|
||||||
Type: runtimespec.NetworkNamespace,
|
Type: runtimespec.NetworkNamespace,
|
||||||
Path: getNetworkNamespace(sandboxPid),
|
Path: opts.GetNetworkNamespace(sandboxPid),
|
||||||
})
|
})
|
||||||
assert.Contains(t, spec.Linux.Namespaces, runtimespec.LinuxNamespace{
|
assert.Contains(t, spec.Linux.Namespaces, runtimespec.LinuxNamespace{
|
||||||
Type: runtimespec.IPCNamespace,
|
Type: runtimespec.IPCNamespace,
|
||||||
Path: getIPCNamespace(sandboxPid),
|
Path: opts.GetIPCNamespace(sandboxPid),
|
||||||
})
|
})
|
||||||
assert.Contains(t, spec.Linux.Namespaces, runtimespec.LinuxNamespace{
|
assert.Contains(t, spec.Linux.Namespaces, runtimespec.LinuxNamespace{
|
||||||
Type: runtimespec.UTSNamespace,
|
Type: runtimespec.UTSNamespace,
|
||||||
Path: getUTSNamespace(sandboxPid),
|
Path: opts.GetUTSNamespace(sandboxPid),
|
||||||
})
|
})
|
||||||
assert.Contains(t, spec.Linux.Namespaces, runtimespec.LinuxNamespace{
|
assert.Contains(t, spec.Linux.Namespaces, runtimespec.LinuxNamespace{
|
||||||
Type: runtimespec.PIDNamespace,
|
Type: runtimespec.PIDNamespace,
|
||||||
Path: getPIDNamespace(sandboxPid),
|
Path: opts.GetPIDNamespace(sandboxPid),
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Logf("Check PodSandbox annotations")
|
t.Logf("Check PodSandbox annotations")
|
||||||
@ -203,8 +204,6 @@ func TestContainerCapabilities(t *testing.T) {
|
|||||||
testID := "test-id"
|
testID := "test-id"
|
||||||
testSandboxID := "sandbox-id"
|
testSandboxID := "sandbox-id"
|
||||||
testPid := uint32(1234)
|
testPid := uint32(1234)
|
||||||
config, sandboxConfig, imageConfig, specCheck := getCreateContainerTestData()
|
|
||||||
c := newTestCRIService()
|
|
||||||
for desc, test := range map[string]struct {
|
for desc, test := range map[string]struct {
|
||||||
capability *runtime.Capability
|
capability *runtime.Capability
|
||||||
includes []string
|
includes []string
|
||||||
@ -222,20 +221,20 @@ func TestContainerCapabilities(t *testing.T) {
|
|||||||
capability: &runtime.Capability{
|
capability: &runtime.Capability{
|
||||||
AddCapabilities: []string{"ALL"},
|
AddCapabilities: []string{"ALL"},
|
||||||
},
|
},
|
||||||
includes: getOCICapabilitiesList(),
|
includes: oci.GetAllCapabilities(),
|
||||||
},
|
},
|
||||||
"should be able to drop all capabilities": {
|
"should be able to drop all capabilities": {
|
||||||
capability: &runtime.Capability{
|
capability: &runtime.Capability{
|
||||||
DropCapabilities: []string{"ALL"},
|
DropCapabilities: []string{"ALL"},
|
||||||
},
|
},
|
||||||
excludes: getOCICapabilitiesList(),
|
excludes: oci.GetAllCapabilities(),
|
||||||
},
|
},
|
||||||
"should be able to drop capabilities with add all": {
|
"should be able to drop capabilities with add all": {
|
||||||
capability: &runtime.Capability{
|
capability: &runtime.Capability{
|
||||||
AddCapabilities: []string{"ALL"},
|
AddCapabilities: []string{"ALL"},
|
||||||
DropCapabilities: []string{"CHOWN"},
|
DropCapabilities: []string{"CHOWN"},
|
||||||
},
|
},
|
||||||
includes: util.SubtractStringSlice(getOCICapabilitiesList(), "CAP_CHOWN"),
|
includes: util.SubtractStringSlice(oci.GetAllCapabilities(), "CAP_CHOWN"),
|
||||||
excludes: []string{"CAP_CHOWN"},
|
excludes: []string{"CAP_CHOWN"},
|
||||||
},
|
},
|
||||||
"should be able to add capabilities with drop all": {
|
"should be able to add capabilities with drop all": {
|
||||||
@ -244,10 +243,13 @@ func TestContainerCapabilities(t *testing.T) {
|
|||||||
DropCapabilities: []string{"ALL"},
|
DropCapabilities: []string{"ALL"},
|
||||||
},
|
},
|
||||||
includes: []string{"CAP_SYS_ADMIN"},
|
includes: []string{"CAP_SYS_ADMIN"},
|
||||||
excludes: util.SubtractStringSlice(getOCICapabilitiesList(), "CAP_SYS_ADMIN"),
|
excludes: util.SubtractStringSlice(oci.GetAllCapabilities(), "CAP_SYS_ADMIN"),
|
||||||
},
|
},
|
||||||
} {
|
} {
|
||||||
t.Logf("TestCase %q", desc)
|
t.Logf("TestCase %q", desc)
|
||||||
|
config, sandboxConfig, imageConfig, specCheck := getCreateContainerTestData()
|
||||||
|
c := newTestCRIService()
|
||||||
|
|
||||||
config.Linux.SecurityContext.Capabilities = test.capability
|
config.Linux.SecurityContext.Capabilities = test.capability
|
||||||
spec, err := c.generateContainerSpec(testID, testSandboxID, testPid, config, sandboxConfig, imageConfig, nil, []string{})
|
spec, err := c.generateContainerSpec(testID, testSandboxID, testPid, config, sandboxConfig, imageConfig, nil, []string{})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
@ -522,20 +524,19 @@ func TestContainerSpecCommand(t *testing.T) {
|
|||||||
} {
|
} {
|
||||||
|
|
||||||
config, _, imageConfig, _ := getCreateContainerTestData()
|
config, _, imageConfig, _ := getCreateContainerTestData()
|
||||||
og, err := generate.New("linux")
|
|
||||||
assert.NoError(t, err)
|
|
||||||
g := newCustomGenerator(og)
|
|
||||||
config.Command = test.criEntrypoint
|
config.Command = test.criEntrypoint
|
||||||
config.Args = test.criArgs
|
config.Args = test.criArgs
|
||||||
imageConfig.Entrypoint = test.imageEntrypoint
|
imageConfig.Entrypoint = test.imageEntrypoint
|
||||||
imageConfig.Cmd = test.imageArgs
|
imageConfig.Cmd = test.imageArgs
|
||||||
err = setOCIProcessArgs(&g, config, imageConfig)
|
|
||||||
|
var spec runtimespec.Spec
|
||||||
|
err := opts.WithProcessArgs(config, imageConfig)(nil, nil, nil, &spec)
|
||||||
if test.expectErr {
|
if test.expectErr {
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, test.expected, g.Config.Process.Args, desc)
|
assert.Equal(t, test.expected, spec.Process.Args, desc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -762,6 +763,11 @@ func TestGenerateContainerMounts(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestPrivilegedBindMount(t *testing.T) {
|
func TestPrivilegedBindMount(t *testing.T) {
|
||||||
|
testPid := uint32(1234)
|
||||||
|
c := newTestCRIService()
|
||||||
|
testSandboxID := "sandbox-id"
|
||||||
|
config, sandboxConfig, imageConfig, _ := getCreateContainerTestData()
|
||||||
|
|
||||||
for desc, test := range map[string]struct {
|
for desc, test := range map[string]struct {
|
||||||
privileged bool
|
privileged bool
|
||||||
expectedSysFSRO bool
|
expectedSysFSRO bool
|
||||||
@ -778,15 +784,13 @@ func TestPrivilegedBindMount(t *testing.T) {
|
|||||||
},
|
},
|
||||||
} {
|
} {
|
||||||
t.Logf("TestCase %q", desc)
|
t.Logf("TestCase %q", desc)
|
||||||
og, err := generate.New("linux")
|
|
||||||
|
config.Linux.SecurityContext.Privileged = test.privileged
|
||||||
|
sandboxConfig.Linux.SecurityContext.Privileged = test.privileged
|
||||||
|
|
||||||
|
spec, err := c.generateContainerSpec(t.Name(), testSandboxID, testPid, config, sandboxConfig, imageConfig, nil, nil)
|
||||||
|
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
g := newCustomGenerator(og)
|
|
||||||
c := newTestCRIService()
|
|
||||||
c.addOCIBindMounts(&g, nil, "")
|
|
||||||
if test.privileged {
|
|
||||||
setOCIBindMountsPrivileged(&g)
|
|
||||||
}
|
|
||||||
spec := g.Config
|
|
||||||
if test.expectedSysFSRO {
|
if test.expectedSysFSRO {
|
||||||
checkMount(t, spec.Mounts, "sysfs", "/sys", "sysfs", []string{"ro"}, []string{"rw"})
|
checkMount(t, spec.Mounts, "sysfs", "/sys", "sysfs", []string{"ro"}, []string{"rw"})
|
||||||
} else {
|
} else {
|
||||||
@ -801,6 +805,7 @@ func TestPrivilegedBindMount(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestMountPropagation(t *testing.T) {
|
func TestMountPropagation(t *testing.T) {
|
||||||
|
|
||||||
sharedLookupMountFn := func(string) (mount.Info, error) {
|
sharedLookupMountFn := func(string) (mount.Info, error) {
|
||||||
return mount.Info{
|
return mount.Info{
|
||||||
Mountpoint: "host-path",
|
Mountpoint: "host-path",
|
||||||
@ -888,17 +893,19 @@ func TestMountPropagation(t *testing.T) {
|
|||||||
},
|
},
|
||||||
} {
|
} {
|
||||||
t.Logf("TestCase %q", desc)
|
t.Logf("TestCase %q", desc)
|
||||||
og, err := generate.New("linux")
|
|
||||||
assert.NoError(t, err)
|
|
||||||
g := newCustomGenerator(og)
|
|
||||||
c := newTestCRIService()
|
c := newTestCRIService()
|
||||||
c.os.(*ostesting.FakeOS).LookupMountFn = test.fakeLookupMountFn
|
c.os.(*ostesting.FakeOS).LookupMountFn = test.fakeLookupMountFn
|
||||||
err = c.addOCIBindMounts(&g, []*runtime.Mount{test.criMount}, "")
|
config, _, _, _ := getCreateContainerTestData()
|
||||||
|
|
||||||
|
var spec runtimespec.Spec
|
||||||
|
spec.Linux = &runtimespec.Linux{}
|
||||||
|
|
||||||
|
err := opts.WithMounts(c.os, config, []*runtime.Mount{test.criMount}, "")(nil, nil, nil, &spec)
|
||||||
if test.expectErr {
|
if test.expectErr {
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
} else {
|
} else {
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
checkMount(t, g.Config.Mounts, test.criMount.HostPath, test.criMount.ContainerPath, "bind", test.optionsCheck, nil)
|
checkMount(t, spec.Mounts, test.criMount.HostPath, test.criMount.ContainerPath, "bind", test.optionsCheck, nil)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -917,7 +924,7 @@ func TestPidNamespace(t *testing.T) {
|
|||||||
pidNS: runtime.NamespaceMode_NODE,
|
pidNS: runtime.NamespaceMode_NODE,
|
||||||
expected: runtimespec.LinuxNamespace{
|
expected: runtimespec.LinuxNamespace{
|
||||||
Type: runtimespec.PIDNamespace,
|
Type: runtimespec.PIDNamespace,
|
||||||
Path: getPIDNamespace(testPid),
|
Path: opts.GetPIDNamespace(testPid),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"container namespace mode": {
|
"container namespace mode": {
|
||||||
@ -930,7 +937,7 @@ func TestPidNamespace(t *testing.T) {
|
|||||||
pidNS: runtime.NamespaceMode_POD,
|
pidNS: runtime.NamespaceMode_POD,
|
||||||
expected: runtimespec.LinuxNamespace{
|
expected: runtimespec.LinuxNamespace{
|
||||||
Type: runtimespec.PIDNamespace,
|
Type: runtimespec.PIDNamespace,
|
||||||
Path: getPIDNamespace(testPid),
|
Path: opts.GetPIDNamespace(testPid),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
} {
|
} {
|
||||||
@ -942,8 +949,14 @@ func TestPidNamespace(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDefaultRuntimeSpec(t *testing.T) {
|
func TestNoDefaultRunMount(t *testing.T) {
|
||||||
spec, err := defaultRuntimeSpec("test-id")
|
testID := "test-id"
|
||||||
|
testPid := uint32(1234)
|
||||||
|
testSandboxID := "sandbox-id"
|
||||||
|
config, sandboxConfig, imageConfig, _ := getCreateContainerTestData()
|
||||||
|
c := newTestCRIService()
|
||||||
|
|
||||||
|
spec, err := c.generateContainerSpec(testID, testSandboxID, testPid, config, sandboxConfig, imageConfig, nil, nil)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
for _, mount := range spec.Mounts {
|
for _, mount := range spec.Mounts {
|
||||||
assert.NotEqual(t, "/run", mount.Destination)
|
assert.NotEqual(t, "/run", mount.Destination)
|
||||||
@ -1079,8 +1092,10 @@ func TestMaskedAndReadonlyPaths(t *testing.T) {
|
|||||||
testPid := uint32(1234)
|
testPid := uint32(1234)
|
||||||
config, sandboxConfig, imageConfig, specCheck := getCreateContainerTestData()
|
config, sandboxConfig, imageConfig, specCheck := getCreateContainerTestData()
|
||||||
c := newTestCRIService()
|
c := newTestCRIService()
|
||||||
defaultSpec, err := defaultRuntimeSpec(testID)
|
|
||||||
|
defaultSpec, err := c.generateContainerSpec(testID, testSandboxID, testPid, config, sandboxConfig, imageConfig, nil, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
for desc, test := range map[string]struct {
|
for desc, test := range map[string]struct {
|
||||||
masked []string
|
masked []string
|
||||||
readonly []string
|
readonly []string
|
||||||
@ -1096,8 +1111,8 @@ func TestMaskedAndReadonlyPaths(t *testing.T) {
|
|||||||
"should be able to specify empty paths": {
|
"should be able to specify empty paths": {
|
||||||
masked: []string{},
|
masked: []string{},
|
||||||
readonly: []string{},
|
readonly: []string{},
|
||||||
expectedMasked: nil,
|
expectedMasked: []string{},
|
||||||
expectedReadonly: nil,
|
expectedReadonly: []string{},
|
||||||
privileged: false,
|
privileged: false,
|
||||||
},
|
},
|
||||||
"should apply CRI specified paths": {
|
"should apply CRI specified paths": {
|
||||||
|
@ -24,6 +24,7 @@ import (
|
|||||||
"github.com/containerd/containerd"
|
"github.com/containerd/containerd"
|
||||||
containerdio "github.com/containerd/containerd/cio"
|
containerdio "github.com/containerd/containerd/cio"
|
||||||
"github.com/containerd/containerd/errdefs"
|
"github.com/containerd/containerd/errdefs"
|
||||||
|
"github.com/containerd/containerd/oci"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
@ -99,14 +100,16 @@ func (c *criService) execInContainer(ctx context.Context, id string, opts execOp
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "failed to load task")
|
return nil, errors.Wrap(err, "failed to load task")
|
||||||
}
|
}
|
||||||
if opts.tty {
|
|
||||||
g := newSpecGenerator(spec)
|
|
||||||
g.AddProcessEnv("TERM", "xterm")
|
|
||||||
spec = g.Config
|
|
||||||
}
|
|
||||||
pspec := spec.Process
|
pspec := spec.Process
|
||||||
pspec.Args = opts.cmd
|
|
||||||
pspec.Terminal = opts.tty
|
pspec.Terminal = opts.tty
|
||||||
|
if opts.tty {
|
||||||
|
if err := oci.WithEnv([]string{"TERM=xterm"})(nil, nil, nil, spec); err != nil {
|
||||||
|
return nil, errors.Wrap(err, "add TERM env var to spec")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pspec.Args = opts.cmd
|
||||||
|
|
||||||
if opts.stdout == nil {
|
if opts.stdout == nil {
|
||||||
opts.stdout = cio.NewDiscardLogger()
|
opts.stdout = cio.NewDiscardLogger()
|
||||||
|
@ -29,6 +29,7 @@ import (
|
|||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
|
runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
|
||||||
|
|
||||||
|
"github.com/containerd/cri/pkg/containerd/opts"
|
||||||
ctrdutil "github.com/containerd/cri/pkg/containerd/util"
|
ctrdutil "github.com/containerd/cri/pkg/containerd/util"
|
||||||
containerstore "github.com/containerd/cri/pkg/store/container"
|
containerstore "github.com/containerd/cri/pkg/store/container"
|
||||||
"github.com/containerd/cri/pkg/util"
|
"github.com/containerd/cri/pkg/util"
|
||||||
@ -135,27 +136,11 @@ func updateOCILinuxResource(spec *runtimespec.Spec, new *runtime.LinuxContainerR
|
|||||||
if err := util.DeepCopy(&cloned, spec); err != nil {
|
if err := util.DeepCopy(&cloned, spec); err != nil {
|
||||||
return nil, errors.Wrap(err, "failed to deep copy")
|
return nil, errors.Wrap(err, "failed to deep copy")
|
||||||
}
|
}
|
||||||
g := newSpecGenerator(&cloned)
|
if cloned.Linux == nil {
|
||||||
|
cloned.Linux = &runtimespec.Linux{}
|
||||||
if new.GetCpuPeriod() != 0 {
|
|
||||||
g.SetLinuxResourcesCPUPeriod(uint64(new.GetCpuPeriod()))
|
|
||||||
}
|
}
|
||||||
if new.GetCpuQuota() != 0 {
|
if err := opts.WithResources(new)(nil, nil, nil, &cloned); err != nil {
|
||||||
g.SetLinuxResourcesCPUQuota(new.GetCpuQuota())
|
return nil, errors.Wrap(err, "unable to set linux container resources")
|
||||||
}
|
}
|
||||||
if new.GetCpuShares() != 0 {
|
return &cloned, nil
|
||||||
g.SetLinuxResourcesCPUShares(uint64(new.GetCpuShares()))
|
|
||||||
}
|
|
||||||
if new.GetMemoryLimitInBytes() != 0 {
|
|
||||||
g.SetLinuxResourcesMemoryLimit(new.GetMemoryLimitInBytes())
|
|
||||||
}
|
|
||||||
// OOMScore is not updatable.
|
|
||||||
if new.GetCpusetCpus() != "" {
|
|
||||||
g.SetLinuxResourcesCPUCpus(new.GetCpusetCpus())
|
|
||||||
}
|
|
||||||
if new.GetCpusetMems() != "" {
|
|
||||||
g.SetLinuxResourcesCPUMems(new.GetCpusetMems())
|
|
||||||
}
|
|
||||||
|
|
||||||
return g.Config, nil
|
|
||||||
}
|
}
|
||||||
|
@ -18,8 +18,6 @@ package server
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
|
||||||
"path"
|
"path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"regexp"
|
"regexp"
|
||||||
@ -36,8 +34,6 @@ import (
|
|||||||
"github.com/containerd/typeurl"
|
"github.com/containerd/typeurl"
|
||||||
"github.com/docker/distribution/reference"
|
"github.com/docker/distribution/reference"
|
||||||
imagedigest "github.com/opencontainers/go-digest"
|
imagedigest "github.com/opencontainers/go-digest"
|
||||||
runtimespec "github.com/opencontainers/runtime-spec/specs-go"
|
|
||||||
"github.com/opencontainers/runtime-tools/generate"
|
|
||||||
"github.com/opencontainers/selinux/go-selinux"
|
"github.com/opencontainers/selinux/go-selinux"
|
||||||
"github.com/opencontainers/selinux/go-selinux/label"
|
"github.com/opencontainers/selinux/go-selinux/label"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
@ -69,8 +65,6 @@ const (
|
|||||||
const (
|
const (
|
||||||
// defaultSandboxOOMAdj is default omm adj for sandbox container. (kubernetes#47938).
|
// defaultSandboxOOMAdj is default omm adj for sandbox container. (kubernetes#47938).
|
||||||
defaultSandboxOOMAdj = -998
|
defaultSandboxOOMAdj = -998
|
||||||
// defaultSandboxCPUshares is default cpu shares for sandbox container.
|
|
||||||
defaultSandboxCPUshares = 2
|
|
||||||
// defaultShmSize is the default size of the sandbox shm.
|
// defaultShmSize is the default size of the sandbox shm.
|
||||||
defaultShmSize = int64(1024 * 1024 * 64)
|
defaultShmSize = int64(1024 * 1024 * 64)
|
||||||
// relativeRootfsPath is the rootfs path relative to bundle path.
|
// relativeRootfsPath is the rootfs path relative to bundle path.
|
||||||
@ -86,14 +80,6 @@ const (
|
|||||||
maxDNSSearches = 6
|
maxDNSSearches = 6
|
||||||
// Delimiter used to construct container/sandbox names.
|
// Delimiter used to construct container/sandbox names.
|
||||||
nameDelimiter = "_"
|
nameDelimiter = "_"
|
||||||
// netNSFormat is the format of network namespace of a process.
|
|
||||||
netNSFormat = "/proc/%v/ns/net"
|
|
||||||
// ipcNSFormat is the format of ipc namespace of a process.
|
|
||||||
ipcNSFormat = "/proc/%v/ns/ipc"
|
|
||||||
// utsNSFormat is the format of uts namespace of a process.
|
|
||||||
utsNSFormat = "/proc/%v/ns/uts"
|
|
||||||
// pidNSFormat is the format of pid namespace of a process.
|
|
||||||
pidNSFormat = "/proc/%v/ns/pid"
|
|
||||||
// devShm is the default path of /dev/shm.
|
// devShm is the default path of /dev/shm.
|
||||||
devShm = "/dev/shm"
|
devShm = "/dev/shm"
|
||||||
// etcHosts is the default path of /etc/hosts file.
|
// etcHosts is the default path of /etc/hosts file.
|
||||||
@ -220,26 +206,6 @@ func (c *criService) getSandboxDevShm(id string) string {
|
|||||||
return filepath.Join(c.getVolatileSandboxRootDir(id), "shm")
|
return filepath.Join(c.getVolatileSandboxRootDir(id), "shm")
|
||||||
}
|
}
|
||||||
|
|
||||||
// getNetworkNamespace returns the network namespace of a process.
|
|
||||||
func getNetworkNamespace(pid uint32) string {
|
|
||||||
return fmt.Sprintf(netNSFormat, pid)
|
|
||||||
}
|
|
||||||
|
|
||||||
// getIPCNamespace returns the ipc namespace of a process.
|
|
||||||
func getIPCNamespace(pid uint32) string {
|
|
||||||
return fmt.Sprintf(ipcNSFormat, pid)
|
|
||||||
}
|
|
||||||
|
|
||||||
// getUTSNamespace returns the uts namespace of a process.
|
|
||||||
func getUTSNamespace(pid uint32) string {
|
|
||||||
return fmt.Sprintf(utsNSFormat, pid)
|
|
||||||
}
|
|
||||||
|
|
||||||
// getPIDNamespace returns the pid namespace of a process.
|
|
||||||
func getPIDNamespace(pid uint32) string {
|
|
||||||
return fmt.Sprintf(pidNSFormat, pid)
|
|
||||||
}
|
|
||||||
|
|
||||||
// criContainerStateToString formats CRI container state to string.
|
// criContainerStateToString formats CRI container state to string.
|
||||||
func criContainerStateToString(state runtime.ContainerState) string {
|
func criContainerStateToString(state runtime.ContainerState) string {
|
||||||
return runtime.ContainerState_name[int32(state)]
|
return runtime.ContainerState_name[int32(state)]
|
||||||
@ -397,54 +363,6 @@ func buildLabels(configLabels map[string]string, containerType string) map[strin
|
|||||||
return labels
|
return labels
|
||||||
}
|
}
|
||||||
|
|
||||||
// newSpecGenerator creates a new spec generator for the runtime spec.
|
|
||||||
func newSpecGenerator(spec *runtimespec.Spec) generator {
|
|
||||||
g := generate.NewFromSpec(spec)
|
|
||||||
g.HostSpecific = true
|
|
||||||
return newCustomGenerator(g)
|
|
||||||
}
|
|
||||||
|
|
||||||
// generator is a custom generator with some functions overridden
|
|
||||||
// used by the cri plugin.
|
|
||||||
// TODO(random-liu): Upstream this fix.
|
|
||||||
type generator struct {
|
|
||||||
generate.Generator
|
|
||||||
envCache map[string]int
|
|
||||||
}
|
|
||||||
|
|
||||||
func newCustomGenerator(g generate.Generator) generator {
|
|
||||||
cg := generator{
|
|
||||||
Generator: g,
|
|
||||||
envCache: make(map[string]int),
|
|
||||||
}
|
|
||||||
if g.Config != nil && g.Config.Process != nil {
|
|
||||||
for i, env := range g.Config.Process.Env {
|
|
||||||
kv := strings.SplitN(env, "=", 2)
|
|
||||||
cg.envCache[kv[0]] = i
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return cg
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddProcessEnv overrides the original AddProcessEnv. It uses
|
|
||||||
// a map to cache and override envs.
|
|
||||||
func (g *generator) AddProcessEnv(key, value string) {
|
|
||||||
if len(g.envCache) == 0 {
|
|
||||||
// Call AddProccessEnv once to initialize the spec.
|
|
||||||
g.Generator.AddProcessEnv(key, value)
|
|
||||||
g.envCache[key] = 0
|
|
||||||
return
|
|
||||||
}
|
|
||||||
spec := g.Config
|
|
||||||
env := fmt.Sprintf("%s=%s", key, value)
|
|
||||||
if idx, ok := g.envCache[key]; !ok {
|
|
||||||
spec.Process.Env = append(spec.Process.Env, env)
|
|
||||||
g.envCache[key] = len(spec.Process.Env) - 1
|
|
||||||
} else {
|
|
||||||
spec.Process.Env[idx] = env
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func getPodCNILabels(id string, config *runtime.PodSandboxConfig) map[string]string {
|
func getPodCNILabels(id string, config *runtime.PodSandboxConfig) map[string]string {
|
||||||
return map[string]string{
|
return map[string]string{
|
||||||
"K8S_POD_NAMESPACE": config.GetMetadata().GetNamespace(),
|
"K8S_POD_NAMESPACE": config.GetMetadata().GetNamespace(),
|
||||||
@ -464,33 +382,6 @@ func toRuntimeAuthConfig(a criconfig.AuthConfig) *runtime.AuthConfig {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// mounts defines how to sort runtime.Mount.
|
|
||||||
// This is the same with the Docker implementation:
|
|
||||||
// https://github.com/moby/moby/blob/17.05.x/daemon/volumes.go#L26
|
|
||||||
type orderedMounts []*runtime.Mount
|
|
||||||
|
|
||||||
// Len returns the number of mounts. Used in sorting.
|
|
||||||
func (m orderedMounts) Len() int {
|
|
||||||
return len(m)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Less returns true if the number of parts (a/b/c would be 3 parts) in the
|
|
||||||
// mount indexed by parameter 1 is less than that of the mount indexed by
|
|
||||||
// parameter 2. Used in sorting.
|
|
||||||
func (m orderedMounts) Less(i, j int) bool {
|
|
||||||
return m.parts(i) < m.parts(j)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Swap swaps two items in an array of mounts. Used in sorting
|
|
||||||
func (m orderedMounts) Swap(i, j int) {
|
|
||||||
m[i], m[j] = m[j], m[i]
|
|
||||||
}
|
|
||||||
|
|
||||||
// parts returns the number of parts in the destination of a mount. Used in sorting.
|
|
||||||
func (m orderedMounts) parts(i int) int {
|
|
||||||
return strings.Count(filepath.Clean(m[i].ContainerPath), string(os.PathSeparator))
|
|
||||||
}
|
|
||||||
|
|
||||||
// parseImageReferences parses a list of arbitrary image references and returns
|
// parseImageReferences parses a list of arbitrary image references and returns
|
||||||
// the repotags and repodigests
|
// the repotags and repodigests
|
||||||
func parseImageReferences(refs []string) ([]string, []string) {
|
func parseImageReferences(refs []string) ([]string, []string) {
|
||||||
@ -553,30 +444,6 @@ func getRuntimeOptions(c containers.Container) (interface{}, error) {
|
|||||||
return opts, nil
|
return opts, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getCurrentOOMScoreAdj() (int, error) {
|
|
||||||
b, err := ioutil.ReadFile("/proc/self/oom_score_adj")
|
|
||||||
if err != nil {
|
|
||||||
return 0, errors.Wrap(err, "could not get the daemon oom_score_adj")
|
|
||||||
}
|
|
||||||
s := strings.TrimSpace(string(b))
|
|
||||||
i, err := strconv.Atoi(s)
|
|
||||||
if err != nil {
|
|
||||||
return 0, errors.Wrap(err, "could not get the daemon oom_score_adj")
|
|
||||||
}
|
|
||||||
return i, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func restrictOOMScoreAdj(preferredOOMScoreAdj int) (int, error) {
|
|
||||||
currentOOMScoreAdj, err := getCurrentOOMScoreAdj()
|
|
||||||
if err != nil {
|
|
||||||
return preferredOOMScoreAdj, err
|
|
||||||
}
|
|
||||||
if preferredOOMScoreAdj < currentOOMScoreAdj {
|
|
||||||
return currentOOMScoreAdj, nil
|
|
||||||
}
|
|
||||||
return preferredOOMScoreAdj, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// unknownExitCode is the exit code when exit reason is unknown.
|
// unknownExitCode is the exit code when exit reason is unknown.
|
||||||
unknownExitCode = 255
|
unknownExitCode = 255
|
||||||
|
@ -17,10 +17,10 @@ limitations under the License.
|
|||||||
package server
|
package server
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"sort"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/BurntSushi/toml"
|
"github.com/BurntSushi/toml"
|
||||||
|
"github.com/containerd/containerd/oci"
|
||||||
"github.com/containerd/containerd/runtime/linux/runctypes"
|
"github.com/containerd/containerd/runtime/linux/runctypes"
|
||||||
runcoptions "github.com/containerd/containerd/runtime/v2/runc/options"
|
runcoptions "github.com/containerd/containerd/runtime/v2/runc/options"
|
||||||
"github.com/docker/distribution/reference"
|
"github.com/docker/distribution/reference"
|
||||||
@ -28,7 +28,6 @@ import (
|
|||||||
runtimespec "github.com/opencontainers/runtime-spec/specs-go"
|
runtimespec "github.com/opencontainers/runtime-spec/specs-go"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
|
|
||||||
|
|
||||||
criconfig "github.com/containerd/cri/pkg/config"
|
criconfig "github.com/containerd/cri/pkg/config"
|
||||||
"github.com/containerd/cri/pkg/store"
|
"github.com/containerd/cri/pkg/store"
|
||||||
@ -153,27 +152,6 @@ func TestBuildLabels(t *testing.T) {
|
|||||||
assert.Equal(t, "b", configLabels["a"], "change in new labels should not affect original label")
|
assert.Equal(t, "b", configLabels["a"], "change in new labels should not affect original label")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestOrderedMounts(t *testing.T) {
|
|
||||||
mounts := []*runtime.Mount{
|
|
||||||
{ContainerPath: "/a/b/c"},
|
|
||||||
{ContainerPath: "/a/b"},
|
|
||||||
{ContainerPath: "/a/b/c/d"},
|
|
||||||
{ContainerPath: "/a"},
|
|
||||||
{ContainerPath: "/b"},
|
|
||||||
{ContainerPath: "/b/c"},
|
|
||||||
}
|
|
||||||
expected := []*runtime.Mount{
|
|
||||||
{ContainerPath: "/a"},
|
|
||||||
{ContainerPath: "/b"},
|
|
||||||
{ContainerPath: "/a/b"},
|
|
||||||
{ContainerPath: "/b/c"},
|
|
||||||
{ContainerPath: "/a/b/c"},
|
|
||||||
{ContainerPath: "/a/b/c/d"},
|
|
||||||
}
|
|
||||||
sort.Stable(orderedMounts(mounts))
|
|
||||||
assert.Equal(t, expected, mounts)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestParseImageReferences(t *testing.T) {
|
func TestParseImageReferences(t *testing.T) {
|
||||||
refs := []string{
|
refs := []string{
|
||||||
"gcr.io/library/busybox@sha256:e6693c20186f837fc393390135d8a598a96a833917917789d63766cab6c59582",
|
"gcr.io/library/busybox@sha256:e6693c20186f837fc393390135d8a598a96a833917917789d63766cab6c59582",
|
||||||
@ -306,33 +284,12 @@ systemd_cgroup = true
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRestrictOOMScoreAdj(t *testing.T) {
|
func TestEnvDeduplication(t *testing.T) {
|
||||||
current, err := getCurrentOOMScoreAdj()
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
got, err := restrictOOMScoreAdj(current - 1)
|
|
||||||
require.NoError(t, err)
|
|
||||||
assert.Equal(t, got, current)
|
|
||||||
|
|
||||||
got, err = restrictOOMScoreAdj(current)
|
|
||||||
require.NoError(t, err)
|
|
||||||
assert.Equal(t, got, current)
|
|
||||||
|
|
||||||
got, err = restrictOOMScoreAdj(current + 1)
|
|
||||||
require.NoError(t, err)
|
|
||||||
assert.Equal(t, got, current+1)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestCustomGenerator(t *testing.T) {
|
|
||||||
for desc, test := range map[string]struct {
|
for desc, test := range map[string]struct {
|
||||||
existing []string
|
existing []string
|
||||||
kv [][2]string
|
kv [][2]string
|
||||||
expected []string
|
expected []string
|
||||||
expectNil bool
|
|
||||||
}{
|
}{
|
||||||
"empty": {
|
|
||||||
expectNil: true,
|
|
||||||
},
|
|
||||||
"single env": {
|
"single env": {
|
||||||
kv: [][2]string{
|
kv: [][2]string{
|
||||||
{"a", "b"},
|
{"a", "b"},
|
||||||
@ -387,23 +344,16 @@ func TestCustomGenerator(t *testing.T) {
|
|||||||
},
|
},
|
||||||
} {
|
} {
|
||||||
t.Logf("TestCase %q", desc)
|
t.Logf("TestCase %q", desc)
|
||||||
var spec *runtimespec.Spec
|
var spec runtimespec.Spec
|
||||||
if len(test.existing) > 0 {
|
if len(test.existing) > 0 {
|
||||||
spec = &runtimespec.Spec{
|
spec.Process = &runtimespec.Process{
|
||||||
Process: &runtimespec.Process{
|
Env: test.existing,
|
||||||
Env: test.existing,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
g := newSpecGenerator(spec)
|
|
||||||
for _, kv := range test.kv {
|
for _, kv := range test.kv {
|
||||||
g.AddProcessEnv(kv[0], kv[1])
|
oci.WithEnv([]string{kv[0] + "=" + kv[1]})(nil, nil, nil, &spec)
|
||||||
}
|
|
||||||
if test.expectNil {
|
|
||||||
assert.Nil(t, g.Config)
|
|
||||||
} else {
|
|
||||||
assert.Equal(t, test.expected, g.Config.Process.Env)
|
|
||||||
}
|
}
|
||||||
|
assert.Equal(t, test.expected, spec.Process.Env)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -343,67 +343,61 @@ func (c *criService) generateSandboxContainerSpec(id string, config *runtime.Pod
|
|||||||
imageConfig *imagespec.ImageConfig, nsPath string, runtimePodAnnotations []string) (*runtimespec.Spec, error) {
|
imageConfig *imagespec.ImageConfig, nsPath string, runtimePodAnnotations []string) (*runtimespec.Spec, error) {
|
||||||
// Creates a spec Generator with the default spec.
|
// Creates a spec Generator with the default spec.
|
||||||
// TODO(random-liu): [P1] Compare the default settings with docker and containerd default.
|
// TODO(random-liu): [P1] Compare the default settings with docker and containerd default.
|
||||||
spec, err := defaultRuntimeSpec(id)
|
specOpts := []oci.SpecOpts{
|
||||||
if err != nil {
|
customopts.WithoutRunMount,
|
||||||
return nil, err
|
customopts.WithoutDefaultSecuritySettings,
|
||||||
|
customopts.WithRelativeRoot(relativeRootfsPath),
|
||||||
|
oci.WithEnv(imageConfig.Env),
|
||||||
|
oci.WithRootFSReadonly(),
|
||||||
|
oci.WithHostname(config.GetHostname()),
|
||||||
}
|
}
|
||||||
g := newSpecGenerator(spec)
|
|
||||||
|
|
||||||
// Apply default config from image config.
|
|
||||||
if err := addImageEnvs(&g, imageConfig.Env); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if imageConfig.WorkingDir != "" {
|
if imageConfig.WorkingDir != "" {
|
||||||
g.SetProcessCwd(imageConfig.WorkingDir)
|
specOpts = append(specOpts, oci.WithProcessCwd(imageConfig.WorkingDir))
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(imageConfig.Entrypoint) == 0 && len(imageConfig.Cmd) == 0 {
|
if len(imageConfig.Entrypoint) == 0 && len(imageConfig.Cmd) == 0 {
|
||||||
// Pause image must have entrypoint or cmd.
|
// Pause image must have entrypoint or cmd.
|
||||||
return nil, errors.Errorf("invalid empty entrypoint and cmd in image config %+v", imageConfig)
|
return nil, errors.Errorf("invalid empty entrypoint and cmd in image config %+v", imageConfig)
|
||||||
}
|
}
|
||||||
// Set process commands.
|
specOpts = append(specOpts, oci.WithProcessArgs(append(imageConfig.Entrypoint, imageConfig.Cmd...)...))
|
||||||
g.SetProcessArgs(append(imageConfig.Entrypoint, imageConfig.Cmd...))
|
|
||||||
|
|
||||||
// Set relative root path.
|
|
||||||
g.SetRootPath(relativeRootfsPath)
|
|
||||||
|
|
||||||
// Make root of sandbox container read-only.
|
|
||||||
g.SetRootReadonly(true)
|
|
||||||
|
|
||||||
// Set hostname.
|
|
||||||
g.SetHostname(config.GetHostname())
|
|
||||||
|
|
||||||
// TODO(random-liu): [P2] Consider whether to add labels and annotations to the container.
|
// TODO(random-liu): [P2] Consider whether to add labels and annotations to the container.
|
||||||
|
|
||||||
// Set cgroups parent.
|
// Set cgroups parent.
|
||||||
if c.config.DisableCgroup {
|
if c.config.DisableCgroup {
|
||||||
g.SetLinuxCgroupsPath("")
|
specOpts = append(specOpts, customopts.WithDisabledCgroups)
|
||||||
} else {
|
} else {
|
||||||
if config.GetLinux().GetCgroupParent() != "" {
|
if config.GetLinux().GetCgroupParent() != "" {
|
||||||
cgroupsPath := getCgroupsPath(config.GetLinux().GetCgroupParent(), id,
|
cgroupsPath := getCgroupsPath(config.GetLinux().GetCgroupParent(), id,
|
||||||
c.config.SystemdCgroup)
|
c.config.SystemdCgroup)
|
||||||
g.SetLinuxCgroupsPath(cgroupsPath)
|
specOpts = append(specOpts, oci.WithCgroup(cgroupsPath))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// When cgroup parent is not set, containerd-shim will create container in a child cgroup
|
// When cgroup parent is not set, containerd-shim will create container in a child cgroup
|
||||||
// of the cgroup itself is in.
|
// of the cgroup itself is in.
|
||||||
// TODO(random-liu): [P2] Set default cgroup path if cgroup parent is not specified.
|
// TODO(random-liu): [P2] Set default cgroup path if cgroup parent is not specified.
|
||||||
|
|
||||||
// Set namespace options.
|
// Set namespace options.
|
||||||
securityContext := config.GetLinux().GetSecurityContext()
|
var (
|
||||||
nsOptions := securityContext.GetNamespaceOptions()
|
securityContext = config.GetLinux().GetSecurityContext()
|
||||||
|
nsOptions = securityContext.GetNamespaceOptions()
|
||||||
|
)
|
||||||
if nsOptions.GetNetwork() == runtime.NamespaceMode_NODE {
|
if nsOptions.GetNetwork() == runtime.NamespaceMode_NODE {
|
||||||
g.RemoveLinuxNamespace(string(runtimespec.NetworkNamespace)) // nolint: errcheck
|
specOpts = append(specOpts, customopts.WithoutNamespace(runtimespec.NetworkNamespace))
|
||||||
} else {
|
} else {
|
||||||
//TODO(Abhi): May be move this to containerd spec opts (WithLinuxSpaceOption)
|
//TODO(Abhi): May be move this to containerd spec opts (WithLinuxSpaceOption)
|
||||||
g.AddOrReplaceLinuxNamespace(string(runtimespec.NetworkNamespace), nsPath) // nolint: errcheck
|
specOpts = append(specOpts, oci.WithLinuxNamespace(
|
||||||
|
runtimespec.LinuxNamespace{
|
||||||
|
Type: runtimespec.NetworkNamespace,
|
||||||
|
Path: nsPath,
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
if nsOptions.GetPid() == runtime.NamespaceMode_NODE {
|
if nsOptions.GetPid() == runtime.NamespaceMode_NODE {
|
||||||
g.RemoveLinuxNamespace(string(runtimespec.PIDNamespace)) // nolint: errcheck
|
specOpts = append(specOpts, customopts.WithoutNamespace(runtimespec.PIDNamespace))
|
||||||
}
|
}
|
||||||
if nsOptions.GetIpc() == runtime.NamespaceMode_NODE {
|
if nsOptions.GetIpc() == runtime.NamespaceMode_NODE {
|
||||||
g.RemoveLinuxNamespace(string(runtimespec.IPCNamespace)) // nolint: errcheck
|
specOpts = append(specOpts, customopts.WithoutNamespace(runtimespec.IPCNamespace))
|
||||||
}
|
}
|
||||||
|
|
||||||
// It's fine to generate the spec before the sandbox /dev/shm
|
// It's fine to generate the spec before the sandbox /dev/shm
|
||||||
@ -412,56 +406,50 @@ func (c *criService) generateSandboxContainerSpec(id string, config *runtime.Pod
|
|||||||
if nsOptions.GetIpc() == runtime.NamespaceMode_NODE {
|
if nsOptions.GetIpc() == runtime.NamespaceMode_NODE {
|
||||||
sandboxDevShm = devShm
|
sandboxDevShm = devShm
|
||||||
}
|
}
|
||||||
g.AddMount(runtimespec.Mount{
|
specOpts = append(specOpts, oci.WithMounts([]runtimespec.Mount{
|
||||||
Source: sandboxDevShm,
|
{
|
||||||
Destination: devShm,
|
Source: sandboxDevShm,
|
||||||
Type: "bind",
|
Destination: devShm,
|
||||||
Options: []string{"rbind", "ro"},
|
Type: "bind",
|
||||||
})
|
Options: []string{"rbind", "ro"},
|
||||||
|
},
|
||||||
|
}))
|
||||||
|
|
||||||
selinuxOpt := securityContext.GetSelinuxOptions()
|
selinuxOpt := securityContext.GetSelinuxOptions()
|
||||||
processLabel, mountLabel, err := initSelinuxOpts(selinuxOpt)
|
processLabel, mountLabel, err := initSelinuxOpts(selinuxOpt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(err, "failed to init selinux options %+v", securityContext.GetSelinuxOptions())
|
return nil, errors.Wrapf(err, "failed to init selinux options %+v", securityContext.GetSelinuxOptions())
|
||||||
}
|
}
|
||||||
g.SetProcessSelinuxLabel(processLabel)
|
|
||||||
g.SetLinuxMountLabel(mountLabel)
|
|
||||||
|
|
||||||
supplementalGroups := securityContext.GetSupplementalGroups()
|
supplementalGroups := securityContext.GetSupplementalGroups()
|
||||||
for _, group := range supplementalGroups {
|
specOpts = append(specOpts,
|
||||||
g.AddProcessAdditionalGid(uint32(group))
|
customopts.WithSelinuxLabels(processLabel, mountLabel),
|
||||||
}
|
customopts.WithSupplementalGroups(supplementalGroups),
|
||||||
|
)
|
||||||
|
|
||||||
// Add sysctls
|
// Add sysctls
|
||||||
sysctls := config.GetLinux().GetSysctls()
|
sysctls := config.GetLinux().GetSysctls()
|
||||||
for key, value := range sysctls {
|
specOpts = append(specOpts, customopts.WithSysctls(sysctls))
|
||||||
g.AddLinuxSysctl(key, value)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Note: LinuxSandboxSecurityContext does not currently provide an apparmor profile
|
// Note: LinuxSandboxSecurityContext does not currently provide an apparmor profile
|
||||||
|
|
||||||
if !c.config.DisableCgroup {
|
if !c.config.DisableCgroup {
|
||||||
g.SetLinuxResourcesCPUShares(uint64(defaultSandboxCPUshares))
|
specOpts = append(specOpts, customopts.WithDefaultSandboxShares)
|
||||||
}
|
}
|
||||||
adj := int(defaultSandboxOOMAdj)
|
specOpts = append(specOpts, customopts.WithPodOOMScoreAdj(int(defaultSandboxOOMAdj), c.config.RestrictOOMScoreAdj))
|
||||||
if c.config.RestrictOOMScoreAdj {
|
|
||||||
adj, err = restrictOOMScoreAdj(adj)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
g.SetProcessOOMScoreAdj(adj)
|
|
||||||
|
|
||||||
for pKey, pValue := range getPassthroughAnnotations(config.Annotations,
|
for pKey, pValue := range getPassthroughAnnotations(config.Annotations,
|
||||||
runtimePodAnnotations) {
|
runtimePodAnnotations) {
|
||||||
g.AddAnnotation(pKey, pValue)
|
specOpts = append(specOpts, customopts.WithAnnotation(pKey, pValue))
|
||||||
}
|
}
|
||||||
|
|
||||||
g.AddAnnotation(annotations.ContainerType, annotations.ContainerTypeSandbox)
|
specOpts = append(specOpts,
|
||||||
g.AddAnnotation(annotations.SandboxID, id)
|
customopts.WithAnnotation(annotations.ContainerType, annotations.ContainerTypeSandbox),
|
||||||
g.AddAnnotation(annotations.SandboxLogDir, config.GetLogDirectory())
|
customopts.WithAnnotation(annotations.SandboxID, id),
|
||||||
|
customopts.WithAnnotation(annotations.SandboxLogDir, config.GetLogDirectory()),
|
||||||
|
)
|
||||||
|
|
||||||
return g.Config, nil
|
return runtimeSpec(id, specOpts...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// setupSandboxFiles sets up necessary sandbox files including /dev/shm, /etc/hosts,
|
// setupSandboxFiles sets up necessary sandbox files including /dev/shm, /etc/hosts,
|
||||||
|
@ -32,6 +32,7 @@ import (
|
|||||||
|
|
||||||
"github.com/containerd/cri/pkg/annotations"
|
"github.com/containerd/cri/pkg/annotations"
|
||||||
criconfig "github.com/containerd/cri/pkg/config"
|
criconfig "github.com/containerd/cri/pkg/config"
|
||||||
|
"github.com/containerd/cri/pkg/containerd/opts"
|
||||||
ostesting "github.com/containerd/cri/pkg/os/testing"
|
ostesting "github.com/containerd/cri/pkg/os/testing"
|
||||||
sandboxstore "github.com/containerd/cri/pkg/store/sandbox"
|
sandboxstore "github.com/containerd/cri/pkg/store/sandbox"
|
||||||
)
|
)
|
||||||
@ -66,7 +67,7 @@ func getRunPodSandboxTestData() (*runtime.PodSandboxConfig, *imagespec.ImageConf
|
|||||||
assert.Contains(t, spec.Process.Env, "a=b", "c=d")
|
assert.Contains(t, spec.Process.Env, "a=b", "c=d")
|
||||||
assert.Equal(t, []string{"/pause", "forever"}, spec.Process.Args)
|
assert.Equal(t, []string{"/pause", "forever"}, spec.Process.Args)
|
||||||
assert.Equal(t, "/workspace", spec.Process.Cwd)
|
assert.Equal(t, "/workspace", spec.Process.Cwd)
|
||||||
assert.EqualValues(t, *spec.Linux.Resources.CPU.Shares, defaultSandboxCPUshares)
|
assert.EqualValues(t, *spec.Linux.Resources.CPU.Shares, opts.DefaultSandboxCPUshares)
|
||||||
assert.EqualValues(t, *spec.Process.OOMScoreAdj, defaultSandboxOOMAdj)
|
assert.EqualValues(t, *spec.Process.OOMScoreAdj, defaultSandboxOOMAdj)
|
||||||
|
|
||||||
t.Logf("Check PodSandbox annotations")
|
t.Logf("Check PodSandbox annotations")
|
||||||
@ -139,13 +140,6 @@ func TestGenerateSandboxContainerSpec(t *testing.T) {
|
|||||||
},
|
},
|
||||||
expectErr: true,
|
expectErr: true,
|
||||||
},
|
},
|
||||||
"should return error when env is invalid ": {
|
|
||||||
// Also covers addImageEnvs.
|
|
||||||
imageConfigChange: func(c *imagespec.ImageConfig) {
|
|
||||||
c.Env = []string{"a"}
|
|
||||||
},
|
|
||||||
expectErr: true,
|
|
||||||
},
|
|
||||||
"should set supplemental groups correctly": {
|
"should set supplemental groups correctly": {
|
||||||
configChange: func(c *runtime.PodSandboxConfig) {
|
configChange: func(c *runtime.PodSandboxConfig) {
|
||||||
c.Linux.SecurityContext = &runtime.LinuxSandboxSecurityContext{
|
c.Linux.SecurityContext = &runtime.LinuxSandboxSecurityContext{
|
||||||
|
11
vendor.conf
11
vendor.conf
@ -1,9 +1,8 @@
|
|||||||
github.com/beorn7/perks 4c0e84591b9aa9e6dcfdf3e020114cd81f89d5f9
|
github.com/beorn7/perks 4c0e84591b9aa9e6dcfdf3e020114cd81f89d5f9
|
||||||
github.com/blang/semver v3.1.0
|
|
||||||
github.com/BurntSushi/toml a368813c5e648fee92e5f6c30e3944ff9d5e8895
|
github.com/BurntSushi/toml a368813c5e648fee92e5f6c30e3944ff9d5e8895
|
||||||
github.com/containerd/cgroups 1152b960fcee041f50df15cdc67c29dbccf801ef
|
github.com/containerd/cgroups 1152b960fcee041f50df15cdc67c29dbccf801ef
|
||||||
github.com/containerd/console c12b1e7919c14469339a5d38f2f8ed9b64a9de23
|
github.com/containerd/console c12b1e7919c14469339a5d38f2f8ed9b64a9de23
|
||||||
github.com/containerd/containerd 4543e32a8b29e691e523ddc142f0c9068917df54
|
github.com/containerd/containerd c60a5fd19073636432c7318cee039f01f367ccd8
|
||||||
github.com/containerd/continuity bd77b46c8352f74eb12c85bdc01f4b90f69d66b4
|
github.com/containerd/continuity bd77b46c8352f74eb12c85bdc01f4b90f69d66b4
|
||||||
github.com/containerd/fifo 3d5202aec260678c48179c56f40e6f38a095738c
|
github.com/containerd/fifo 3d5202aec260678c48179c56f40e6f38a095738c
|
||||||
github.com/containerd/go-cni 40bcf8ec8acd7372be1d77031d585d5d8e561c90
|
github.com/containerd/go-cni 40bcf8ec8acd7372be1d77031d585d5d8e561c90
|
||||||
@ -27,8 +26,6 @@ github.com/gogo/protobuf v1.0.0
|
|||||||
github.com/golang/protobuf v1.1.0
|
github.com/golang/protobuf v1.1.0
|
||||||
github.com/google/gofuzz 44d81051d367757e1c7c6a5a86423ece9afcf63c
|
github.com/google/gofuzz 44d81051d367757e1c7c6a5a86423ece9afcf63c
|
||||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.1
|
github.com/grpc-ecosystem/go-grpc-prometheus v1.1
|
||||||
github.com/hashicorp/errwrap 7554cd9344cec97297fa6649b055a8c98c2a1e55
|
|
||||||
github.com/hashicorp/go-multierror ed905158d87462226a13fe39ddf685ea65f1c11f
|
|
||||||
github.com/json-iterator/go 1.1.5
|
github.com/json-iterator/go 1.1.5
|
||||||
github.com/matttproud/golang_protobuf_extensions v1.0.0
|
github.com/matttproud/golang_protobuf_extensions v1.0.0
|
||||||
github.com/Microsoft/go-winio v0.4.11
|
github.com/Microsoft/go-winio v0.4.11
|
||||||
@ -39,7 +36,6 @@ github.com/opencontainers/go-digest c9281466c8b2f606084ac71339773efd177436e7
|
|||||||
github.com/opencontainers/image-spec v1.0.1
|
github.com/opencontainers/image-spec v1.0.1
|
||||||
github.com/opencontainers/runc 12f6a991201fdb8f82579582d5e00e28fba06d0a
|
github.com/opencontainers/runc 12f6a991201fdb8f82579582d5e00e28fba06d0a
|
||||||
github.com/opencontainers/runtime-spec eba862dc2470385a233c7507392675cbeadf7353
|
github.com/opencontainers/runtime-spec eba862dc2470385a233c7507392675cbeadf7353
|
||||||
github.com/opencontainers/runtime-tools fb101d5d42ab9c040f7d0a004e78336e5d5cb197
|
|
||||||
github.com/opencontainers/selinux b6fa367ed7f534f9ba25391cc2d467085dbb445a
|
github.com/opencontainers/selinux b6fa367ed7f534f9ba25391cc2d467085dbb445a
|
||||||
github.com/pkg/errors v0.8.0
|
github.com/pkg/errors v0.8.0
|
||||||
github.com/pmezard/go-difflib v1.0.0
|
github.com/pmezard/go-difflib v1.0.0
|
||||||
@ -53,15 +49,12 @@ github.com/stretchr/testify v1.1.4
|
|||||||
github.com/syndtr/gocapability db04d3cc01c8b54962a58ec7e491717d06cfcc16
|
github.com/syndtr/gocapability db04d3cc01c8b54962a58ec7e491717d06cfcc16
|
||||||
github.com/tchap/go-patricia v2.2.6
|
github.com/tchap/go-patricia v2.2.6
|
||||||
github.com/urfave/cli 7bc6a0acffa589f415f88aca16cc1de5ffd66f9c
|
github.com/urfave/cli 7bc6a0acffa589f415f88aca16cc1de5ffd66f9c
|
||||||
github.com/xeipuuv/gojsonpointer 4e3ac2762d5f479393488629ee9370b50873b3a6
|
|
||||||
github.com/xeipuuv/gojsonreference bd5ef7bd5415a7ac448318e64f11a24cd21e594b
|
|
||||||
github.com/xeipuuv/gojsonschema 1d523034197ff1f222f6429836dd36a2457a1874
|
|
||||||
go.etcd.io/bbolt v1.3.1-etcd.8
|
go.etcd.io/bbolt v1.3.1-etcd.8
|
||||||
golang.org/x/crypto 49796115aa4b964c318aad4f3084fdb41e9aa067
|
golang.org/x/crypto 49796115aa4b964c318aad4f3084fdb41e9aa067
|
||||||
golang.org/x/net b3756b4b77d7b13260a0a2ec658753cf48922eac
|
golang.org/x/net b3756b4b77d7b13260a0a2ec658753cf48922eac
|
||||||
golang.org/x/oauth2 a6bd8cefa1811bd24b86f8902872e4e8225f74c4
|
golang.org/x/oauth2 a6bd8cefa1811bd24b86f8902872e4e8225f74c4
|
||||||
golang.org/x/sync 42b317875d0fa942474b76e1b46a6060d720ae6e
|
golang.org/x/sync 42b317875d0fa942474b76e1b46a6060d720ae6e
|
||||||
golang.org/x/sys 1b2967e3c290b7c545b3db0deeda16e9be4f98a2 https://github.com/golang/sys
|
golang.org/x/sys d455e41777fca6e8a5a79e34a14b8368bc11d9ba https://github.com/golang/sys
|
||||||
golang.org/x/text 19e51611da83d6be54ddafce4a4af510cb3e9ea4
|
golang.org/x/text 19e51611da83d6be54ddafce4a4af510cb3e9ea4
|
||||||
golang.org/x/time f51c12702a4d776e4c1fa9b0fabab841babae631
|
golang.org/x/time f51c12702a4d776e4c1fa9b0fabab841babae631
|
||||||
google.golang.org/genproto d80a6e20e776b0b17a324d0ba1ab50a39c8e8944
|
google.golang.org/genproto d80a6e20e776b0b17a324d0ba1ab50a39c8e8944
|
||||||
|
22
vendor/github.com/blang/semver/LICENSE
generated
vendored
22
vendor/github.com/blang/semver/LICENSE
generated
vendored
@ -1,22 +0,0 @@
|
|||||||
The MIT License
|
|
||||||
|
|
||||||
Copyright (c) 2014 Benedikt Lang <github at benediktlang.de>
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in
|
|
||||||
all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
THE SOFTWARE.
|
|
||||||
|
|
191
vendor/github.com/blang/semver/README.md
generated
vendored
191
vendor/github.com/blang/semver/README.md
generated
vendored
@ -1,191 +0,0 @@
|
|||||||
semver for golang [](https://drone.io/github.com/blang/semver/latest) [](https://godoc.org/github.com/blang/semver) [](https://coveralls.io/r/blang/semver?branch=master)
|
|
||||||
======
|
|
||||||
|
|
||||||
semver is a [Semantic Versioning](http://semver.org/) library written in golang. It fully covers spec version `2.0.0`.
|
|
||||||
|
|
||||||
Usage
|
|
||||||
-----
|
|
||||||
```bash
|
|
||||||
$ go get github.com/blang/semver
|
|
||||||
```
|
|
||||||
Note: Always vendor your dependencies or fix on a specific version tag.
|
|
||||||
|
|
||||||
```go
|
|
||||||
import github.com/blang/semver
|
|
||||||
v1, err := semver.Make("1.0.0-beta")
|
|
||||||
v2, err := semver.Make("2.0.0-beta")
|
|
||||||
v1.Compare(v2)
|
|
||||||
```
|
|
||||||
|
|
||||||
Also check the [GoDocs](http://godoc.org/github.com/blang/semver).
|
|
||||||
|
|
||||||
Why should I use this lib?
|
|
||||||
-----
|
|
||||||
|
|
||||||
- Fully spec compatible
|
|
||||||
- No reflection
|
|
||||||
- No regex
|
|
||||||
- Fully tested (Coverage >99%)
|
|
||||||
- Readable parsing/validation errors
|
|
||||||
- Fast (See [Benchmarks](#benchmarks))
|
|
||||||
- Only Stdlib
|
|
||||||
- Uses values instead of pointers
|
|
||||||
- Many features, see below
|
|
||||||
|
|
||||||
|
|
||||||
Features
|
|
||||||
-----
|
|
||||||
|
|
||||||
- Parsing and validation at all levels
|
|
||||||
- Comparator-like comparisons
|
|
||||||
- Compare Helper Methods
|
|
||||||
- InPlace manipulation
|
|
||||||
- Ranges `>=1.0.0 <2.0.0 || >=3.0.0 !3.0.1-beta.1`
|
|
||||||
- Sortable (implements sort.Interface)
|
|
||||||
- database/sql compatible (sql.Scanner/Valuer)
|
|
||||||
- encoding/json compatible (json.Marshaler/Unmarshaler)
|
|
||||||
|
|
||||||
Ranges
|
|
||||||
------
|
|
||||||
|
|
||||||
A `Range` is a set of conditions which specify which versions satisfy the range.
|
|
||||||
|
|
||||||
A condition is composed of an operator and a version. The supported operators are:
|
|
||||||
|
|
||||||
- `<1.0.0` Less than `1.0.0`
|
|
||||||
- `<=1.0.0` Less than or equal to `1.0.0`
|
|
||||||
- `>1.0.0` Greater than `1.0.0`
|
|
||||||
- `>=1.0.0` Greater than or equal to `1.0.0`
|
|
||||||
- `1.0.0`, `=1.0.0`, `==1.0.0` Equal to `1.0.0`
|
|
||||||
- `!1.0.0`, `!=1.0.0` Not equal to `1.0.0`. Excludes version `1.0.0`.
|
|
||||||
|
|
||||||
A `Range` can link multiple `Ranges` separated by space:
|
|
||||||
|
|
||||||
Ranges can be linked by logical AND:
|
|
||||||
|
|
||||||
- `>1.0.0 <2.0.0` would match between both ranges, so `1.1.1` and `1.8.7` but not `1.0.0` or `2.0.0`
|
|
||||||
- `>1.0.0 <3.0.0 !2.0.3-beta.2` would match every version between `1.0.0` and `3.0.0` except `2.0.3-beta.2`
|
|
||||||
|
|
||||||
Ranges can also be linked by logical OR:
|
|
||||||
|
|
||||||
- `<2.0.0 || >=3.0.0` would match `1.x.x` and `3.x.x` but not `2.x.x`
|
|
||||||
|
|
||||||
AND has a higher precedence than OR. It's not possible to use brackets.
|
|
||||||
|
|
||||||
Ranges can be combined by both AND and OR
|
|
||||||
|
|
||||||
- `>1.0.0 <2.0.0 || >3.0.0 !4.2.1` would match `1.2.3`, `1.9.9`, `3.1.1`, but not `4.2.1`, `2.1.1`
|
|
||||||
|
|
||||||
Range usage:
|
|
||||||
|
|
||||||
```
|
|
||||||
v, err := semver.Parse("1.2.3")
|
|
||||||
range, err := semver.ParseRange(">1.0.0 <2.0.0 || >=3.0.0")
|
|
||||||
if range(v) {
|
|
||||||
//valid
|
|
||||||
}
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
Example
|
|
||||||
-----
|
|
||||||
|
|
||||||
Have a look at full examples in [examples/main.go](examples/main.go)
|
|
||||||
|
|
||||||
```go
|
|
||||||
import github.com/blang/semver
|
|
||||||
|
|
||||||
v, err := semver.Make("0.0.1-alpha.preview+123.github")
|
|
||||||
fmt.Printf("Major: %d\n", v.Major)
|
|
||||||
fmt.Printf("Minor: %d\n", v.Minor)
|
|
||||||
fmt.Printf("Patch: %d\n", v.Patch)
|
|
||||||
fmt.Printf("Pre: %s\n", v.Pre)
|
|
||||||
fmt.Printf("Build: %s\n", v.Build)
|
|
||||||
|
|
||||||
// Prerelease versions array
|
|
||||||
if len(v.Pre) > 0 {
|
|
||||||
fmt.Println("Prerelease versions:")
|
|
||||||
for i, pre := range v.Pre {
|
|
||||||
fmt.Printf("%d: %q\n", i, pre)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Build meta data array
|
|
||||||
if len(v.Build) > 0 {
|
|
||||||
fmt.Println("Build meta data:")
|
|
||||||
for i, build := range v.Build {
|
|
||||||
fmt.Printf("%d: %q\n", i, build)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
v001, err := semver.Make("0.0.1")
|
|
||||||
// Compare using helpers: v.GT(v2), v.LT, v.GTE, v.LTE
|
|
||||||
v001.GT(v) == true
|
|
||||||
v.LT(v001) == true
|
|
||||||
v.GTE(v) == true
|
|
||||||
v.LTE(v) == true
|
|
||||||
|
|
||||||
// Or use v.Compare(v2) for comparisons (-1, 0, 1):
|
|
||||||
v001.Compare(v) == 1
|
|
||||||
v.Compare(v001) == -1
|
|
||||||
v.Compare(v) == 0
|
|
||||||
|
|
||||||
// Manipulate Version in place:
|
|
||||||
v.Pre[0], err = semver.NewPRVersion("beta")
|
|
||||||
if err != nil {
|
|
||||||
fmt.Printf("Error parsing pre release version: %q", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Println("\nValidate versions:")
|
|
||||||
v.Build[0] = "?"
|
|
||||||
|
|
||||||
err = v.Validate()
|
|
||||||
if err != nil {
|
|
||||||
fmt.Printf("Validation failed: %s\n", err)
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
Benchmarks
|
|
||||||
-----
|
|
||||||
|
|
||||||
BenchmarkParseSimple-4 5000000 390 ns/op 48 B/op 1 allocs/op
|
|
||||||
BenchmarkParseComplex-4 1000000 1813 ns/op 256 B/op 7 allocs/op
|
|
||||||
BenchmarkParseAverage-4 1000000 1171 ns/op 163 B/op 4 allocs/op
|
|
||||||
BenchmarkStringSimple-4 20000000 119 ns/op 16 B/op 1 allocs/op
|
|
||||||
BenchmarkStringLarger-4 10000000 206 ns/op 32 B/op 2 allocs/op
|
|
||||||
BenchmarkStringComplex-4 5000000 324 ns/op 80 B/op 3 allocs/op
|
|
||||||
BenchmarkStringAverage-4 5000000 273 ns/op 53 B/op 2 allocs/op
|
|
||||||
BenchmarkValidateSimple-4 200000000 9.33 ns/op 0 B/op 0 allocs/op
|
|
||||||
BenchmarkValidateComplex-4 3000000 469 ns/op 0 B/op 0 allocs/op
|
|
||||||
BenchmarkValidateAverage-4 5000000 256 ns/op 0 B/op 0 allocs/op
|
|
||||||
BenchmarkCompareSimple-4 100000000 11.8 ns/op 0 B/op 0 allocs/op
|
|
||||||
BenchmarkCompareComplex-4 50000000 30.8 ns/op 0 B/op 0 allocs/op
|
|
||||||
BenchmarkCompareAverage-4 30000000 41.5 ns/op 0 B/op 0 allocs/op
|
|
||||||
BenchmarkSort-4 3000000 419 ns/op 256 B/op 2 allocs/op
|
|
||||||
BenchmarkRangeParseSimple-4 2000000 850 ns/op 192 B/op 5 allocs/op
|
|
||||||
BenchmarkRangeParseAverage-4 1000000 1677 ns/op 400 B/op 10 allocs/op
|
|
||||||
BenchmarkRangeParseComplex-4 300000 5214 ns/op 1440 B/op 30 allocs/op
|
|
||||||
BenchmarkRangeMatchSimple-4 50000000 25.6 ns/op 0 B/op 0 allocs/op
|
|
||||||
BenchmarkRangeMatchAverage-4 30000000 56.4 ns/op 0 B/op 0 allocs/op
|
|
||||||
BenchmarkRangeMatchComplex-4 10000000 153 ns/op 0 B/op 0 allocs/op
|
|
||||||
|
|
||||||
See benchmark cases at [semver_test.go](semver_test.go)
|
|
||||||
|
|
||||||
|
|
||||||
Motivation
|
|
||||||
-----
|
|
||||||
|
|
||||||
I simply couldn't find any lib supporting the full spec. Others were just wrong or used reflection and regex which i don't like.
|
|
||||||
|
|
||||||
|
|
||||||
Contribution
|
|
||||||
-----
|
|
||||||
|
|
||||||
Feel free to make a pull request. For bigger changes create a issue first to discuss about it.
|
|
||||||
|
|
||||||
|
|
||||||
License
|
|
||||||
-----
|
|
||||||
|
|
||||||
See [LICENSE](LICENSE) file.
|
|
23
vendor/github.com/blang/semver/json.go
generated
vendored
23
vendor/github.com/blang/semver/json.go
generated
vendored
@ -1,23 +0,0 @@
|
|||||||
package semver
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
)
|
|
||||||
|
|
||||||
// MarshalJSON implements the encoding/json.Marshaler interface.
|
|
||||||
func (v Version) MarshalJSON() ([]byte, error) {
|
|
||||||
return json.Marshal(v.String())
|
|
||||||
}
|
|
||||||
|
|
||||||
// UnmarshalJSON implements the encoding/json.Unmarshaler interface.
|
|
||||||
func (v *Version) UnmarshalJSON(data []byte) (err error) {
|
|
||||||
var versionString string
|
|
||||||
|
|
||||||
if err = json.Unmarshal(data, &versionString); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
*v, err = Parse(versionString)
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
224
vendor/github.com/blang/semver/range.go
generated
vendored
224
vendor/github.com/blang/semver/range.go
generated
vendored
@ -1,224 +0,0 @@
|
|||||||
package semver
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
"unicode"
|
|
||||||
)
|
|
||||||
|
|
||||||
type comparator func(Version, Version) bool
|
|
||||||
|
|
||||||
var (
|
|
||||||
compEQ comparator = func(v1 Version, v2 Version) bool {
|
|
||||||
return v1.Compare(v2) == 0
|
|
||||||
}
|
|
||||||
compNE = func(v1 Version, v2 Version) bool {
|
|
||||||
return v1.Compare(v2) != 0
|
|
||||||
}
|
|
||||||
compGT = func(v1 Version, v2 Version) bool {
|
|
||||||
return v1.Compare(v2) == 1
|
|
||||||
}
|
|
||||||
compGE = func(v1 Version, v2 Version) bool {
|
|
||||||
return v1.Compare(v2) >= 0
|
|
||||||
}
|
|
||||||
compLT = func(v1 Version, v2 Version) bool {
|
|
||||||
return v1.Compare(v2) == -1
|
|
||||||
}
|
|
||||||
compLE = func(v1 Version, v2 Version) bool {
|
|
||||||
return v1.Compare(v2) <= 0
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
type versionRange struct {
|
|
||||||
v Version
|
|
||||||
c comparator
|
|
||||||
}
|
|
||||||
|
|
||||||
// rangeFunc creates a Range from the given versionRange.
|
|
||||||
func (vr *versionRange) rangeFunc() Range {
|
|
||||||
return Range(func(v Version) bool {
|
|
||||||
return vr.c(v, vr.v)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// Range represents a range of versions.
|
|
||||||
// A Range can be used to check if a Version satisfies it:
|
|
||||||
//
|
|
||||||
// range, err := semver.ParseRange(">1.0.0 <2.0.0")
|
|
||||||
// range(semver.MustParse("1.1.1") // returns true
|
|
||||||
type Range func(Version) bool
|
|
||||||
|
|
||||||
// OR combines the existing Range with another Range using logical OR.
|
|
||||||
func (rf Range) OR(f Range) Range {
|
|
||||||
return Range(func(v Version) bool {
|
|
||||||
return rf(v) || f(v)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// AND combines the existing Range with another Range using logical AND.
|
|
||||||
func (rf Range) AND(f Range) Range {
|
|
||||||
return Range(func(v Version) bool {
|
|
||||||
return rf(v) && f(v)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// ParseRange parses a range and returns a Range.
|
|
||||||
// If the range could not be parsed an error is returned.
|
|
||||||
//
|
|
||||||
// Valid ranges are:
|
|
||||||
// - "<1.0.0"
|
|
||||||
// - "<=1.0.0"
|
|
||||||
// - ">1.0.0"
|
|
||||||
// - ">=1.0.0"
|
|
||||||
// - "1.0.0", "=1.0.0", "==1.0.0"
|
|
||||||
// - "!1.0.0", "!=1.0.0"
|
|
||||||
//
|
|
||||||
// A Range can consist of multiple ranges separated by space:
|
|
||||||
// Ranges can be linked by logical AND:
|
|
||||||
// - ">1.0.0 <2.0.0" would match between both ranges, so "1.1.1" and "1.8.7" but not "1.0.0" or "2.0.0"
|
|
||||||
// - ">1.0.0 <3.0.0 !2.0.3-beta.2" would match every version between 1.0.0 and 3.0.0 except 2.0.3-beta.2
|
|
||||||
//
|
|
||||||
// Ranges can also be linked by logical OR:
|
|
||||||
// - "<2.0.0 || >=3.0.0" would match "1.x.x" and "3.x.x" but not "2.x.x"
|
|
||||||
//
|
|
||||||
// AND has a higher precedence than OR. It's not possible to use brackets.
|
|
||||||
//
|
|
||||||
// Ranges can be combined by both AND and OR
|
|
||||||
//
|
|
||||||
// - `>1.0.0 <2.0.0 || >3.0.0 !4.2.1` would match `1.2.3`, `1.9.9`, `3.1.1`, but not `4.2.1`, `2.1.1`
|
|
||||||
func ParseRange(s string) (Range, error) {
|
|
||||||
parts := splitAndTrim(s)
|
|
||||||
orParts, err := splitORParts(parts)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
var orFn Range
|
|
||||||
for _, p := range orParts {
|
|
||||||
var andFn Range
|
|
||||||
for _, ap := range p {
|
|
||||||
opStr, vStr, err := splitComparatorVersion(ap)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
vr, err := buildVersionRange(opStr, vStr)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("Could not parse Range %q: %s", ap, err)
|
|
||||||
}
|
|
||||||
rf := vr.rangeFunc()
|
|
||||||
|
|
||||||
// Set function
|
|
||||||
if andFn == nil {
|
|
||||||
andFn = rf
|
|
||||||
} else { // Combine with existing function
|
|
||||||
andFn = andFn.AND(rf)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if orFn == nil {
|
|
||||||
orFn = andFn
|
|
||||||
} else {
|
|
||||||
orFn = orFn.OR(andFn)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
return orFn, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// splitORParts splits the already cleaned parts by '||'.
|
|
||||||
// Checks for invalid positions of the operator and returns an
|
|
||||||
// error if found.
|
|
||||||
func splitORParts(parts []string) ([][]string, error) {
|
|
||||||
var ORparts [][]string
|
|
||||||
last := 0
|
|
||||||
for i, p := range parts {
|
|
||||||
if p == "||" {
|
|
||||||
if i == 0 {
|
|
||||||
return nil, fmt.Errorf("First element in range is '||'")
|
|
||||||
}
|
|
||||||
ORparts = append(ORparts, parts[last:i])
|
|
||||||
last = i + 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if last == len(parts) {
|
|
||||||
return nil, fmt.Errorf("Last element in range is '||'")
|
|
||||||
}
|
|
||||||
ORparts = append(ORparts, parts[last:])
|
|
||||||
return ORparts, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// buildVersionRange takes a slice of 2: operator and version
|
|
||||||
// and builds a versionRange, otherwise an error.
|
|
||||||
func buildVersionRange(opStr, vStr string) (*versionRange, error) {
|
|
||||||
c := parseComparator(opStr)
|
|
||||||
if c == nil {
|
|
||||||
return nil, fmt.Errorf("Could not parse comparator %q in %q", opStr, strings.Join([]string{opStr, vStr}, ""))
|
|
||||||
}
|
|
||||||
v, err := Parse(vStr)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("Could not parse version %q in %q: %s", vStr, strings.Join([]string{opStr, vStr}, ""), err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return &versionRange{
|
|
||||||
v: v,
|
|
||||||
c: c,
|
|
||||||
}, nil
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// splitAndTrim splits a range string by spaces and cleans leading and trailing spaces
|
|
||||||
func splitAndTrim(s string) (result []string) {
|
|
||||||
last := 0
|
|
||||||
for i := 0; i < len(s); i++ {
|
|
||||||
if s[i] == ' ' {
|
|
||||||
if last < i-1 {
|
|
||||||
result = append(result, s[last:i])
|
|
||||||
}
|
|
||||||
last = i + 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if last < len(s)-1 {
|
|
||||||
result = append(result, s[last:])
|
|
||||||
}
|
|
||||||
// parts := strings.Split(s, " ")
|
|
||||||
// for _, x := range parts {
|
|
||||||
// if s := strings.TrimSpace(x); len(s) != 0 {
|
|
||||||
// result = append(result, s)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// splitComparatorVersion splits the comparator from the version.
|
|
||||||
// Spaces between the comparator and the version are not allowed.
|
|
||||||
// Input must be free of leading or trailing spaces.
|
|
||||||
func splitComparatorVersion(s string) (string, string, error) {
|
|
||||||
i := strings.IndexFunc(s, unicode.IsDigit)
|
|
||||||
if i == -1 {
|
|
||||||
return "", "", fmt.Errorf("Could not get version from string: %q", s)
|
|
||||||
}
|
|
||||||
return strings.TrimSpace(s[0:i]), s[i:], nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func parseComparator(s string) comparator {
|
|
||||||
switch s {
|
|
||||||
case "==":
|
|
||||||
fallthrough
|
|
||||||
case "":
|
|
||||||
fallthrough
|
|
||||||
case "=":
|
|
||||||
return compEQ
|
|
||||||
case ">":
|
|
||||||
return compGT
|
|
||||||
case ">=":
|
|
||||||
return compGE
|
|
||||||
case "<":
|
|
||||||
return compLT
|
|
||||||
case "<=":
|
|
||||||
return compLE
|
|
||||||
case "!":
|
|
||||||
fallthrough
|
|
||||||
case "!=":
|
|
||||||
return compNE
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
395
vendor/github.com/blang/semver/semver.go
generated
vendored
395
vendor/github.com/blang/semver/semver.go
generated
vendored
@ -1,395 +0,0 @@
|
|||||||
package semver
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
numbers string = "0123456789"
|
|
||||||
alphas = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-"
|
|
||||||
alphanum = alphas + numbers
|
|
||||||
)
|
|
||||||
|
|
||||||
// SpecVersion is the latest fully supported spec version of semver
|
|
||||||
var SpecVersion = Version{
|
|
||||||
Major: 2,
|
|
||||||
Minor: 0,
|
|
||||||
Patch: 0,
|
|
||||||
}
|
|
||||||
|
|
||||||
// Version represents a semver compatible version
|
|
||||||
type Version struct {
|
|
||||||
Major uint64
|
|
||||||
Minor uint64
|
|
||||||
Patch uint64
|
|
||||||
Pre []PRVersion
|
|
||||||
Build []string //No Precendence
|
|
||||||
}
|
|
||||||
|
|
||||||
// Version to string
|
|
||||||
func (v Version) String() string {
|
|
||||||
b := make([]byte, 0, 5)
|
|
||||||
b = strconv.AppendUint(b, v.Major, 10)
|
|
||||||
b = append(b, '.')
|
|
||||||
b = strconv.AppendUint(b, v.Minor, 10)
|
|
||||||
b = append(b, '.')
|
|
||||||
b = strconv.AppendUint(b, v.Patch, 10)
|
|
||||||
|
|
||||||
if len(v.Pre) > 0 {
|
|
||||||
b = append(b, '-')
|
|
||||||
b = append(b, v.Pre[0].String()...)
|
|
||||||
|
|
||||||
for _, pre := range v.Pre[1:] {
|
|
||||||
b = append(b, '.')
|
|
||||||
b = append(b, pre.String()...)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(v.Build) > 0 {
|
|
||||||
b = append(b, '+')
|
|
||||||
b = append(b, v.Build[0]...)
|
|
||||||
|
|
||||||
for _, build := range v.Build[1:] {
|
|
||||||
b = append(b, '.')
|
|
||||||
b = append(b, build...)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return string(b)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Equals checks if v is equal to o.
|
|
||||||
func (v Version) Equals(o Version) bool {
|
|
||||||
return (v.Compare(o) == 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
// EQ checks if v is equal to o.
|
|
||||||
func (v Version) EQ(o Version) bool {
|
|
||||||
return (v.Compare(o) == 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
// NE checks if v is not equal to o.
|
|
||||||
func (v Version) NE(o Version) bool {
|
|
||||||
return (v.Compare(o) != 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GT checks if v is greater than o.
|
|
||||||
func (v Version) GT(o Version) bool {
|
|
||||||
return (v.Compare(o) == 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GTE checks if v is greater than or equal to o.
|
|
||||||
func (v Version) GTE(o Version) bool {
|
|
||||||
return (v.Compare(o) >= 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GE checks if v is greater than or equal to o.
|
|
||||||
func (v Version) GE(o Version) bool {
|
|
||||||
return (v.Compare(o) >= 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
// LT checks if v is less than o.
|
|
||||||
func (v Version) LT(o Version) bool {
|
|
||||||
return (v.Compare(o) == -1)
|
|
||||||
}
|
|
||||||
|
|
||||||
// LTE checks if v is less than or equal to o.
|
|
||||||
func (v Version) LTE(o Version) bool {
|
|
||||||
return (v.Compare(o) <= 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
// LE checks if v is less than or equal to o.
|
|
||||||
func (v Version) LE(o Version) bool {
|
|
||||||
return (v.Compare(o) <= 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compare compares Versions v to o:
|
|
||||||
// -1 == v is less than o
|
|
||||||
// 0 == v is equal to o
|
|
||||||
// 1 == v is greater than o
|
|
||||||
func (v Version) Compare(o Version) int {
|
|
||||||
if v.Major != o.Major {
|
|
||||||
if v.Major > o.Major {
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
if v.Minor != o.Minor {
|
|
||||||
if v.Minor > o.Minor {
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
if v.Patch != o.Patch {
|
|
||||||
if v.Patch > o.Patch {
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
|
|
||||||
// Quick comparison if a version has no prerelease versions
|
|
||||||
if len(v.Pre) == 0 && len(o.Pre) == 0 {
|
|
||||||
return 0
|
|
||||||
} else if len(v.Pre) == 0 && len(o.Pre) > 0 {
|
|
||||||
return 1
|
|
||||||
} else if len(v.Pre) > 0 && len(o.Pre) == 0 {
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
|
|
||||||
i := 0
|
|
||||||
for ; i < len(v.Pre) && i < len(o.Pre); i++ {
|
|
||||||
if comp := v.Pre[i].Compare(o.Pre[i]); comp == 0 {
|
|
||||||
continue
|
|
||||||
} else if comp == 1 {
|
|
||||||
return 1
|
|
||||||
} else {
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If all pr versions are the equal but one has further prversion, this one greater
|
|
||||||
if i == len(v.Pre) && i == len(o.Pre) {
|
|
||||||
return 0
|
|
||||||
} else if i == len(v.Pre) && i < len(o.Pre) {
|
|
||||||
return -1
|
|
||||||
} else {
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validate validates v and returns error in case
|
|
||||||
func (v Version) Validate() error {
|
|
||||||
// Major, Minor, Patch already validated using uint64
|
|
||||||
|
|
||||||
for _, pre := range v.Pre {
|
|
||||||
if !pre.IsNum { //Numeric prerelease versions already uint64
|
|
||||||
if len(pre.VersionStr) == 0 {
|
|
||||||
return fmt.Errorf("Prerelease can not be empty %q", pre.VersionStr)
|
|
||||||
}
|
|
||||||
if !containsOnly(pre.VersionStr, alphanum) {
|
|
||||||
return fmt.Errorf("Invalid character(s) found in prerelease %q", pre.VersionStr)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, build := range v.Build {
|
|
||||||
if len(build) == 0 {
|
|
||||||
return fmt.Errorf("Build meta data can not be empty %q", build)
|
|
||||||
}
|
|
||||||
if !containsOnly(build, alphanum) {
|
|
||||||
return fmt.Errorf("Invalid character(s) found in build meta data %q", build)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// New is an alias for Parse and returns a pointer, parses version string and returns a validated Version or error
|
|
||||||
func New(s string) (vp *Version, err error) {
|
|
||||||
v, err := Parse(s)
|
|
||||||
vp = &v
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make is an alias for Parse, parses version string and returns a validated Version or error
|
|
||||||
func Make(s string) (Version, error) {
|
|
||||||
return Parse(s)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parse parses version string and returns a validated Version or error
|
|
||||||
func Parse(s string) (Version, error) {
|
|
||||||
if len(s) == 0 {
|
|
||||||
return Version{}, errors.New("Version string empty")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Split into major.minor.(patch+pr+meta)
|
|
||||||
parts := strings.SplitN(s, ".", 3)
|
|
||||||
if len(parts) != 3 {
|
|
||||||
return Version{}, errors.New("No Major.Minor.Patch elements found")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Major
|
|
||||||
if !containsOnly(parts[0], numbers) {
|
|
||||||
return Version{}, fmt.Errorf("Invalid character(s) found in major number %q", parts[0])
|
|
||||||
}
|
|
||||||
if hasLeadingZeroes(parts[0]) {
|
|
||||||
return Version{}, fmt.Errorf("Major number must not contain leading zeroes %q", parts[0])
|
|
||||||
}
|
|
||||||
major, err := strconv.ParseUint(parts[0], 10, 64)
|
|
||||||
if err != nil {
|
|
||||||
return Version{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Minor
|
|
||||||
if !containsOnly(parts[1], numbers) {
|
|
||||||
return Version{}, fmt.Errorf("Invalid character(s) found in minor number %q", parts[1])
|
|
||||||
}
|
|
||||||
if hasLeadingZeroes(parts[1]) {
|
|
||||||
return Version{}, fmt.Errorf("Minor number must not contain leading zeroes %q", parts[1])
|
|
||||||
}
|
|
||||||
minor, err := strconv.ParseUint(parts[1], 10, 64)
|
|
||||||
if err != nil {
|
|
||||||
return Version{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
v := Version{}
|
|
||||||
v.Major = major
|
|
||||||
v.Minor = minor
|
|
||||||
|
|
||||||
var build, prerelease []string
|
|
||||||
patchStr := parts[2]
|
|
||||||
|
|
||||||
if buildIndex := strings.IndexRune(patchStr, '+'); buildIndex != -1 {
|
|
||||||
build = strings.Split(patchStr[buildIndex+1:], ".")
|
|
||||||
patchStr = patchStr[:buildIndex]
|
|
||||||
}
|
|
||||||
|
|
||||||
if preIndex := strings.IndexRune(patchStr, '-'); preIndex != -1 {
|
|
||||||
prerelease = strings.Split(patchStr[preIndex+1:], ".")
|
|
||||||
patchStr = patchStr[:preIndex]
|
|
||||||
}
|
|
||||||
|
|
||||||
if !containsOnly(patchStr, numbers) {
|
|
||||||
return Version{}, fmt.Errorf("Invalid character(s) found in patch number %q", patchStr)
|
|
||||||
}
|
|
||||||
if hasLeadingZeroes(patchStr) {
|
|
||||||
return Version{}, fmt.Errorf("Patch number must not contain leading zeroes %q", patchStr)
|
|
||||||
}
|
|
||||||
patch, err := strconv.ParseUint(patchStr, 10, 64)
|
|
||||||
if err != nil {
|
|
||||||
return Version{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
v.Patch = patch
|
|
||||||
|
|
||||||
// Prerelease
|
|
||||||
for _, prstr := range prerelease {
|
|
||||||
parsedPR, err := NewPRVersion(prstr)
|
|
||||||
if err != nil {
|
|
||||||
return Version{}, err
|
|
||||||
}
|
|
||||||
v.Pre = append(v.Pre, parsedPR)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Build meta data
|
|
||||||
for _, str := range build {
|
|
||||||
if len(str) == 0 {
|
|
||||||
return Version{}, errors.New("Build meta data is empty")
|
|
||||||
}
|
|
||||||
if !containsOnly(str, alphanum) {
|
|
||||||
return Version{}, fmt.Errorf("Invalid character(s) found in build meta data %q", str)
|
|
||||||
}
|
|
||||||
v.Build = append(v.Build, str)
|
|
||||||
}
|
|
||||||
|
|
||||||
return v, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// MustParse is like Parse but panics if the version cannot be parsed.
|
|
||||||
func MustParse(s string) Version {
|
|
||||||
v, err := Parse(s)
|
|
||||||
if err != nil {
|
|
||||||
panic(`semver: Parse(` + s + `): ` + err.Error())
|
|
||||||
}
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
// PRVersion represents a PreRelease Version
|
|
||||||
type PRVersion struct {
|
|
||||||
VersionStr string
|
|
||||||
VersionNum uint64
|
|
||||||
IsNum bool
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewPRVersion creates a new valid prerelease version
|
|
||||||
func NewPRVersion(s string) (PRVersion, error) {
|
|
||||||
if len(s) == 0 {
|
|
||||||
return PRVersion{}, errors.New("Prerelease is empty")
|
|
||||||
}
|
|
||||||
v := PRVersion{}
|
|
||||||
if containsOnly(s, numbers) {
|
|
||||||
if hasLeadingZeroes(s) {
|
|
||||||
return PRVersion{}, fmt.Errorf("Numeric PreRelease version must not contain leading zeroes %q", s)
|
|
||||||
}
|
|
||||||
num, err := strconv.ParseUint(s, 10, 64)
|
|
||||||
|
|
||||||
// Might never be hit, but just in case
|
|
||||||
if err != nil {
|
|
||||||
return PRVersion{}, err
|
|
||||||
}
|
|
||||||
v.VersionNum = num
|
|
||||||
v.IsNum = true
|
|
||||||
} else if containsOnly(s, alphanum) {
|
|
||||||
v.VersionStr = s
|
|
||||||
v.IsNum = false
|
|
||||||
} else {
|
|
||||||
return PRVersion{}, fmt.Errorf("Invalid character(s) found in prerelease %q", s)
|
|
||||||
}
|
|
||||||
return v, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsNumeric checks if prerelease-version is numeric
|
|
||||||
func (v PRVersion) IsNumeric() bool {
|
|
||||||
return v.IsNum
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compare compares two PreRelease Versions v and o:
|
|
||||||
// -1 == v is less than o
|
|
||||||
// 0 == v is equal to o
|
|
||||||
// 1 == v is greater than o
|
|
||||||
func (v PRVersion) Compare(o PRVersion) int {
|
|
||||||
if v.IsNum && !o.IsNum {
|
|
||||||
return -1
|
|
||||||
} else if !v.IsNum && o.IsNum {
|
|
||||||
return 1
|
|
||||||
} else if v.IsNum && o.IsNum {
|
|
||||||
if v.VersionNum == o.VersionNum {
|
|
||||||
return 0
|
|
||||||
} else if v.VersionNum > o.VersionNum {
|
|
||||||
return 1
|
|
||||||
} else {
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
} else { // both are Alphas
|
|
||||||
if v.VersionStr == o.VersionStr {
|
|
||||||
return 0
|
|
||||||
} else if v.VersionStr > o.VersionStr {
|
|
||||||
return 1
|
|
||||||
} else {
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// PreRelease version to string
|
|
||||||
func (v PRVersion) String() string {
|
|
||||||
if v.IsNum {
|
|
||||||
return strconv.FormatUint(v.VersionNum, 10)
|
|
||||||
}
|
|
||||||
return v.VersionStr
|
|
||||||
}
|
|
||||||
|
|
||||||
func containsOnly(s string, set string) bool {
|
|
||||||
return strings.IndexFunc(s, func(r rune) bool {
|
|
||||||
return !strings.ContainsRune(set, r)
|
|
||||||
}) == -1
|
|
||||||
}
|
|
||||||
|
|
||||||
func hasLeadingZeroes(s string) bool {
|
|
||||||
return len(s) > 1 && s[0] == '0'
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewBuildVersion creates a new valid build version
|
|
||||||
func NewBuildVersion(s string) (string, error) {
|
|
||||||
if len(s) == 0 {
|
|
||||||
return "", errors.New("Buildversion is empty")
|
|
||||||
}
|
|
||||||
if !containsOnly(s, alphanum) {
|
|
||||||
return "", fmt.Errorf("Invalid character(s) found in build meta data %q", s)
|
|
||||||
}
|
|
||||||
return s, nil
|
|
||||||
}
|
|
28
vendor/github.com/blang/semver/sort.go
generated
vendored
28
vendor/github.com/blang/semver/sort.go
generated
vendored
@ -1,28 +0,0 @@
|
|||||||
package semver
|
|
||||||
|
|
||||||
import (
|
|
||||||
"sort"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Versions represents multiple versions.
|
|
||||||
type Versions []Version
|
|
||||||
|
|
||||||
// Len returns length of version collection
|
|
||||||
func (s Versions) Len() int {
|
|
||||||
return len(s)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Swap swaps two versions inside the collection by its indices
|
|
||||||
func (s Versions) Swap(i, j int) {
|
|
||||||
s[i], s[j] = s[j], s[i]
|
|
||||||
}
|
|
||||||
|
|
||||||
// Less checks if version at index i is less than version at index j
|
|
||||||
func (s Versions) Less(i, j int) bool {
|
|
||||||
return s[i].LT(s[j])
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sort sorts a slice of versions
|
|
||||||
func Sort(versions []Version) {
|
|
||||||
sort.Sort(Versions(versions))
|
|
||||||
}
|
|
30
vendor/github.com/blang/semver/sql.go
generated
vendored
30
vendor/github.com/blang/semver/sql.go
generated
vendored
@ -1,30 +0,0 @@
|
|||||||
package semver
|
|
||||||
|
|
||||||
import (
|
|
||||||
"database/sql/driver"
|
|
||||||
"fmt"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Scan implements the database/sql.Scanner interface.
|
|
||||||
func (v *Version) Scan(src interface{}) (err error) {
|
|
||||||
var str string
|
|
||||||
switch src := src.(type) {
|
|
||||||
case string:
|
|
||||||
str = src
|
|
||||||
case []byte:
|
|
||||||
str = string(src)
|
|
||||||
default:
|
|
||||||
return fmt.Errorf("Version.Scan: cannot convert %T to string.", src)
|
|
||||||
}
|
|
||||||
|
|
||||||
if t, err := Parse(str); err == nil {
|
|
||||||
*v = t
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Value implements the database/sql/driver.Valuer interface.
|
|
||||||
func (v Version) Value() (driver.Value, error) {
|
|
||||||
return v.String(), nil
|
|
||||||
}
|
|
126
vendor/github.com/containerd/containerd/api/events/task.pb.go
generated
vendored
126
vendor/github.com/containerd/containerd/api/events/task.pb.go
generated
vendored
@ -55,6 +55,9 @@ type TaskDelete struct {
|
|||||||
Pid uint32 `protobuf:"varint,2,opt,name=pid,proto3" json:"pid,omitempty"`
|
Pid uint32 `protobuf:"varint,2,opt,name=pid,proto3" json:"pid,omitempty"`
|
||||||
ExitStatus uint32 `protobuf:"varint,3,opt,name=exit_status,json=exitStatus,proto3" json:"exit_status,omitempty"`
|
ExitStatus uint32 `protobuf:"varint,3,opt,name=exit_status,json=exitStatus,proto3" json:"exit_status,omitempty"`
|
||||||
ExitedAt time.Time `protobuf:"bytes,4,opt,name=exited_at,json=exitedAt,stdtime" json:"exited_at"`
|
ExitedAt time.Time `protobuf:"bytes,4,opt,name=exited_at,json=exitedAt,stdtime" json:"exited_at"`
|
||||||
|
// id is the specific exec. By default if omitted will be `""` thus matches
|
||||||
|
// the init exec of the task matching `container_id`.
|
||||||
|
ID string `protobuf:"bytes,5,opt,name=id,proto3" json:"id,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *TaskDelete) Reset() { *m = TaskDelete{} }
|
func (m *TaskDelete) Reset() { *m = TaskDelete{} }
|
||||||
@ -210,6 +213,8 @@ func (m *TaskDelete) Field(fieldpath []string) (string, bool) {
|
|||||||
// unhandled: exited_at
|
// unhandled: exited_at
|
||||||
case "container_id":
|
case "container_id":
|
||||||
return string(m.ContainerID), len(m.ContainerID) > 0
|
return string(m.ContainerID), len(m.ContainerID) > 0
|
||||||
|
case "id":
|
||||||
|
return string(m.ID), len(m.ID) > 0
|
||||||
}
|
}
|
||||||
return "", false
|
return "", false
|
||||||
}
|
}
|
||||||
@ -474,6 +479,12 @@ func (m *TaskDelete) MarshalTo(dAtA []byte) (int, error) {
|
|||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
i += n2
|
i += n2
|
||||||
|
if len(m.ID) > 0 {
|
||||||
|
dAtA[i] = 0x2a
|
||||||
|
i++
|
||||||
|
i = encodeVarintTask(dAtA, i, uint64(len(m.ID)))
|
||||||
|
i += copy(dAtA[i:], m.ID)
|
||||||
|
}
|
||||||
return i, nil
|
return i, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -806,6 +817,10 @@ func (m *TaskDelete) Size() (n int) {
|
|||||||
}
|
}
|
||||||
l = types.SizeOfStdTime(m.ExitedAt)
|
l = types.SizeOfStdTime(m.ExitedAt)
|
||||||
n += 1 + l + sovTask(uint64(l))
|
n += 1 + l + sovTask(uint64(l))
|
||||||
|
l = len(m.ID)
|
||||||
|
if l > 0 {
|
||||||
|
n += 1 + l + sovTask(uint64(l))
|
||||||
|
}
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -975,6 +990,7 @@ func (this *TaskDelete) String() string {
|
|||||||
`Pid:` + fmt.Sprintf("%v", this.Pid) + `,`,
|
`Pid:` + fmt.Sprintf("%v", this.Pid) + `,`,
|
||||||
`ExitStatus:` + fmt.Sprintf("%v", this.ExitStatus) + `,`,
|
`ExitStatus:` + fmt.Sprintf("%v", this.ExitStatus) + `,`,
|
||||||
`ExitedAt:` + strings.Replace(strings.Replace(this.ExitedAt.String(), "Timestamp", "google_protobuf2.Timestamp", 1), `&`, ``, 1) + `,`,
|
`ExitedAt:` + strings.Replace(strings.Replace(this.ExitedAt.String(), "Timestamp", "google_protobuf2.Timestamp", 1), `&`, ``, 1) + `,`,
|
||||||
|
`ID:` + fmt.Sprintf("%v", this.ID) + `,`,
|
||||||
`}`,
|
`}`,
|
||||||
}, "")
|
}, "")
|
||||||
return s
|
return s
|
||||||
@ -1522,6 +1538,35 @@ func (m *TaskDelete) Unmarshal(dAtA []byte) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
iNdEx = postIndex
|
iNdEx = postIndex
|
||||||
|
case 5:
|
||||||
|
if wireType != 2 {
|
||||||
|
return fmt.Errorf("proto: wrong wireType = %d for field ID", wireType)
|
||||||
|
}
|
||||||
|
var stringLen uint64
|
||||||
|
for shift := uint(0); ; shift += 7 {
|
||||||
|
if shift >= 64 {
|
||||||
|
return ErrIntOverflowTask
|
||||||
|
}
|
||||||
|
if iNdEx >= l {
|
||||||
|
return io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
b := dAtA[iNdEx]
|
||||||
|
iNdEx++
|
||||||
|
stringLen |= (uint64(b) & 0x7F) << shift
|
||||||
|
if b < 0x80 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
intStringLen := int(stringLen)
|
||||||
|
if intStringLen < 0 {
|
||||||
|
return ErrInvalidLengthTask
|
||||||
|
}
|
||||||
|
postIndex := iNdEx + intStringLen
|
||||||
|
if postIndex > l {
|
||||||
|
return io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
m.ID = string(dAtA[iNdEx:postIndex])
|
||||||
|
iNdEx = postIndex
|
||||||
default:
|
default:
|
||||||
iNdEx = preIndex
|
iNdEx = preIndex
|
||||||
skippy, err := skipTask(dAtA[iNdEx:])
|
skippy, err := skipTask(dAtA[iNdEx:])
|
||||||
@ -2566,45 +2611,46 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var fileDescriptorTask = []byte{
|
var fileDescriptorTask = []byte{
|
||||||
// 637 bytes of a gzipped FileDescriptorProto
|
// 644 bytes of a gzipped FileDescriptorProto
|
||||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x95, 0xcd, 0x6e, 0xd3, 0x40,
|
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x95, 0xcd, 0x6e, 0xd3, 0x40,
|
||||||
0x10, 0xc7, 0x63, 0xa7, 0x75, 0x93, 0x09, 0x55, 0x8b, 0x55, 0x41, 0xc8, 0xc1, 0x8e, 0xcc, 0x25,
|
0x10, 0xc7, 0x63, 0xa7, 0x75, 0xd3, 0x09, 0x55, 0x8b, 0x55, 0x95, 0x90, 0x83, 0x1d, 0x99, 0x4b,
|
||||||
0x27, 0x5b, 0x04, 0x89, 0x0b, 0x42, 0x6a, 0xd2, 0x70, 0xc8, 0xa1, 0x4a, 0x71, 0x7b, 0xa8, 0xb8,
|
0x4e, 0xb6, 0x08, 0x12, 0x17, 0x84, 0xd4, 0xa4, 0xe1, 0x90, 0x43, 0x95, 0xe2, 0xf6, 0x50, 0x71,
|
||||||
0x44, 0x4e, 0x76, 0x93, 0x2c, 0x8d, 0xbd, 0x96, 0x3d, 0x46, 0x45, 0xe2, 0xc0, 0x23, 0xf0, 0x08,
|
0x89, 0x36, 0xd9, 0x4d, 0xb2, 0x34, 0xf1, 0x5a, 0xf6, 0x18, 0x15, 0x89, 0x03, 0x8f, 0xc0, 0x23,
|
||||||
0x3c, 0x05, 0xcf, 0xd0, 0x03, 0x07, 0x8e, 0x9c, 0x02, 0xf5, 0x03, 0x70, 0xe2, 0x01, 0xd0, 0x7a,
|
0xf0, 0x38, 0x3d, 0x20, 0xc4, 0x91, 0x53, 0xa0, 0x7e, 0x00, 0x4e, 0x3c, 0x00, 0x5a, 0xaf, 0x93,
|
||||||
0x1d, 0xb7, 0x50, 0xf1, 0x65, 0x89, 0x53, 0x76, 0x66, 0x67, 0xff, 0x33, 0xf3, 0xdb, 0xc9, 0x1a,
|
0xb6, 0x54, 0x7c, 0x59, 0xe2, 0x94, 0x9d, 0xd9, 0xd9, 0xff, 0xec, 0xfc, 0x76, 0x3c, 0x81, 0xc7,
|
||||||
0x1e, 0xcd, 0x19, 0x2e, 0x92, 0x89, 0x3d, 0xe5, 0xbe, 0x33, 0xe5, 0x01, 0x7a, 0x2c, 0xa0, 0x11,
|
0x13, 0x8e, 0xd3, 0x64, 0xe8, 0x8e, 0xc4, 0xdc, 0x1b, 0x89, 0x00, 0x09, 0x0f, 0x58, 0x44, 0xaf,
|
||||||
0xb9, 0xbe, 0xf4, 0x42, 0xe6, 0xd0, 0x97, 0x34, 0xc0, 0xd8, 0x41, 0x2f, 0x3e, 0xb3, 0xc3, 0x88,
|
0x2f, 0x49, 0xc8, 0x3d, 0xf6, 0x8a, 0x05, 0x18, 0x7b, 0x48, 0xe2, 0x33, 0x37, 0x8c, 0x04, 0x0a,
|
||||||
0x23, 0xd7, 0x6f, 0x5f, 0x45, 0xd8, 0x72, 0xb7, 0xb5, 0x37, 0xe7, 0x73, 0x9e, 0xed, 0x3a, 0x62,
|
0xf3, 0xee, 0x55, 0x84, 0xab, 0x76, 0xeb, 0xbb, 0x13, 0x31, 0x11, 0xd9, 0xae, 0x27, 0x57, 0x2a,
|
||||||
0x25, 0x03, 0x5b, 0xe6, 0x9c, 0xf3, 0xf9, 0x92, 0x3a, 0x99, 0x35, 0x49, 0x66, 0x0e, 0x32, 0x9f,
|
0xb0, 0x6e, 0x4f, 0x84, 0x98, 0xcc, 0x98, 0x97, 0x59, 0xc3, 0x64, 0xec, 0x21, 0x9f, 0xb3, 0x18,
|
||||||
0xc6, 0xe8, 0xf9, 0x61, 0x1e, 0xf0, 0x77, 0x15, 0xe0, 0xab, 0x90, 0xc6, 0x8e, 0xcf, 0x93, 0x00,
|
0xc9, 0x3c, 0xcc, 0x03, 0xfe, 0xee, 0x06, 0xf8, 0x3a, 0x64, 0xb1, 0x37, 0x17, 0x49, 0x80, 0xf9,
|
||||||
0xf3, 0x73, 0xfb, 0x7f, 0x3c, 0x57, 0xa4, 0x0c, 0x97, 0xc9, 0x9c, 0x05, 0xce, 0x8c, 0xd1, 0x25,
|
0xb9, 0xfd, 0x3f, 0x9e, 0x5b, 0xa5, 0x0c, 0x67, 0xc9, 0x84, 0x07, 0xde, 0x98, 0xb3, 0x19, 0x0d,
|
||||||
0x09, 0x3d, 0x5c, 0x48, 0x05, 0xeb, 0xab, 0x02, 0x70, 0xe2, 0xc5, 0x67, 0x07, 0x11, 0xf5, 0x90,
|
0x09, 0x4e, 0x95, 0x82, 0xf3, 0x4d, 0x03, 0x38, 0x21, 0xf1, 0xd9, 0x41, 0xc4, 0x08, 0x32, 0xb3,
|
||||||
0xea, 0x5d, 0xb8, 0x55, 0x1c, 0x1e, 0x33, 0xd2, 0x54, 0xda, 0x4a, 0xa7, 0xde, 0xdf, 0x49, 0x57,
|
0x05, 0x77, 0x56, 0x87, 0x07, 0x9c, 0xd6, 0xb4, 0x86, 0xd6, 0xdc, 0xec, 0x6c, 0xa7, 0x0b, 0xbb,
|
||||||
0x66, 0xe3, 0x60, 0xed, 0x1f, 0x0e, 0xdc, 0x46, 0x11, 0x34, 0x24, 0xfa, 0x1d, 0xd0, 0x26, 0x49,
|
0x7a, 0xb0, 0xf4, 0xf7, 0xba, 0x7e, 0x75, 0x15, 0xd4, 0xa3, 0xe6, 0x1e, 0x18, 0xc3, 0x24, 0xa0,
|
||||||
0x40, 0x96, 0xb4, 0xa9, 0x8a, 0x68, 0x37, 0xb7, 0x74, 0x07, 0xb4, 0x88, 0x73, 0x9c, 0xc5, 0xcd,
|
0x33, 0x56, 0xd3, 0x65, 0xb4, 0x9f, 0x5b, 0xa6, 0x07, 0x46, 0x24, 0x04, 0x8e, 0xe3, 0x5a, 0xb9,
|
||||||
0x6a, 0xbb, 0xda, 0x69, 0x74, 0xef, 0xda, 0xd7, 0x78, 0x65, 0xbd, 0xd8, 0x87, 0xa2, 0x17, 0x37,
|
0x51, 0x6e, 0x56, 0x5b, 0xf7, 0xdc, 0x6b, 0xbc, 0xb2, 0x5a, 0xdc, 0x43, 0x59, 0x8b, 0x9f, 0x87,
|
||||||
0x0f, 0xd3, 0x1f, 0x80, 0xca, 0x78, 0x73, 0xa3, 0xad, 0x74, 0x1a, 0xdd, 0x7b, 0xf6, 0x0d, 0xb8,
|
0x99, 0x0f, 0x41, 0xe7, 0xa2, 0xb6, 0xd6, 0xd0, 0x9a, 0xd5, 0xd6, 0x7d, 0xf7, 0x16, 0x5c, 0x57,
|
||||||
0xb6, 0xa8, 0x73, 0x38, 0xea, 0x6b, 0xe9, 0xca, 0x54, 0x87, 0x23, 0x57, 0x65, 0x5c, 0x37, 0x00,
|
0xde, 0xb3, 0xd7, 0xef, 0x18, 0xe9, 0xc2, 0xd6, 0x7b, 0x7d, 0x5f, 0xe7, 0xc2, 0xb4, 0x00, 0x46,
|
||||||
0xa6, 0x0b, 0x3a, 0x3d, 0x0b, 0x39, 0x0b, 0xb0, 0xb9, 0x99, 0xe5, 0xbf, 0xe6, 0xd1, 0x77, 0xa1,
|
0x53, 0x36, 0x3a, 0x0b, 0x05, 0x0f, 0xb0, 0xb6, 0x9e, 0xe5, 0xbf, 0xe6, 0x31, 0x77, 0xa0, 0x1c,
|
||||||
0x1a, 0x32, 0xd2, 0xd4, 0xda, 0x4a, 0x67, 0xdb, 0x15, 0x4b, 0xeb, 0x19, 0xd4, 0x85, 0xce, 0x31,
|
0x72, 0x5a, 0x33, 0x1a, 0x5a, 0x73, 0xcb, 0x97, 0x4b, 0xe7, 0x39, 0x6c, 0x4a, 0x9d, 0x63, 0x24,
|
||||||
0x7a, 0x11, 0x96, 0x6a, 0x37, 0x97, 0x54, 0xaf, 0x24, 0xdf, 0xe7, 0x0c, 0x07, 0x74, 0x49, 0x4b,
|
0x11, 0x16, 0x2a, 0x37, 0x97, 0xd4, 0xaf, 0x24, 0x3f, 0xe6, 0x0c, 0xbb, 0x6c, 0xc6, 0x0a, 0x32,
|
||||||
0x32, 0xbc, 0x21, 0xaa, 0x9b, 0xd0, 0xa0, 0xe7, 0x0c, 0xc7, 0x31, 0x7a, 0x98, 0x08, 0x84, 0x62,
|
0xbc, 0x25, 0x6a, 0xda, 0x50, 0x65, 0xe7, 0x1c, 0x07, 0x31, 0x12, 0x4c, 0x24, 0x42, 0xb9, 0x03,
|
||||||
0x07, 0x84, 0xeb, 0x38, 0xf3, 0xe8, 0x3d, 0xa8, 0x0b, 0x8b, 0x92, 0xb1, 0x87, 0x39, 0xb4, 0x96,
|
0xd2, 0x75, 0x9c, 0x79, 0xcc, 0x36, 0x6c, 0x4a, 0x8b, 0xd1, 0x01, 0xc1, 0x1c, 0x5a, 0xdd, 0x55,
|
||||||
0x2d, 0x07, 0xcd, 0x5e, 0xdf, 0xba, 0x7d, 0xb2, 0x1e, 0xb4, 0x7e, 0xed, 0x62, 0x65, 0x56, 0xde,
|
0x8d, 0xe6, 0x2e, 0x5f, 0xdd, 0x3d, 0x59, 0x36, 0x5a, 0xa7, 0x72, 0xb1, 0xb0, 0x4b, 0xef, 0xbe,
|
||||||
0x7e, 0x36, 0x15, 0xb7, 0x26, 0x8f, 0xf5, 0xd0, 0x7a, 0x01, 0x9a, 0x64, 0xaa, 0xef, 0xc1, 0x66,
|
0xd8, 0x9a, 0x5f, 0x51, 0xc7, 0xda, 0x68, 0xee, 0x81, 0xce, 0xa9, 0xa2, 0x96, 0x53, 0xed, 0xfa,
|
||||||
0x8c, 0x84, 0x05, 0xb2, 0x58, 0x57, 0x1a, 0xe2, 0x66, 0x63, 0x24, 0x3c, 0xc1, 0xf5, 0xcd, 0x4a,
|
0x3a, 0xa7, 0xce, 0x4b, 0x30, 0x14, 0x6b, 0x73, 0x17, 0xd6, 0x63, 0xa4, 0x3c, 0x50, 0x45, 0xf8,
|
||||||
0x2b, 0xf7, 0xd3, 0x28, 0xca, 0xca, 0x92, 0x7e, 0x1a, 0x45, 0x7a, 0x0b, 0x6a, 0x48, 0x23, 0x9f,
|
0xca, 0x90, 0x2f, 0x1e, 0x23, 0x15, 0x09, 0x2e, 0x5f, 0x5c, 0x59, 0xb9, 0x9f, 0x45, 0x51, 0x76,
|
||||||
0x05, 0xde, 0x32, 0xab, 0xa8, 0xe6, 0x16, 0xb6, 0xf5, 0x41, 0x81, 0x9a, 0x48, 0xf6, 0xf4, 0x9c,
|
0x5d, 0xe5, 0x67, 0x51, 0x64, 0xd6, 0xa1, 0x82, 0x2c, 0x9a, 0xf3, 0x80, 0xcc, 0xb2, 0x9b, 0x56,
|
||||||
0x61, 0xc9, 0x31, 0x53, 0x73, 0x42, 0xf5, 0x7c, 0x04, 0x06, 0xae, 0xca, 0x0a, 0x74, 0xd5, 0x5f,
|
0xfc, 0x95, 0xed, 0x7c, 0xd0, 0xa0, 0x22, 0x93, 0x3d, 0x3b, 0xe7, 0x58, 0xb0, 0xfd, 0xf4, 0x9c,
|
||||||
0xa2, 0xdb, 0xf8, 0x3d, 0xba, 0xcd, 0x52, 0xe8, 0x9e, 0xc0, 0x96, 0xe8, 0x66, 0x34, 0x3a, 0x2c,
|
0xdc, 0x8d, 0x22, 0x96, 0x48, 0xcb, 0xbf, 0x44, 0xba, 0xf6, 0x7b, 0xa4, 0xeb, 0x45, 0x90, 0x3a,
|
||||||
0xd3, 0x8c, 0xb5, 0x80, 0x6d, 0x09, 0x83, 0x4e, 0x7b, 0x84, 0x50, 0x52, 0x8a, 0xc8, 0x7d, 0xd8,
|
0x4f, 0x61, 0x43, 0x56, 0xd3, 0xef, 0x1f, 0x16, 0x29, 0xc6, 0x99, 0xc2, 0x96, 0x82, 0xc1, 0x46,
|
||||||
0xa2, 0xe7, 0x74, 0x3a, 0x2e, 0xb0, 0x40, 0xba, 0x32, 0x35, 0xa1, 0x39, 0x1c, 0xb8, 0x9a, 0xd8,
|
0x6d, 0x4a, 0x19, 0x2d, 0x44, 0xe4, 0x01, 0x6c, 0xb0, 0x73, 0x36, 0x1a, 0xac, 0xb0, 0x40, 0xba,
|
||||||
0x1a, 0x12, 0xeb, 0x35, 0xec, 0xac, 0x33, 0x65, 0x33, 0xff, 0x1f, 0x73, 0xdd, 0xbc, 0x0a, 0x6b,
|
0xb0, 0x0d, 0xa9, 0xd9, 0xeb, 0xfa, 0x86, 0xdc, 0xea, 0x51, 0xe7, 0x0d, 0x6c, 0x2f, 0x33, 0x65,
|
||||||
0x5f, 0xfe, 0x33, 0x8e, 0xbc, 0x24, 0x2e, 0x97, 0xd8, 0xea, 0x41, 0x43, 0x28, 0xb8, 0x34, 0x4e,
|
0xdf, 0xc2, 0x7f, 0xcc, 0x75, 0xfb, 0x29, 0x9c, 0x7d, 0xf5, 0xc5, 0x1c, 0x91, 0x24, 0x2e, 0x96,
|
||||||
0xfc, 0x92, 0x12, 0x33, 0xd8, 0xcd, 0x9e, 0xb8, 0xe2, 0x59, 0x28, 0xc9, 0xe0, 0xc7, 0xc7, 0x46,
|
0xd8, 0x69, 0x43, 0x55, 0x2a, 0xf8, 0x2c, 0x4e, 0xe6, 0x05, 0x25, 0xc6, 0xb0, 0x93, 0x8d, 0xbe,
|
||||||
0xfd, 0xf9, 0xb1, 0xe9, 0x1f, 0x5d, 0x5c, 0x1a, 0x95, 0x4f, 0x97, 0x46, 0xe5, 0x4d, 0x6a, 0x28,
|
0xd5, 0xb8, 0x28, 0xc8, 0xe0, 0xe6, 0x10, 0xd2, 0x7f, 0x1e, 0x42, 0x9d, 0xa3, 0x8b, 0x4b, 0xab,
|
||||||
0x17, 0xa9, 0xa1, 0x7c, 0x4c, 0x0d, 0xe5, 0x4b, 0x6a, 0x28, 0xef, 0xbe, 0x19, 0xca, 0xf3, 0xee,
|
0xf4, 0xf9, 0xd2, 0x2a, 0xbd, 0x4d, 0x2d, 0xed, 0x22, 0xb5, 0xb4, 0x4f, 0xa9, 0xa5, 0x7d, 0x4d,
|
||||||
0x3f, 0x7c, 0x65, 0x1e, 0xcb, 0x9f, 0xd3, 0xca, 0x69, 0x75, 0xa2, 0x65, 0x13, 0xf9, 0xf0, 0x7b,
|
0x2d, 0xed, 0xfd, 0x77, 0x4b, 0x7b, 0xd1, 0xfa, 0x87, 0x7f, 0x9f, 0x27, 0xea, 0xe7, 0xb4, 0x74,
|
||||||
0x00, 0x00, 0x00, 0xff, 0xff, 0x07, 0x69, 0x62, 0x9d, 0xa6, 0x06, 0x00, 0x00,
|
0x5a, 0x1e, 0x1a, 0x59, 0x47, 0x3e, 0xfa, 0x11, 0x00, 0x00, 0xff, 0xff, 0xc5, 0x58, 0x0f, 0xec,
|
||||||
|
0xbe, 0x06, 0x00, 0x00,
|
||||||
}
|
}
|
||||||
|
3
vendor/github.com/containerd/containerd/api/events/task.proto
generated
vendored
3
vendor/github.com/containerd/containerd/api/events/task.proto
generated
vendored
@ -29,6 +29,9 @@ message TaskDelete {
|
|||||||
uint32 pid = 2;
|
uint32 pid = 2;
|
||||||
uint32 exit_status = 3;
|
uint32 exit_status = 3;
|
||||||
google.protobuf.Timestamp exited_at = 4 [(gogoproto.stdtime) = true, (gogoproto.nullable) = false];
|
google.protobuf.Timestamp exited_at = 4 [(gogoproto.stdtime) = true, (gogoproto.nullable) = false];
|
||||||
|
// id is the specific exec. By default if omitted will be `""` thus matches
|
||||||
|
// the init exec of the task matching `container_id`.
|
||||||
|
string id = 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
message TaskIO {
|
message TaskIO {
|
||||||
|
2
vendor/github.com/containerd/containerd/archive/tar.go
generated
vendored
2
vendor/github.com/containerd/containerd/archive/tar.go
generated
vendored
@ -194,7 +194,7 @@ func applyNaive(ctx context.Context, root string, tr *tar.Reader, options ApplyO
|
|||||||
parentPath = filepath.Dir(path)
|
parentPath = filepath.Dir(path)
|
||||||
}
|
}
|
||||||
if _, err := os.Lstat(parentPath); err != nil && os.IsNotExist(err) {
|
if _, err := os.Lstat(parentPath); err != nil && os.IsNotExist(err) {
|
||||||
err = mkdirAll(parentPath, 0700)
|
err = mkdirAll(parentPath, 0755)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
72
vendor/github.com/containerd/containerd/cio/io.go
generated
vendored
72
vendor/github.com/containerd/containerd/cio/io.go
generated
vendored
@ -20,8 +20,8 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/containerd/containerd/defaults"
|
"github.com/containerd/containerd/defaults"
|
||||||
@ -222,46 +222,76 @@ type DirectIO struct {
|
|||||||
cio
|
cio
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ IO = &DirectIO{}
|
var (
|
||||||
|
_ IO = &DirectIO{}
|
||||||
|
_ IO = &logURI{}
|
||||||
|
)
|
||||||
|
|
||||||
// LogFile creates a file on disk that logs the task's STDOUT,STDERR.
|
// LogURI provides the raw logging URI
|
||||||
// If the log file already exists, the logs will be appended to the file.
|
func LogURI(uri *url.URL) Creator {
|
||||||
func LogFile(path string) Creator {
|
|
||||||
return func(_ string) (IO, error) {
|
return func(_ string) (IO, error) {
|
||||||
if err := os.MkdirAll(filepath.Dir(path), 0755); err != nil {
|
return &logURI{
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
f, err := os.OpenFile(path, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
f.Close()
|
|
||||||
return &logIO{
|
|
||||||
config: Config{
|
config: Config{
|
||||||
Stdout: path,
|
Stdout: uri.String(),
|
||||||
Stderr: path,
|
Stderr: uri.String(),
|
||||||
},
|
},
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type logIO struct {
|
// BinaryIO forwards container STDOUT|STDERR directly to a logging binary
|
||||||
|
func BinaryIO(binary string, args map[string]string) Creator {
|
||||||
|
return func(_ string) (IO, error) {
|
||||||
|
uri := &url.URL{
|
||||||
|
Scheme: "binary",
|
||||||
|
Host: binary,
|
||||||
|
}
|
||||||
|
for k, v := range args {
|
||||||
|
uri.Query().Set(k, v)
|
||||||
|
}
|
||||||
|
return &logURI{
|
||||||
|
config: Config{
|
||||||
|
Stdout: uri.String(),
|
||||||
|
Stderr: uri.String(),
|
||||||
|
},
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// LogFile creates a file on disk that logs the task's STDOUT,STDERR.
|
||||||
|
// If the log file already exists, the logs will be appended to the file.
|
||||||
|
func LogFile(path string) Creator {
|
||||||
|
return func(_ string) (IO, error) {
|
||||||
|
uri := &url.URL{
|
||||||
|
Scheme: "file",
|
||||||
|
Host: path,
|
||||||
|
}
|
||||||
|
return &logURI{
|
||||||
|
config: Config{
|
||||||
|
Stdout: uri.String(),
|
||||||
|
Stderr: uri.String(),
|
||||||
|
},
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type logURI struct {
|
||||||
config Config
|
config Config
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *logIO) Config() Config {
|
func (l *logURI) Config() Config {
|
||||||
return l.config
|
return l.config
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *logIO) Cancel() {
|
func (l *logURI) Cancel() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *logIO) Wait() {
|
func (l *logURI) Wait() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *logIO) Close() error {
|
func (l *logURI) Close() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
6
vendor/github.com/containerd/containerd/cio/io_windows.go
generated
vendored
6
vendor/github.com/containerd/containerd/cio/io_windows.go
generated
vendored
@ -31,11 +31,15 @@ const pipeRoot = `\\.\pipe`
|
|||||||
|
|
||||||
// NewFIFOSetInDir returns a new set of fifos for the task
|
// NewFIFOSetInDir returns a new set of fifos for the task
|
||||||
func NewFIFOSetInDir(_, id string, terminal bool) (*FIFOSet, error) {
|
func NewFIFOSetInDir(_, id string, terminal bool) (*FIFOSet, error) {
|
||||||
|
stderrPipe := ""
|
||||||
|
if !terminal {
|
||||||
|
stderrPipe = fmt.Sprintf(`%s\ctr-%s-stderr`, pipeRoot, id)
|
||||||
|
}
|
||||||
return NewFIFOSet(Config{
|
return NewFIFOSet(Config{
|
||||||
Terminal: terminal,
|
Terminal: terminal,
|
||||||
Stdin: fmt.Sprintf(`%s\ctr-%s-stdin`, pipeRoot, id),
|
Stdin: fmt.Sprintf(`%s\ctr-%s-stdin`, pipeRoot, id),
|
||||||
Stdout: fmt.Sprintf(`%s\ctr-%s-stdout`, pipeRoot, id),
|
Stdout: fmt.Sprintf(`%s\ctr-%s-stdout`, pipeRoot, id),
|
||||||
Stderr: fmt.Sprintf(`%s\ctr-%s-stderr`, pipeRoot, id),
|
Stderr: stderrPipe,
|
||||||
}, nil), nil
|
}, nil), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
202
vendor/github.com/containerd/containerd/client.go
generated
vendored
202
vendor/github.com/containerd/containerd/client.go
generated
vendored
@ -24,6 +24,7 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -42,7 +43,6 @@ import (
|
|||||||
"github.com/containerd/containerd/content"
|
"github.com/containerd/containerd/content"
|
||||||
contentproxy "github.com/containerd/containerd/content/proxy"
|
contentproxy "github.com/containerd/containerd/content/proxy"
|
||||||
"github.com/containerd/containerd/defaults"
|
"github.com/containerd/containerd/defaults"
|
||||||
"github.com/containerd/containerd/errdefs"
|
|
||||||
"github.com/containerd/containerd/events"
|
"github.com/containerd/containerd/events"
|
||||||
"github.com/containerd/containerd/images"
|
"github.com/containerd/containerd/images"
|
||||||
"github.com/containerd/containerd/leases"
|
"github.com/containerd/containerd/leases"
|
||||||
@ -53,7 +53,6 @@ import (
|
|||||||
"github.com/containerd/containerd/plugin"
|
"github.com/containerd/containerd/plugin"
|
||||||
"github.com/containerd/containerd/remotes"
|
"github.com/containerd/containerd/remotes"
|
||||||
"github.com/containerd/containerd/remotes/docker"
|
"github.com/containerd/containerd/remotes/docker"
|
||||||
"github.com/containerd/containerd/remotes/docker/schema1"
|
|
||||||
"github.com/containerd/containerd/snapshots"
|
"github.com/containerd/containerd/snapshots"
|
||||||
snproxy "github.com/containerd/containerd/snapshots/proxy"
|
snproxy "github.com/containerd/containerd/snapshots/proxy"
|
||||||
"github.com/containerd/typeurl"
|
"github.com/containerd/typeurl"
|
||||||
@ -61,7 +60,6 @@ import (
|
|||||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||||
specs "github.com/opencontainers/runtime-spec/specs-go"
|
specs "github.com/opencontainers/runtime-spec/specs-go"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"golang.org/x/sync/semaphore"
|
|
||||||
"google.golang.org/grpc"
|
"google.golang.org/grpc"
|
||||||
"google.golang.org/grpc/health/grpc_health_v1"
|
"google.golang.org/grpc/health/grpc_health_v1"
|
||||||
)
|
)
|
||||||
@ -283,6 +281,12 @@ type RemoteContext struct {
|
|||||||
// handlers.
|
// handlers.
|
||||||
BaseHandlers []images.Handler
|
BaseHandlers []images.Handler
|
||||||
|
|
||||||
|
// HandlerWrapper wraps the handler which gets sent to dispatch.
|
||||||
|
// Unlike BaseHandlers, this can run before and after the built
|
||||||
|
// in handlers, allowing operations to run on the descriptor
|
||||||
|
// after it has completed transferring.
|
||||||
|
HandlerWrapper func(images.Handler) images.Handler
|
||||||
|
|
||||||
// ConvertSchema1 is whether to convert Docker registry schema 1
|
// ConvertSchema1 is whether to convert Docker registry schema 1
|
||||||
// manifests. If this option is false then any image which resolves
|
// manifests. If this option is false then any image which resolves
|
||||||
// to schema 1 will return an error since schema 1 is not supported.
|
// to schema 1 will return an error since schema 1 is not supported.
|
||||||
@ -296,6 +300,10 @@ type RemoteContext struct {
|
|||||||
|
|
||||||
// MaxConcurrentDownloads is the max concurrent content downloads for each pull.
|
// MaxConcurrentDownloads is the max concurrent content downloads for each pull.
|
||||||
MaxConcurrentDownloads int
|
MaxConcurrentDownloads int
|
||||||
|
|
||||||
|
// AppendDistributionSourceLabel allows fetcher to add distribute source
|
||||||
|
// label for each blob content, which doesn't work for legacy schema1.
|
||||||
|
AppendDistributionSourceLabel bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func defaultRemoteContext() *RemoteContext {
|
func defaultRemoteContext() *RemoteContext {
|
||||||
@ -347,161 +355,6 @@ func (c *Client) Fetch(ctx context.Context, ref string, opts ...RemoteOpt) (imag
|
|||||||
return c.fetch(ctx, fetchCtx, ref, 0)
|
return c.fetch(ctx, fetchCtx, ref, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pull downloads the provided content into containerd's content store
|
|
||||||
// and returns a platform specific image object
|
|
||||||
func (c *Client) Pull(ctx context.Context, ref string, opts ...RemoteOpt) (Image, error) {
|
|
||||||
pullCtx := defaultRemoteContext()
|
|
||||||
for _, o := range opts {
|
|
||||||
if err := o(c, pullCtx); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if pullCtx.PlatformMatcher == nil {
|
|
||||||
if len(pullCtx.Platforms) > 1 {
|
|
||||||
return nil, errors.New("cannot pull multiplatform image locally, try Fetch")
|
|
||||||
} else if len(pullCtx.Platforms) == 0 {
|
|
||||||
pullCtx.PlatformMatcher = platforms.Default()
|
|
||||||
} else {
|
|
||||||
p, err := platforms.Parse(pullCtx.Platforms[0])
|
|
||||||
if err != nil {
|
|
||||||
return nil, errors.Wrapf(err, "invalid platform %s", pullCtx.Platforms[0])
|
|
||||||
}
|
|
||||||
|
|
||||||
pullCtx.PlatformMatcher = platforms.Only(p)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx, done, err := c.WithLease(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
defer done(ctx)
|
|
||||||
|
|
||||||
img, err := c.fetch(ctx, pullCtx, ref, 1)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
i := NewImageWithPlatform(c, img, pullCtx.PlatformMatcher)
|
|
||||||
|
|
||||||
if pullCtx.Unpack {
|
|
||||||
if err := i.Unpack(ctx, pullCtx.Snapshotter); err != nil {
|
|
||||||
return nil, errors.Wrapf(err, "failed to unpack image on snapshotter %s", pullCtx.Snapshotter)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return i, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Client) fetch(ctx context.Context, rCtx *RemoteContext, ref string, limit int) (images.Image, error) {
|
|
||||||
store := c.ContentStore()
|
|
||||||
name, desc, err := rCtx.Resolver.Resolve(ctx, ref)
|
|
||||||
if err != nil {
|
|
||||||
return images.Image{}, errors.Wrapf(err, "failed to resolve reference %q", ref)
|
|
||||||
}
|
|
||||||
|
|
||||||
fetcher, err := rCtx.Resolver.Fetcher(ctx, name)
|
|
||||||
if err != nil {
|
|
||||||
return images.Image{}, errors.Wrapf(err, "failed to get fetcher for %q", name)
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
handler images.Handler
|
|
||||||
|
|
||||||
isConvertible bool
|
|
||||||
converterFunc func(context.Context, ocispec.Descriptor) (ocispec.Descriptor, error)
|
|
||||||
limiter *semaphore.Weighted
|
|
||||||
)
|
|
||||||
|
|
||||||
if desc.MediaType == images.MediaTypeDockerSchema1Manifest && rCtx.ConvertSchema1 {
|
|
||||||
schema1Converter := schema1.NewConverter(store, fetcher)
|
|
||||||
|
|
||||||
handler = images.Handlers(append(rCtx.BaseHandlers, schema1Converter)...)
|
|
||||||
|
|
||||||
isConvertible = true
|
|
||||||
|
|
||||||
converterFunc = func(ctx context.Context, _ ocispec.Descriptor) (ocispec.Descriptor, error) {
|
|
||||||
return schema1Converter.Convert(ctx)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Get all the children for a descriptor
|
|
||||||
childrenHandler := images.ChildrenHandler(store)
|
|
||||||
// Set any children labels for that content
|
|
||||||
childrenHandler = images.SetChildrenLabels(store, childrenHandler)
|
|
||||||
// Filter children by platforms
|
|
||||||
childrenHandler = images.FilterPlatforms(childrenHandler, rCtx.PlatformMatcher)
|
|
||||||
// Sort and limit manifests if a finite number is needed
|
|
||||||
if limit > 0 {
|
|
||||||
childrenHandler = images.LimitManifests(childrenHandler, rCtx.PlatformMatcher, limit)
|
|
||||||
}
|
|
||||||
|
|
||||||
// set isConvertible to true if there is application/octet-stream media type
|
|
||||||
convertibleHandler := images.HandlerFunc(
|
|
||||||
func(_ context.Context, desc ocispec.Descriptor) ([]ocispec.Descriptor, error) {
|
|
||||||
if desc.MediaType == docker.LegacyConfigMediaType {
|
|
||||||
isConvertible = true
|
|
||||||
}
|
|
||||||
|
|
||||||
return []ocispec.Descriptor{}, nil
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
handler = images.Handlers(append(rCtx.BaseHandlers,
|
|
||||||
remotes.FetchHandler(store, fetcher),
|
|
||||||
convertibleHandler,
|
|
||||||
childrenHandler,
|
|
||||||
)...)
|
|
||||||
|
|
||||||
converterFunc = func(ctx context.Context, desc ocispec.Descriptor) (ocispec.Descriptor, error) {
|
|
||||||
return docker.ConvertManifest(ctx, store, desc)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if rCtx.MaxConcurrentDownloads > 0 {
|
|
||||||
limiter = semaphore.NewWeighted(int64(rCtx.MaxConcurrentDownloads))
|
|
||||||
}
|
|
||||||
if err := images.Dispatch(ctx, handler, limiter, desc); err != nil {
|
|
||||||
return images.Image{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if isConvertible {
|
|
||||||
if desc, err = converterFunc(ctx, desc); err != nil {
|
|
||||||
return images.Image{}, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
img := images.Image{
|
|
||||||
Name: name,
|
|
||||||
Target: desc,
|
|
||||||
Labels: rCtx.Labels,
|
|
||||||
}
|
|
||||||
|
|
||||||
is := c.ImageService()
|
|
||||||
for {
|
|
||||||
if created, err := is.Create(ctx, img); err != nil {
|
|
||||||
if !errdefs.IsAlreadyExists(err) {
|
|
||||||
return images.Image{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
updated, err := is.Update(ctx, img)
|
|
||||||
if err != nil {
|
|
||||||
// if image was removed, try create again
|
|
||||||
if errdefs.IsNotFound(err) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
return images.Image{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
img = updated
|
|
||||||
} else {
|
|
||||||
img = created
|
|
||||||
}
|
|
||||||
|
|
||||||
return img, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Push uploads the provided content to a remote resource
|
// Push uploads the provided content to a remote resource
|
||||||
func (c *Client) Push(ctx context.Context, ref string, desc ocispec.Descriptor, opts ...RemoteOpt) error {
|
func (c *Client) Push(ctx context.Context, ref string, desc ocispec.Descriptor, opts ...RemoteOpt) error {
|
||||||
pushCtx := defaultRemoteContext()
|
pushCtx := defaultRemoteContext()
|
||||||
@ -531,7 +384,21 @@ func (c *Client) Push(ctx context.Context, ref string, desc ocispec.Descriptor,
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return remotes.PushContent(ctx, pusher, desc, c.ContentStore(), pushCtx.PlatformMatcher, pushCtx.BaseHandlers...)
|
var wrapper func(images.Handler) images.Handler
|
||||||
|
|
||||||
|
if len(pushCtx.BaseHandlers) > 0 {
|
||||||
|
wrapper = func(h images.Handler) images.Handler {
|
||||||
|
h = images.Handlers(append(pushCtx.BaseHandlers, h)...)
|
||||||
|
if pushCtx.HandlerWrapper != nil {
|
||||||
|
h = pushCtx.HandlerWrapper(h)
|
||||||
|
}
|
||||||
|
return h
|
||||||
|
}
|
||||||
|
} else if pushCtx.HandlerWrapper != nil {
|
||||||
|
wrapper = pushCtx.HandlerWrapper
|
||||||
|
}
|
||||||
|
|
||||||
|
return remotes.PushContent(ctx, pusher, desc, c.ContentStore(), pushCtx.PlatformMatcher, wrapper)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetImage returns an existing image
|
// GetImage returns an existing image
|
||||||
@ -752,3 +619,20 @@ func (c *Client) Version(ctx context.Context) (Version, error) {
|
|||||||
Revision: response.Revision,
|
Revision: response.Revision,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CheckRuntime returns true if the current runtime matches the expected
|
||||||
|
// runtime. Providing various parts of the runtime schema will match those
|
||||||
|
// parts of the expected runtime
|
||||||
|
func CheckRuntime(current, expected string) bool {
|
||||||
|
cp := strings.Split(current, ".")
|
||||||
|
l := len(cp)
|
||||||
|
for i, p := range strings.Split(expected, ".") {
|
||||||
|
if i > l {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if p != cp[i] {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
17
vendor/github.com/containerd/containerd/client_opts.go
generated
vendored
17
vendor/github.com/containerd/containerd/client_opts.go
generated
vendored
@ -179,6 +179,14 @@ func WithImageHandler(h images.Handler) RemoteOpt {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithImageHandlerWrapper wraps the handlers to be called on dispatch.
|
||||||
|
func WithImageHandlerWrapper(w func(images.Handler) images.Handler) RemoteOpt {
|
||||||
|
return func(client *Client, c *RemoteContext) error {
|
||||||
|
c.HandlerWrapper = w
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// WithMaxConcurrentDownloads sets max concurrent download limit.
|
// WithMaxConcurrentDownloads sets max concurrent download limit.
|
||||||
func WithMaxConcurrentDownloads(max int) RemoteOpt {
|
func WithMaxConcurrentDownloads(max int) RemoteOpt {
|
||||||
return func(client *Client, c *RemoteContext) error {
|
return func(client *Client, c *RemoteContext) error {
|
||||||
@ -186,3 +194,12 @@ func WithMaxConcurrentDownloads(max int) RemoteOpt {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithAppendDistributionSourceLabel allows fetcher to add distribute source
|
||||||
|
// label for each blob content, which doesn't work for legacy schema1.
|
||||||
|
func WithAppendDistributionSourceLabel() RemoteOpt {
|
||||||
|
return func(_ *Client, c *RemoteContext) error {
|
||||||
|
c.AppendDistributionSourceLabel = true
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
12
vendor/github.com/containerd/containerd/cmd/containerd/command/main_windows.go
generated
vendored
12
vendor/github.com/containerd/containerd/cmd/containerd/command/main_windows.go
generated
vendored
@ -24,6 +24,7 @@ import (
|
|||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
winio "github.com/Microsoft/go-winio"
|
winio "github.com/Microsoft/go-winio"
|
||||||
|
"github.com/Microsoft/go-winio/pkg/etwlogrus"
|
||||||
"github.com/containerd/containerd/log"
|
"github.com/containerd/containerd/log"
|
||||||
"github.com/containerd/containerd/services/server"
|
"github.com/containerd/containerd/services/server"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
@ -65,7 +66,7 @@ func setupDumpStacks() {
|
|||||||
// Windows does not support signals like *nix systems. So instead of
|
// Windows does not support signals like *nix systems. So instead of
|
||||||
// trapping on SIGUSR1 to dump stacks, we wait on a Win32 event to be
|
// trapping on SIGUSR1 to dump stacks, we wait on a Win32 event to be
|
||||||
// signaled. ACL'd to builtin administrators and local system
|
// signaled. ACL'd to builtin administrators and local system
|
||||||
event := "Global\\containerd-daemon-" + fmt.Sprint(os.Getpid())
|
event := "Global\\stackdump-" + fmt.Sprint(os.Getpid())
|
||||||
ev, _ := windows.UTF16PtrFromString(event)
|
ev, _ := windows.UTF16PtrFromString(event)
|
||||||
sd, err := winio.SddlToSecurityDescriptor("D:P(A;;GA;;;BA)(A;;GA;;;SY)")
|
sd, err := winio.SddlToSecurityDescriptor("D:P(A;;GA;;;BA)(A;;GA;;;SY)")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -89,3 +90,12 @@ func setupDumpStacks() {
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
// Provider ID: {2acb92c0-eb9b-571a-69cf-8f3410f383ad}
|
||||||
|
// Hook isn't closed explicitly, as it will exist until process exit.
|
||||||
|
// GUID is generated based on name - see Microsoft/go-winio/tools/etw-provider-gen.
|
||||||
|
if hook, err := etwlogrus.NewHook("ContainerD"); err == nil {
|
||||||
|
logrus.AddHook(hook)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
2
vendor/github.com/containerd/containerd/cmd/containerd/command/service_windows.go
generated
vendored
2
vendor/github.com/containerd/containerd/cmd/containerd/command/service_windows.go
generated
vendored
@ -88,7 +88,7 @@ func serviceFlags() []cli.Flag {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// applyPlatformFlags applys platform-specific flags.
|
// applyPlatformFlags applies platform-specific flags.
|
||||||
func applyPlatformFlags(context *cli.Context) {
|
func applyPlatformFlags(context *cli.Context) {
|
||||||
|
|
||||||
if s := context.GlobalString("service-name"); s != "" {
|
if s := context.GlobalString("service-name"); s != "" {
|
||||||
|
3
vendor/github.com/containerd/containerd/cmd/ctr/commands/content/fetch.go
generated
vendored
3
vendor/github.com/containerd/containerd/cmd/ctr/commands/content/fetch.go
generated
vendored
@ -149,10 +149,13 @@ func Fetch(ctx context.Context, client *containerd.Client, ref string, config *F
|
|||||||
containerd.WithResolver(config.Resolver),
|
containerd.WithResolver(config.Resolver),
|
||||||
containerd.WithImageHandler(h),
|
containerd.WithImageHandler(h),
|
||||||
containerd.WithSchema1Conversion,
|
containerd.WithSchema1Conversion,
|
||||||
|
containerd.WithAppendDistributionSourceLabel(),
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, platform := range config.Platforms {
|
for _, platform := range config.Platforms {
|
||||||
opts = append(opts, containerd.WithPlatform(platform))
|
opts = append(opts, containerd.WithPlatform(platform))
|
||||||
}
|
}
|
||||||
|
|
||||||
img, err := client.Fetch(pctx, ref, opts...)
|
img, err := client.Fetch(pctx, ref, opts...)
|
||||||
stopProgress()
|
stopProgress()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
66
vendor/github.com/containerd/containerd/cmd/ctr/commands/images/push.go
generated
vendored
66
vendor/github.com/containerd/containerd/cmd/ctr/commands/images/push.go
generated
vendored
@ -63,16 +63,19 @@ var pushCommand = cli.Command{
|
|||||||
var (
|
var (
|
||||||
ref = context.Args().First()
|
ref = context.Args().First()
|
||||||
local = context.Args().Get(1)
|
local = context.Args().Get(1)
|
||||||
|
debug = context.GlobalBool("debug")
|
||||||
desc ocispec.Descriptor
|
desc ocispec.Descriptor
|
||||||
)
|
)
|
||||||
if ref == "" {
|
if ref == "" {
|
||||||
return errors.New("please provide a remote image reference to push")
|
return errors.New("please provide a remote image reference to push")
|
||||||
}
|
}
|
||||||
|
|
||||||
client, ctx, cancel, err := commands.NewClient(context)
|
client, ctx, cancel, err := commands.NewClient(context)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
if manifest := context.String("manifest"); manifest != "" {
|
if manifest := context.String("manifest"); manifest != "" {
|
||||||
desc.Digest, err = digest.Parse(manifest)
|
desc.Digest, err = digest.Parse(manifest)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -98,7 +101,12 @@ var pushCommand = cli.Command{
|
|||||||
|
|
||||||
eg, ctx := errgroup.WithContext(ctx)
|
eg, ctx := errgroup.WithContext(ctx)
|
||||||
|
|
||||||
|
// used to notify the progress writer
|
||||||
|
doneCh := make(chan struct{})
|
||||||
|
|
||||||
eg.Go(func() error {
|
eg.Go(func() error {
|
||||||
|
defer close(doneCh)
|
||||||
|
|
||||||
log.G(ctx).WithField("image", ref).WithField("digest", desc.Digest).Debug("pushing")
|
log.G(ctx).WithField("image", ref).WithField("digest", desc.Digest).Debug("pushing")
|
||||||
|
|
||||||
jobHandler := images.HandlerFunc(func(ctx gocontext.Context, desc ocispec.Descriptor) ([]ocispec.Descriptor, error) {
|
jobHandler := images.HandlerFunc(func(ctx gocontext.Context, desc ocispec.Descriptor) ([]ocispec.Descriptor, error) {
|
||||||
@ -112,43 +120,41 @@ var pushCommand = cli.Command{
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
errs := make(chan error)
|
// don't show progress if debug mode is set
|
||||||
go func() {
|
if !debug {
|
||||||
defer close(errs)
|
eg.Go(func() error {
|
||||||
errs <- eg.Wait()
|
var (
|
||||||
}()
|
ticker = time.NewTicker(100 * time.Millisecond)
|
||||||
|
fw = progress.NewWriter(os.Stdout)
|
||||||
|
start = time.Now()
|
||||||
|
done bool
|
||||||
|
)
|
||||||
|
|
||||||
var (
|
defer ticker.Stop()
|
||||||
ticker = time.NewTicker(100 * time.Millisecond)
|
|
||||||
fw = progress.NewWriter(os.Stdout)
|
|
||||||
start = time.Now()
|
|
||||||
done bool
|
|
||||||
)
|
|
||||||
defer ticker.Stop()
|
|
||||||
|
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-ticker.C:
|
case <-ticker.C:
|
||||||
fw.Flush()
|
fw.Flush()
|
||||||
|
|
||||||
tw := tabwriter.NewWriter(fw, 1, 8, 1, ' ', 0)
|
tw := tabwriter.NewWriter(fw, 1, 8, 1, ' ', 0)
|
||||||
|
|
||||||
content.Display(tw, ongoing.status(), start)
|
content.Display(tw, ongoing.status(), start)
|
||||||
tw.Flush()
|
tw.Flush()
|
||||||
|
|
||||||
if done {
|
if done {
|
||||||
fw.Flush()
|
fw.Flush()
|
||||||
return nil
|
return nil
|
||||||
|
}
|
||||||
|
case <-doneCh:
|
||||||
|
done = true
|
||||||
|
case <-ctx.Done():
|
||||||
|
done = true // allow ui to update once more
|
||||||
|
}
|
||||||
}
|
}
|
||||||
case err := <-errs:
|
})
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
done = true
|
|
||||||
case <-ctx.Done():
|
|
||||||
done = true // allow ui to update once more
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
return eg.Wait()
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
6
vendor/github.com/containerd/containerd/cmd/ctr/commands/run/run.go
generated
vendored
6
vendor/github.com/containerd/containerd/cmd/ctr/commands/run/run.go
generated
vendored
@ -99,6 +99,10 @@ var Command = cli.Command{
|
|||||||
Name: "null-io",
|
Name: "null-io",
|
||||||
Usage: "send all IO to /dev/null",
|
Usage: "send all IO to /dev/null",
|
||||||
},
|
},
|
||||||
|
cli.StringFlag{
|
||||||
|
Name: "log-uri",
|
||||||
|
Usage: "log uri",
|
||||||
|
},
|
||||||
cli.BoolFlag{
|
cli.BoolFlag{
|
||||||
Name: "detach,d",
|
Name: "detach,d",
|
||||||
Usage: "detach from the task after it has started execution",
|
Usage: "detach from the task after it has started execution",
|
||||||
@ -161,7 +165,7 @@ var Command = cli.Command{
|
|||||||
}
|
}
|
||||||
opts := getNewTaskOpts(context)
|
opts := getNewTaskOpts(context)
|
||||||
ioOpts := []cio.Opt{cio.WithFIFODir(context.String("fifo-dir"))}
|
ioOpts := []cio.Opt{cio.WithFIFODir(context.String("fifo-dir"))}
|
||||||
task, err := tasks.NewTask(ctx, client, container, context.String("checkpoint"), con, context.Bool("null-io"), ioOpts, opts...)
|
task, err := tasks.NewTask(ctx, client, container, context.String("checkpoint"), con, context.Bool("null-io"), context.String("log-uri"), ioOpts, opts...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
1
vendor/github.com/containerd/containerd/cmd/ctr/commands/run/run_unix.go
generated
vendored
1
vendor/github.com/containerd/containerd/cmd/ctr/commands/run/run_unix.go
generated
vendored
@ -147,6 +147,7 @@ func NewContainer(ctx gocontext.Context, client *containerd.Client, context *cli
|
|||||||
|
|
||||||
cOpts = append(cOpts, containerd.WithRuntime(context.String("runtime"), nil))
|
cOpts = append(cOpts, containerd.WithRuntime(context.String("runtime"), nil))
|
||||||
|
|
||||||
|
opts = append(opts, oci.WithAnnotations(commands.LabelArgs(context.StringSlice("label"))))
|
||||||
var s specs.Spec
|
var s specs.Spec
|
||||||
spec = containerd.WithSpec(&s, opts...)
|
spec = containerd.WithSpec(&s, opts...)
|
||||||
|
|
||||||
|
5
vendor/github.com/containerd/containerd/cmd/ctr/commands/tasks/checkpoint.go
generated
vendored
5
vendor/github.com/containerd/containerd/cmd/ctr/commands/tasks/checkpoint.go
generated
vendored
@ -21,6 +21,7 @@ import (
|
|||||||
|
|
||||||
"github.com/containerd/containerd"
|
"github.com/containerd/containerd"
|
||||||
"github.com/containerd/containerd/cmd/ctr/commands"
|
"github.com/containerd/containerd/cmd/ctr/commands"
|
||||||
|
"github.com/containerd/containerd/plugin"
|
||||||
"github.com/containerd/containerd/runtime/linux/runctypes"
|
"github.com/containerd/containerd/runtime/linux/runctypes"
|
||||||
"github.com/containerd/containerd/runtime/v2/runc/options"
|
"github.com/containerd/containerd/runtime/v2/runc/options"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
@ -86,7 +87,7 @@ func withCheckpointOpts(rt string, context *cli.Context) containerd.CheckpointTa
|
|||||||
workPath := context.String("work-path")
|
workPath := context.String("work-path")
|
||||||
|
|
||||||
switch rt {
|
switch rt {
|
||||||
case "io.containerd.runc.v1":
|
case plugin.RuntimeRuncV1, plugin.RuntimeRuncV2:
|
||||||
if r.Options == nil {
|
if r.Options == nil {
|
||||||
r.Options = &options.CheckpointOptions{}
|
r.Options = &options.CheckpointOptions{}
|
||||||
}
|
}
|
||||||
@ -101,7 +102,7 @@ func withCheckpointOpts(rt string, context *cli.Context) containerd.CheckpointTa
|
|||||||
if workPath != "" {
|
if workPath != "" {
|
||||||
opts.WorkPath = workPath
|
opts.WorkPath = workPath
|
||||||
}
|
}
|
||||||
case "io.containerd.runtime.v1.linux":
|
case plugin.RuntimeLinuxV1:
|
||||||
if r.Options == nil {
|
if r.Options == nil {
|
||||||
r.Options = &runctypes.CheckpointOptions{}
|
r.Options = &runctypes.CheckpointOptions{}
|
||||||
}
|
}
|
||||||
|
6
vendor/github.com/containerd/containerd/cmd/ctr/commands/tasks/start.go
generated
vendored
6
vendor/github.com/containerd/containerd/cmd/ctr/commands/tasks/start.go
generated
vendored
@ -35,6 +35,10 @@ var startCommand = cli.Command{
|
|||||||
Name: "null-io",
|
Name: "null-io",
|
||||||
Usage: "send all IO to /dev/null",
|
Usage: "send all IO to /dev/null",
|
||||||
},
|
},
|
||||||
|
cli.StringFlag{
|
||||||
|
Name: "log-uri",
|
||||||
|
Usage: "log uri",
|
||||||
|
},
|
||||||
cli.StringFlag{
|
cli.StringFlag{
|
||||||
Name: "fifo-dir",
|
Name: "fifo-dir",
|
||||||
Usage: "directory used for storing IO FIFOs",
|
Usage: "directory used for storing IO FIFOs",
|
||||||
@ -85,7 +89,7 @@ var startCommand = cli.Command{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
task, err := NewTask(ctx, client, container, "", con, context.Bool("null-io"), ioOpts, opts...)
|
task, err := NewTask(ctx, client, container, "", con, context.Bool("null-io"), context.String("log-uri"), ioOpts, opts...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
10
vendor/github.com/containerd/containerd/cmd/ctr/commands/tasks/tasks_unix.go
generated
vendored
10
vendor/github.com/containerd/containerd/cmd/ctr/commands/tasks/tasks_unix.go
generated
vendored
@ -20,6 +20,7 @@ package tasks
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
gocontext "context"
|
gocontext "context"
|
||||||
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
|
|
||||||
@ -67,7 +68,7 @@ func HandleConsoleResize(ctx gocontext.Context, task resizer, con console.Consol
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewTask creates a new task
|
// NewTask creates a new task
|
||||||
func NewTask(ctx gocontext.Context, client *containerd.Client, container containerd.Container, checkpoint string, con console.Console, nullIO bool, ioOpts []cio.Opt, opts ...containerd.NewTaskOpts) (containerd.Task, error) {
|
func NewTask(ctx gocontext.Context, client *containerd.Client, container containerd.Container, checkpoint string, con console.Console, nullIO bool, logURI string, ioOpts []cio.Opt, opts ...containerd.NewTaskOpts) (containerd.Task, error) {
|
||||||
stdio := cio.NewCreator(append([]cio.Opt{cio.WithStdio}, ioOpts...)...)
|
stdio := cio.NewCreator(append([]cio.Opt{cio.WithStdio}, ioOpts...)...)
|
||||||
if checkpoint != "" {
|
if checkpoint != "" {
|
||||||
im, err := client.GetImage(ctx, checkpoint)
|
im, err := client.GetImage(ctx, checkpoint)
|
||||||
@ -86,6 +87,13 @@ func NewTask(ctx gocontext.Context, client *containerd.Client, container contain
|
|||||||
}
|
}
|
||||||
ioCreator = cio.NullIO
|
ioCreator = cio.NullIO
|
||||||
}
|
}
|
||||||
|
if logURI != "" {
|
||||||
|
u, err := url.Parse(logURI)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
ioCreator = cio.LogURI(u)
|
||||||
|
}
|
||||||
return container.NewTask(ctx, ioCreator, opts...)
|
return container.NewTask(ctx, ioCreator, opts...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
4
vendor/github.com/containerd/containerd/cmd/ctr/commands/tasks/tasks_windows.go
generated
vendored
4
vendor/github.com/containerd/containerd/cmd/ctr/commands/tasks/tasks_windows.go
generated
vendored
@ -58,13 +58,13 @@ func HandleConsoleResize(ctx gocontext.Context, task resizer, con console.Consol
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewTask creates a new task
|
// NewTask creates a new task
|
||||||
func NewTask(ctx gocontext.Context, client *containerd.Client, container containerd.Container, _ string, con console.Console, nullIO bool, ioOpts []cio.Opt, opts ...containerd.NewTaskOpts) (containerd.Task, error) {
|
func NewTask(ctx gocontext.Context, client *containerd.Client, container containerd.Container, _ string, con console.Console, nullIO bool, logURI string, ioOpts []cio.Opt, opts ...containerd.NewTaskOpts) (containerd.Task, error) {
|
||||||
var ioCreator cio.Creator
|
var ioCreator cio.Creator
|
||||||
if con != nil {
|
if con != nil {
|
||||||
if nullIO {
|
if nullIO {
|
||||||
return nil, errors.New("tty and null-io cannot be used together")
|
return nil, errors.New("tty and null-io cannot be used together")
|
||||||
}
|
}
|
||||||
ioCreator = cio.NewCreator(append([]cio.Opt{cio.WithStreams(con, con, con), cio.WithTerminal}, ioOpts...)...)
|
ioCreator = cio.NewCreator(append([]cio.Opt{cio.WithStreams(con, con, nil), cio.WithTerminal}, ioOpts...)...)
|
||||||
} else if nullIO {
|
} else if nullIO {
|
||||||
ioCreator = cio.NullIO
|
ioCreator = cio.NullIO
|
||||||
} else {
|
} else {
|
||||||
|
4
vendor/github.com/containerd/containerd/container.go
generated
vendored
4
vendor/github.com/containerd/containerd/container.go
generated
vendored
@ -229,7 +229,9 @@ func (c *container) NewTask(ctx context.Context, ioCreate cio.Creator, opts ...N
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var info TaskInfo
|
info := TaskInfo{
|
||||||
|
runtime: r.Runtime.Name,
|
||||||
|
}
|
||||||
for _, o := range opts {
|
for _, o := range opts {
|
||||||
if err := o(ctx, c.client, &info); err != nil {
|
if err := o(ctx, c.client, &info); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
9
vendor/github.com/containerd/containerd/container_opts.go
generated
vendored
9
vendor/github.com/containerd/containerd/container_opts.go
generated
vendored
@ -23,6 +23,7 @@ import (
|
|||||||
"github.com/containerd/containerd/errdefs"
|
"github.com/containerd/containerd/errdefs"
|
||||||
"github.com/containerd/containerd/oci"
|
"github.com/containerd/containerd/oci"
|
||||||
"github.com/containerd/containerd/platforms"
|
"github.com/containerd/containerd/platforms"
|
||||||
|
"github.com/containerd/containerd/snapshots"
|
||||||
"github.com/containerd/typeurl"
|
"github.com/containerd/typeurl"
|
||||||
"github.com/gogo/protobuf/types"
|
"github.com/gogo/protobuf/types"
|
||||||
"github.com/opencontainers/image-spec/identity"
|
"github.com/opencontainers/image-spec/identity"
|
||||||
@ -118,7 +119,7 @@ func WithSnapshot(id string) NewContainerOpts {
|
|||||||
|
|
||||||
// WithNewSnapshot allocates a new snapshot to be used by the container as the
|
// WithNewSnapshot allocates a new snapshot to be used by the container as the
|
||||||
// root filesystem in read-write mode
|
// root filesystem in read-write mode
|
||||||
func WithNewSnapshot(id string, i Image) NewContainerOpts {
|
func WithNewSnapshot(id string, i Image, opts ...snapshots.Opt) NewContainerOpts {
|
||||||
return func(ctx context.Context, client *Client, c *containers.Container) error {
|
return func(ctx context.Context, client *Client, c *containers.Container) error {
|
||||||
diffIDs, err := i.(*image).i.RootFS(ctx, client.ContentStore(), platforms.Default())
|
diffIDs, err := i.(*image).i.RootFS(ctx, client.ContentStore(), platforms.Default())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -126,7 +127,7 @@ func WithNewSnapshot(id string, i Image) NewContainerOpts {
|
|||||||
}
|
}
|
||||||
setSnapshotterIfEmpty(c)
|
setSnapshotterIfEmpty(c)
|
||||||
parent := identity.ChainID(diffIDs).String()
|
parent := identity.ChainID(diffIDs).String()
|
||||||
if _, err := client.SnapshotService(c.Snapshotter).Prepare(ctx, id, parent); err != nil {
|
if _, err := client.SnapshotService(c.Snapshotter).Prepare(ctx, id, parent, opts...); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
c.SnapshotKey = id
|
c.SnapshotKey = id
|
||||||
@ -148,7 +149,7 @@ func WithSnapshotCleanup(ctx context.Context, client *Client, c containers.Conta
|
|||||||
|
|
||||||
// WithNewSnapshotView allocates a new snapshot to be used by the container as the
|
// WithNewSnapshotView allocates a new snapshot to be used by the container as the
|
||||||
// root filesystem in read-only mode
|
// root filesystem in read-only mode
|
||||||
func WithNewSnapshotView(id string, i Image) NewContainerOpts {
|
func WithNewSnapshotView(id string, i Image, opts ...snapshots.Opt) NewContainerOpts {
|
||||||
return func(ctx context.Context, client *Client, c *containers.Container) error {
|
return func(ctx context.Context, client *Client, c *containers.Container) error {
|
||||||
diffIDs, err := i.(*image).i.RootFS(ctx, client.ContentStore(), platforms.Default())
|
diffIDs, err := i.(*image).i.RootFS(ctx, client.ContentStore(), platforms.Default())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -156,7 +157,7 @@ func WithNewSnapshotView(id string, i Image) NewContainerOpts {
|
|||||||
}
|
}
|
||||||
setSnapshotterIfEmpty(c)
|
setSnapshotterIfEmpty(c)
|
||||||
parent := identity.ChainID(diffIDs).String()
|
parent := identity.ChainID(diffIDs).String()
|
||||||
if _, err := client.SnapshotService(c.Snapshotter).View(ctx, id, parent); err != nil {
|
if _, err := client.SnapshotService(c.Snapshotter).View(ctx, id, parent, opts...); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
c.SnapshotKey = id
|
c.SnapshotKey = id
|
||||||
|
4
vendor/github.com/containerd/containerd/containers/containers.go
generated
vendored
4
vendor/github.com/containerd/containerd/containers/containers.go
generated
vendored
@ -86,6 +86,10 @@ type RuntimeInfo struct {
|
|||||||
|
|
||||||
// Store interacts with the underlying container storage
|
// Store interacts with the underlying container storage
|
||||||
type Store interface {
|
type Store interface {
|
||||||
|
// Get a container using the id.
|
||||||
|
//
|
||||||
|
// Container object is returned on success. If the id is not known to the
|
||||||
|
// store, an error will be returned.
|
||||||
Get(ctx context.Context, id string) (Container, error)
|
Get(ctx context.Context, id string) (Container, error)
|
||||||
|
|
||||||
// List returns containers that match one or more of the provided filters.
|
// List returns containers that match one or more of the provided filters.
|
||||||
|
24
vendor/github.com/containerd/containerd/contrib/nvidia/nvidia.go
generated
vendored
24
vendor/github.com/containerd/containerd/contrib/nvidia/nvidia.go
generated
vendored
@ -29,7 +29,8 @@ import (
|
|||||||
specs "github.com/opencontainers/runtime-spec/specs-go"
|
specs "github.com/opencontainers/runtime-spec/specs-go"
|
||||||
)
|
)
|
||||||
|
|
||||||
const nvidiaCLI = "nvidia-container-cli"
|
// NvidiaCLI is the path to the Nvidia helper binary
|
||||||
|
const NvidiaCLI = "nvidia-container-cli"
|
||||||
|
|
||||||
// Capability specifies capabilities for the gpu inside the container
|
// Capability specifies capabilities for the gpu inside the container
|
||||||
// Detailed explanation of options can be found:
|
// Detailed explanation of options can be found:
|
||||||
@ -51,13 +52,16 @@ const (
|
|||||||
Display Capability = "display"
|
Display Capability = "display"
|
||||||
)
|
)
|
||||||
|
|
||||||
var allCaps = []Capability{
|
// AllCaps returns the complete list of supported Nvidia capabilties.
|
||||||
Compute,
|
func AllCaps() []Capability {
|
||||||
Compat32,
|
return []Capability{
|
||||||
Graphics,
|
Compute,
|
||||||
Utility,
|
Compat32,
|
||||||
Video,
|
Graphics,
|
||||||
Display,
|
Utility,
|
||||||
|
Video,
|
||||||
|
Display,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithGPUs adds NVIDIA gpu support to a container
|
// WithGPUs adds NVIDIA gpu support to a container
|
||||||
@ -76,7 +80,7 @@ func WithGPUs(opts ...Opts) oci.SpecOpts {
|
|||||||
}
|
}
|
||||||
c.OCIHookPath = path
|
c.OCIHookPath = path
|
||||||
}
|
}
|
||||||
nvidiaPath, err := exec.LookPath(nvidiaCLI)
|
nvidiaPath, err := exec.LookPath(NvidiaCLI)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -166,7 +170,7 @@ func WithAllDevices(c *config) error {
|
|||||||
|
|
||||||
// WithAllCapabilities adds all capabilities to the container for the gpus
|
// WithAllCapabilities adds all capabilities to the container for the gpus
|
||||||
func WithAllCapabilities(c *config) error {
|
func WithAllCapabilities(c *config) error {
|
||||||
c.Capabilities = allCaps
|
c.Capabilities = AllCaps()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
138
vendor/github.com/containerd/containerd/metadata/gc.go
generated
vendored
138
vendor/github.com/containerd/containerd/metadata/gc.go
generated
vendored
@ -64,6 +64,18 @@ func scanRoots(ctx context.Context, tx *bolt.Tx, nc chan<- gc.Node) error {
|
|||||||
// iterate through each namespace
|
// iterate through each namespace
|
||||||
v1c := v1bkt.Cursor()
|
v1c := v1bkt.Cursor()
|
||||||
|
|
||||||
|
// cerr indicates the scan did not successfully send all
|
||||||
|
// the roots. The scan does not need to be cancelled but
|
||||||
|
// must return error at the end.
|
||||||
|
var cerr error
|
||||||
|
fn := func(n gc.Node) {
|
||||||
|
select {
|
||||||
|
case nc <- n:
|
||||||
|
case <-ctx.Done():
|
||||||
|
cerr = ctx.Err()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for k, v := v1c.First(); k != nil; k, v = v1c.Next() {
|
for k, v := v1c.First(); k != nil; k, v = v1c.Next() {
|
||||||
if v != nil {
|
if v != nil {
|
||||||
continue
|
continue
|
||||||
@ -92,11 +104,7 @@ func scanRoots(ctx context.Context, tx *bolt.Tx, nc chan<- gc.Node) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
select {
|
fn(gcnode(ResourceLease, ns, string(k)))
|
||||||
case nc <- gcnode(ResourceLease, ns, string(k)):
|
|
||||||
case <-ctx.Done():
|
|
||||||
return ctx.Err()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Emit content and snapshots as roots instead of implementing
|
// Emit content and snapshots as roots instead of implementing
|
||||||
// in references. Since leases cannot be referenced there is
|
// in references. Since leases cannot be referenced there is
|
||||||
@ -106,11 +114,7 @@ func scanRoots(ctx context.Context, tx *bolt.Tx, nc chan<- gc.Node) error {
|
|||||||
cbkt := libkt.Bucket(bucketKeyObjectContent)
|
cbkt := libkt.Bucket(bucketKeyObjectContent)
|
||||||
if cbkt != nil {
|
if cbkt != nil {
|
||||||
if err := cbkt.ForEach(func(k, v []byte) error {
|
if err := cbkt.ForEach(func(k, v []byte) error {
|
||||||
select {
|
fn(gcnode(ResourceContent, ns, string(k)))
|
||||||
case nc <- gcnode(ResourceContent, ns, string(k)):
|
|
||||||
case <-ctx.Done():
|
|
||||||
return ctx.Err()
|
|
||||||
}
|
|
||||||
return nil
|
return nil
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
return err
|
return err
|
||||||
@ -126,11 +130,7 @@ func scanRoots(ctx context.Context, tx *bolt.Tx, nc chan<- gc.Node) error {
|
|||||||
snbkt := sbkt.Bucket(sk)
|
snbkt := sbkt.Bucket(sk)
|
||||||
|
|
||||||
return snbkt.ForEach(func(k, v []byte) error {
|
return snbkt.ForEach(func(k, v []byte) error {
|
||||||
select {
|
fn(gcnode(ResourceSnapshot, ns, fmt.Sprintf("%s/%s", sk, k)))
|
||||||
case nc <- gcnode(ResourceSnapshot, ns, fmt.Sprintf("%s/%s", sk, k)):
|
|
||||||
case <-ctx.Done():
|
|
||||||
return ctx.Err()
|
|
||||||
}
|
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
@ -141,11 +141,7 @@ func scanRoots(ctx context.Context, tx *bolt.Tx, nc chan<- gc.Node) error {
|
|||||||
ibkt := libkt.Bucket(bucketKeyObjectIngests)
|
ibkt := libkt.Bucket(bucketKeyObjectIngests)
|
||||||
if ibkt != nil {
|
if ibkt != nil {
|
||||||
if err := ibkt.ForEach(func(k, v []byte) error {
|
if err := ibkt.ForEach(func(k, v []byte) error {
|
||||||
select {
|
fn(gcnode(ResourceIngest, ns, string(k)))
|
||||||
case nc <- gcnode(ResourceIngest, ns, string(k)):
|
|
||||||
case <-ctx.Done():
|
|
||||||
return ctx.Err()
|
|
||||||
}
|
|
||||||
return nil
|
return nil
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
return err
|
return err
|
||||||
@ -168,18 +164,9 @@ func scanRoots(ctx context.Context, tx *bolt.Tx, nc chan<- gc.Node) error {
|
|||||||
target := ibkt.Bucket(k).Bucket(bucketKeyTarget)
|
target := ibkt.Bucket(k).Bucket(bucketKeyTarget)
|
||||||
if target != nil {
|
if target != nil {
|
||||||
contentKey := string(target.Get(bucketKeyDigest))
|
contentKey := string(target.Get(bucketKeyDigest))
|
||||||
select {
|
fn(gcnode(ResourceContent, ns, contentKey))
|
||||||
case nc <- gcnode(ResourceContent, ns, contentKey):
|
|
||||||
case <-ctx.Done():
|
|
||||||
return ctx.Err()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return sendSnapshotRefs(ns, ibkt.Bucket(k), func(n gc.Node) {
|
return sendLabelRefs(ns, ibkt.Bucket(k), fn)
|
||||||
select {
|
|
||||||
case nc <- n:
|
|
||||||
case <-ctx.Done():
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -200,11 +187,7 @@ func scanRoots(ctx context.Context, tx *bolt.Tx, nc chan<- gc.Node) error {
|
|||||||
if ea == nil || expThreshold.After(*ea) {
|
if ea == nil || expThreshold.After(*ea) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
select {
|
fn(gcnode(ResourceIngest, ns, string(k)))
|
||||||
case nc <- gcnode(ResourceIngest, ns, string(k)):
|
|
||||||
case <-ctx.Done():
|
|
||||||
return ctx.Err()
|
|
||||||
}
|
|
||||||
return nil
|
return nil
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
return err
|
return err
|
||||||
@ -216,7 +199,12 @@ func scanRoots(ctx context.Context, tx *bolt.Tx, nc chan<- gc.Node) error {
|
|||||||
if v != nil {
|
if v != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return sendRootRef(ctx, nc, gcnode(ResourceContent, ns, string(k)), cbkt.Bucket(k))
|
|
||||||
|
if isRootRef(cbkt.Bucket(k)) {
|
||||||
|
fn(gcnode(ResourceContent, ns, string(k)))
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -229,23 +217,15 @@ func scanRoots(ctx context.Context, tx *bolt.Tx, nc chan<- gc.Node) error {
|
|||||||
if v != nil {
|
if v != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
snapshotter := string(cbkt.Bucket(k).Get(bucketKeySnapshotter))
|
|
||||||
|
cibkt := cbkt.Bucket(k)
|
||||||
|
snapshotter := string(cibkt.Get(bucketKeySnapshotter))
|
||||||
if snapshotter != "" {
|
if snapshotter != "" {
|
||||||
ss := string(cbkt.Bucket(k).Get(bucketKeySnapshotKey))
|
ss := string(cibkt.Get(bucketKeySnapshotKey))
|
||||||
select {
|
fn(gcnode(ResourceSnapshot, ns, fmt.Sprintf("%s/%s", snapshotter, ss)))
|
||||||
case nc <- gcnode(ResourceSnapshot, ns, fmt.Sprintf("%s/%s", snapshotter, ss)):
|
|
||||||
case <-ctx.Done():
|
|
||||||
return ctx.Err()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Send additional snapshot refs through labels
|
return sendLabelRefs(ns, cibkt, fn)
|
||||||
return sendSnapshotRefs(ns, cbkt.Bucket(k), func(n gc.Node) {
|
|
||||||
select {
|
|
||||||
case nc <- n:
|
|
||||||
case <-ctx.Done():
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -263,15 +243,17 @@ func scanRoots(ctx context.Context, tx *bolt.Tx, nc chan<- gc.Node) error {
|
|||||||
if v != nil {
|
if v != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
if isRootRef(snbkt.Bucket(k)) {
|
||||||
return sendRootRef(ctx, nc, gcnode(ResourceSnapshot, ns, fmt.Sprintf("%s/%s", sk, k)), snbkt.Bucket(k))
|
fn(gcnode(ResourceSnapshot, ns, fmt.Sprintf("%s/%s", sk, k)))
|
||||||
|
}
|
||||||
|
return nil
|
||||||
})
|
})
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return cerr
|
||||||
}
|
}
|
||||||
|
|
||||||
func references(ctx context.Context, tx *bolt.Tx, node gc.Node, fn func(gc.Node)) error {
|
func references(ctx context.Context, tx *bolt.Tx, node gc.Node, fn func(gc.Node)) error {
|
||||||
@ -282,10 +264,7 @@ func references(ctx context.Context, tx *bolt.Tx, node gc.Node, fn func(gc.Node)
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := sendSnapshotRefs(node.Namespace, bkt, fn); err != nil {
|
return sendLabelRefs(node.Namespace, bkt, fn)
|
||||||
return err
|
|
||||||
}
|
|
||||||
return sendContentRefs(node.Namespace, bkt, fn)
|
|
||||||
} else if node.Type == ResourceSnapshot {
|
} else if node.Type == ResourceSnapshot {
|
||||||
parts := strings.SplitN(node.Key, "/", 2)
|
parts := strings.SplitN(node.Key, "/", 2)
|
||||||
if len(parts) != 2 {
|
if len(parts) != 2 {
|
||||||
@ -304,7 +283,7 @@ func references(ctx context.Context, tx *bolt.Tx, node gc.Node, fn func(gc.Node)
|
|||||||
fn(gcnode(ResourceSnapshot, node.Namespace, fmt.Sprintf("%s/%s", ss, pv)))
|
fn(gcnode(ResourceSnapshot, node.Namespace, fmt.Sprintf("%s/%s", ss, pv)))
|
||||||
}
|
}
|
||||||
|
|
||||||
return sendSnapshotRefs(node.Namespace, bkt, fn)
|
return sendLabelRefs(node.Namespace, bkt, fn)
|
||||||
} else if node.Type == ResourceIngest {
|
} else if node.Type == ResourceIngest {
|
||||||
// Send expected value
|
// Send expected value
|
||||||
bkt := getBucket(tx, bucketKeyVersion, []byte(node.Namespace), bucketKeyObjectContent, bucketKeyObjectIngests, []byte(node.Key))
|
bkt := getBucket(tx, bucketKeyVersion, []byte(node.Namespace), bucketKeyObjectContent, bucketKeyObjectIngests, []byte(node.Key))
|
||||||
@ -456,25 +435,8 @@ func remove(ctx context.Context, tx *bolt.Tx, node gc.Node) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// sendSnapshotRefs sends all snapshot references referred to by the labels in the bkt
|
// sendLabelRefs sends all snapshot and content references referred to by the labels in the bkt
|
||||||
func sendSnapshotRefs(ns string, bkt *bolt.Bucket, fn func(gc.Node)) error {
|
func sendLabelRefs(ns string, bkt *bolt.Bucket, fn func(gc.Node)) error {
|
||||||
lbkt := bkt.Bucket(bucketKeyObjectLabels)
|
|
||||||
if lbkt != nil {
|
|
||||||
lc := lbkt.Cursor()
|
|
||||||
|
|
||||||
for k, v := lc.Seek(labelGCSnapRef); k != nil && strings.HasPrefix(string(k), string(labelGCSnapRef)); k, v = lc.Next() {
|
|
||||||
snapshotter := k[len(labelGCSnapRef):]
|
|
||||||
if i := bytes.IndexByte(snapshotter, '/'); i >= 0 {
|
|
||||||
snapshotter = snapshotter[:i]
|
|
||||||
}
|
|
||||||
fn(gcnode(ResourceSnapshot, ns, fmt.Sprintf("%s/%s", snapshotter, v)))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// sendContentRefs sends all content references referred to by the labels in the bkt
|
|
||||||
func sendContentRefs(ns string, bkt *bolt.Bucket, fn func(gc.Node)) error {
|
|
||||||
lbkt := bkt.Bucket(bucketKeyObjectLabels)
|
lbkt := bkt.Bucket(bucketKeyObjectLabels)
|
||||||
if lbkt != nil {
|
if lbkt != nil {
|
||||||
lc := lbkt.Cursor()
|
lc := lbkt.Cursor()
|
||||||
@ -490,6 +452,15 @@ func sendContentRefs(ns string, bkt *bolt.Bucket, fn func(gc.Node)) error {
|
|||||||
|
|
||||||
fn(gcnode(ResourceContent, ns, string(v)))
|
fn(gcnode(ResourceContent, ns, string(v)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for k, v := lc.Seek(labelGCSnapRef); k != nil && strings.HasPrefix(string(k), string(labelGCSnapRef)); k, v = lc.Next() {
|
||||||
|
snapshotter := k[len(labelGCSnapRef):]
|
||||||
|
if i := bytes.IndexByte(snapshotter, '/'); i >= 0 {
|
||||||
|
snapshotter = snapshotter[:i]
|
||||||
|
}
|
||||||
|
fn(gcnode(ResourceSnapshot, ns, fmt.Sprintf("%s/%s", snapshotter, v)))
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -506,17 +477,6 @@ func isRootRef(bkt *bolt.Bucket) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func sendRootRef(ctx context.Context, nc chan<- gc.Node, n gc.Node, bkt *bolt.Bucket) error {
|
|
||||||
if isRootRef(bkt) {
|
|
||||||
select {
|
|
||||||
case nc <- n:
|
|
||||||
case <-ctx.Done():
|
|
||||||
return ctx.Err()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func gcnode(t gc.ResourceType, ns, key string) gc.Node {
|
func gcnode(t gc.ResourceType, ns, key string) gc.Node {
|
||||||
return gc.Node{
|
return gc.Node{
|
||||||
Type: t,
|
Type: t,
|
||||||
|
2
vendor/github.com/containerd/containerd/metadata/snapshot.go
generated
vendored
2
vendor/github.com/containerd/containerd/metadata/snapshot.go
generated
vendored
@ -232,7 +232,7 @@ func overlayInfo(info, overlay snapshots.Info) snapshots.Info {
|
|||||||
info.Labels = overlay.Labels
|
info.Labels = overlay.Labels
|
||||||
} else {
|
} else {
|
||||||
for k, v := range overlay.Labels {
|
for k, v := range overlay.Labels {
|
||||||
overlay.Labels[k] = v
|
info.Labels[k] = v
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return info
|
return info
|
||||||
|
77
vendor/github.com/containerd/containerd/oci/spec_opts.go
generated
vendored
77
vendor/github.com/containerd/containerd/oci/spec_opts.go
generated
vendored
@ -33,7 +33,7 @@ import (
|
|||||||
"github.com/containerd/containerd/namespaces"
|
"github.com/containerd/containerd/namespaces"
|
||||||
"github.com/containerd/containerd/platforms"
|
"github.com/containerd/containerd/platforms"
|
||||||
"github.com/containerd/continuity/fs"
|
"github.com/containerd/continuity/fs"
|
||||||
"github.com/opencontainers/image-spec/specs-go/v1"
|
v1 "github.com/opencontainers/image-spec/specs-go/v1"
|
||||||
"github.com/opencontainers/runc/libcontainer/user"
|
"github.com/opencontainers/runc/libcontainer/user"
|
||||||
specs "github.com/opencontainers/runtime-spec/specs-go"
|
specs "github.com/opencontainers/runtime-spec/specs-go"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
@ -741,9 +741,11 @@ func WithCapabilities(caps []string) SpecOpts {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// WithAllCapabilities sets all linux capabilities for the process
|
// WithAllCapabilities sets all linux capabilities for the process
|
||||||
var WithAllCapabilities = WithCapabilities(getAllCapabilities())
|
var WithAllCapabilities = WithCapabilities(GetAllCapabilities())
|
||||||
|
|
||||||
func getAllCapabilities() []string {
|
// GetAllCapabilities returns all caps up to CAP_LAST_CAP
|
||||||
|
// or CAP_BLOCK_SUSPEND on RHEL6
|
||||||
|
func GetAllCapabilities() []string {
|
||||||
last := capability.CAP_LAST_CAP
|
last := capability.CAP_LAST_CAP
|
||||||
// hack for RHEL6 which has no /proc/sys/kernel/cap_last_cap
|
// hack for RHEL6 which has no /proc/sys/kernel/cap_last_cap
|
||||||
if last == capability.Cap(63) {
|
if last == capability.Cap(63) {
|
||||||
@ -759,6 +761,61 @@ func getAllCapabilities() []string {
|
|||||||
return caps
|
return caps
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func capsContain(caps []string, s string) bool {
|
||||||
|
for _, c := range caps {
|
||||||
|
if c == s {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func removeCap(caps *[]string, s string) {
|
||||||
|
for i, c := range *caps {
|
||||||
|
if c == s {
|
||||||
|
*caps = append((*caps)[:i], (*caps)[i+1:]...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithAddedCapabilities adds the provided capabilities
|
||||||
|
func WithAddedCapabilities(caps []string) SpecOpts {
|
||||||
|
return func(_ context.Context, _ Client, _ *containers.Container, s *Spec) error {
|
||||||
|
setCapabilities(s)
|
||||||
|
for _, c := range caps {
|
||||||
|
for _, cl := range []*[]string{
|
||||||
|
&s.Process.Capabilities.Bounding,
|
||||||
|
&s.Process.Capabilities.Effective,
|
||||||
|
&s.Process.Capabilities.Permitted,
|
||||||
|
&s.Process.Capabilities.Inheritable,
|
||||||
|
} {
|
||||||
|
if !capsContain(*cl, c) {
|
||||||
|
*cl = append(*cl, c)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithDroppedCapabilities removes the provided capabilities
|
||||||
|
func WithDroppedCapabilities(caps []string) SpecOpts {
|
||||||
|
return func(_ context.Context, _ Client, _ *containers.Container, s *Spec) error {
|
||||||
|
setCapabilities(s)
|
||||||
|
for _, c := range caps {
|
||||||
|
for _, cl := range []*[]string{
|
||||||
|
&s.Process.Capabilities.Bounding,
|
||||||
|
&s.Process.Capabilities.Effective,
|
||||||
|
&s.Process.Capabilities.Permitted,
|
||||||
|
&s.Process.Capabilities.Inheritable,
|
||||||
|
} {
|
||||||
|
removeCap(cl, c)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// WithAmbientCapabilities set the Linux ambient capabilities for the process
|
// WithAmbientCapabilities set the Linux ambient capabilities for the process
|
||||||
// Ambient capabilities should only be set for non-root users or the caller should
|
// Ambient capabilities should only be set for non-root users or the caller should
|
||||||
// understand how these capabilities are used and set
|
// understand how these capabilities are used and set
|
||||||
@ -1063,3 +1120,17 @@ func WithMemoryLimit(limit uint64) SpecOpts {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithAnnotations appends or replaces the annotations on the spec with the
|
||||||
|
// provided annotations
|
||||||
|
func WithAnnotations(annotations map[string]string) SpecOpts {
|
||||||
|
return func(_ context.Context, _ Client, _ *containers.Container, s *Spec) error {
|
||||||
|
if s.Annotations == nil {
|
||||||
|
s.Annotations = make(map[string]string)
|
||||||
|
}
|
||||||
|
for k, v := range annotations {
|
||||||
|
s.Annotations[k] = v
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
9
vendor/github.com/containerd/containerd/plugin/plugin.go
generated
vendored
9
vendor/github.com/containerd/containerd/plugin/plugin.go
generated
vendored
@ -75,6 +75,15 @@ const (
|
|||||||
GCPlugin Type = "io.containerd.gc.v1"
|
GCPlugin Type = "io.containerd.gc.v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// RuntimeLinuxV1 is the legacy linux runtime
|
||||||
|
RuntimeLinuxV1 = "io.containerd.runtime.v1.linux"
|
||||||
|
// RuntimeRuncV1 is the runc runtime that supports a single container
|
||||||
|
RuntimeRuncV1 = "io.containerd.runc.v1"
|
||||||
|
// RuntimeRuncV2 is the runc runtime that supports multiple containers per shim
|
||||||
|
RuntimeRuncV2 = "io.containerd.runc.v2"
|
||||||
|
)
|
||||||
|
|
||||||
// Registration contains information for registering a plugin
|
// Registration contains information for registering a plugin
|
||||||
type Registration struct {
|
type Registration struct {
|
||||||
// Type of the plugin
|
// Type of the plugin
|
||||||
|
204
vendor/github.com/containerd/containerd/pull.go
generated
vendored
Normal file
204
vendor/github.com/containerd/containerd/pull.go
generated
vendored
Normal file
@ -0,0 +1,204 @@
|
|||||||
|
/*
|
||||||
|
Copyright The containerd Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package containerd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/containerd/containerd/errdefs"
|
||||||
|
"github.com/containerd/containerd/images"
|
||||||
|
"github.com/containerd/containerd/platforms"
|
||||||
|
"github.com/containerd/containerd/remotes"
|
||||||
|
"github.com/containerd/containerd/remotes/docker"
|
||||||
|
"github.com/containerd/containerd/remotes/docker/schema1"
|
||||||
|
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
"golang.org/x/sync/semaphore"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Pull downloads the provided content into containerd's content store
|
||||||
|
// and returns a platform specific image object
|
||||||
|
func (c *Client) Pull(ctx context.Context, ref string, opts ...RemoteOpt) (Image, error) {
|
||||||
|
pullCtx := defaultRemoteContext()
|
||||||
|
for _, o := range opts {
|
||||||
|
if err := o(c, pullCtx); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if pullCtx.PlatformMatcher == nil {
|
||||||
|
if len(pullCtx.Platforms) > 1 {
|
||||||
|
return nil, errors.New("cannot pull multiplatform image locally, try Fetch")
|
||||||
|
} else if len(pullCtx.Platforms) == 0 {
|
||||||
|
pullCtx.PlatformMatcher = platforms.Default()
|
||||||
|
} else {
|
||||||
|
p, err := platforms.Parse(pullCtx.Platforms[0])
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrapf(err, "invalid platform %s", pullCtx.Platforms[0])
|
||||||
|
}
|
||||||
|
|
||||||
|
pullCtx.PlatformMatcher = platforms.Only(p)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx, done, err := c.WithLease(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer done(ctx)
|
||||||
|
|
||||||
|
img, err := c.fetch(ctx, pullCtx, ref, 1)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
i := NewImageWithPlatform(c, img, pullCtx.PlatformMatcher)
|
||||||
|
|
||||||
|
if pullCtx.Unpack {
|
||||||
|
if err := i.Unpack(ctx, pullCtx.Snapshotter); err != nil {
|
||||||
|
return nil, errors.Wrapf(err, "failed to unpack image on snapshotter %s", pullCtx.Snapshotter)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return i, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) fetch(ctx context.Context, rCtx *RemoteContext, ref string, limit int) (images.Image, error) {
|
||||||
|
store := c.ContentStore()
|
||||||
|
name, desc, err := rCtx.Resolver.Resolve(ctx, ref)
|
||||||
|
if err != nil {
|
||||||
|
return images.Image{}, errors.Wrapf(err, "failed to resolve reference %q", ref)
|
||||||
|
}
|
||||||
|
|
||||||
|
fetcher, err := rCtx.Resolver.Fetcher(ctx, name)
|
||||||
|
if err != nil {
|
||||||
|
return images.Image{}, errors.Wrapf(err, "failed to get fetcher for %q", name)
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
handler images.Handler
|
||||||
|
|
||||||
|
isConvertible bool
|
||||||
|
converterFunc func(context.Context, ocispec.Descriptor) (ocispec.Descriptor, error)
|
||||||
|
limiter *semaphore.Weighted
|
||||||
|
)
|
||||||
|
|
||||||
|
if desc.MediaType == images.MediaTypeDockerSchema1Manifest && rCtx.ConvertSchema1 {
|
||||||
|
schema1Converter := schema1.NewConverter(store, fetcher)
|
||||||
|
|
||||||
|
handler = images.Handlers(append(rCtx.BaseHandlers, schema1Converter)...)
|
||||||
|
|
||||||
|
isConvertible = true
|
||||||
|
|
||||||
|
converterFunc = func(ctx context.Context, _ ocispec.Descriptor) (ocispec.Descriptor, error) {
|
||||||
|
return schema1Converter.Convert(ctx)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Get all the children for a descriptor
|
||||||
|
childrenHandler := images.ChildrenHandler(store)
|
||||||
|
// Set any children labels for that content
|
||||||
|
childrenHandler = images.SetChildrenLabels(store, childrenHandler)
|
||||||
|
// Filter manifests by platforms but allow to handle manifest
|
||||||
|
// and configuration for not-target platforms
|
||||||
|
childrenHandler = remotes.FilterManifestByPlatformHandler(childrenHandler, rCtx.PlatformMatcher)
|
||||||
|
// Sort and limit manifests if a finite number is needed
|
||||||
|
if limit > 0 {
|
||||||
|
childrenHandler = images.LimitManifests(childrenHandler, rCtx.PlatformMatcher, limit)
|
||||||
|
}
|
||||||
|
|
||||||
|
// set isConvertible to true if there is application/octet-stream media type
|
||||||
|
convertibleHandler := images.HandlerFunc(
|
||||||
|
func(_ context.Context, desc ocispec.Descriptor) ([]ocispec.Descriptor, error) {
|
||||||
|
if desc.MediaType == docker.LegacyConfigMediaType {
|
||||||
|
isConvertible = true
|
||||||
|
}
|
||||||
|
|
||||||
|
return []ocispec.Descriptor{}, nil
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
handlers := append(rCtx.BaseHandlers,
|
||||||
|
remotes.FetchHandler(store, fetcher),
|
||||||
|
convertibleHandler,
|
||||||
|
childrenHandler,
|
||||||
|
)
|
||||||
|
|
||||||
|
// append distribution source label to blob data
|
||||||
|
if rCtx.AppendDistributionSourceLabel {
|
||||||
|
appendDistSrcLabelHandler, err := docker.AppendDistributionSourceLabel(store, ref)
|
||||||
|
if err != nil {
|
||||||
|
return images.Image{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
handlers = append(handlers, appendDistSrcLabelHandler)
|
||||||
|
}
|
||||||
|
|
||||||
|
handler = images.Handlers(handlers...)
|
||||||
|
|
||||||
|
converterFunc = func(ctx context.Context, desc ocispec.Descriptor) (ocispec.Descriptor, error) {
|
||||||
|
return docker.ConvertManifest(ctx, store, desc)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if rCtx.HandlerWrapper != nil {
|
||||||
|
handler = rCtx.HandlerWrapper(handler)
|
||||||
|
}
|
||||||
|
|
||||||
|
if rCtx.MaxConcurrentDownloads > 0 {
|
||||||
|
limiter = semaphore.NewWeighted(int64(rCtx.MaxConcurrentDownloads))
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := images.Dispatch(ctx, handler, limiter, desc); err != nil {
|
||||||
|
return images.Image{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if isConvertible {
|
||||||
|
if desc, err = converterFunc(ctx, desc); err != nil {
|
||||||
|
return images.Image{}, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
img := images.Image{
|
||||||
|
Name: name,
|
||||||
|
Target: desc,
|
||||||
|
Labels: rCtx.Labels,
|
||||||
|
}
|
||||||
|
|
||||||
|
is := c.ImageService()
|
||||||
|
for {
|
||||||
|
if created, err := is.Create(ctx, img); err != nil {
|
||||||
|
if !errdefs.IsAlreadyExists(err) {
|
||||||
|
return images.Image{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
updated, err := is.Update(ctx, img)
|
||||||
|
if err != nil {
|
||||||
|
// if image was removed, try create again
|
||||||
|
if errdefs.IsNotFound(err) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
return images.Image{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
img = updated
|
||||||
|
} else {
|
||||||
|
img = created
|
||||||
|
}
|
||||||
|
|
||||||
|
return img, nil
|
||||||
|
}
|
||||||
|
}
|
112
vendor/github.com/containerd/containerd/remotes/docker/handler.go
generated
vendored
Normal file
112
vendor/github.com/containerd/containerd/remotes/docker/handler.go
generated
vendored
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
/*
|
||||||
|
Copyright The containerd Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package docker
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"net/url"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/containerd/containerd/content"
|
||||||
|
"github.com/containerd/containerd/images"
|
||||||
|
"github.com/containerd/containerd/labels"
|
||||||
|
"github.com/containerd/containerd/log"
|
||||||
|
"github.com/containerd/containerd/reference"
|
||||||
|
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
// labelDistributionSource describes the source blob comes from.
|
||||||
|
labelDistributionSource = "containerd.io/distribution.source"
|
||||||
|
)
|
||||||
|
|
||||||
|
// AppendDistributionSourceLabel updates the label of blob with distribution source.
|
||||||
|
func AppendDistributionSourceLabel(manager content.Manager, ref string) (images.HandlerFunc, error) {
|
||||||
|
refspec, err := reference.Parse(ref)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
u, err := url.Parse("dummy://" + refspec.Locator)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
source, repo := u.Hostname(), strings.TrimPrefix(u.Path, "/")
|
||||||
|
return func(ctx context.Context, desc ocispec.Descriptor) ([]ocispec.Descriptor, error) {
|
||||||
|
info, err := manager.Info(ctx, desc.Digest)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
key := distributionSourceLabelKey(source)
|
||||||
|
|
||||||
|
originLabel := ""
|
||||||
|
if info.Labels != nil {
|
||||||
|
originLabel = info.Labels[key]
|
||||||
|
}
|
||||||
|
value := appendDistributionSourceLabel(originLabel, repo)
|
||||||
|
|
||||||
|
// The repo name has been limited under 256 and the distribution
|
||||||
|
// label might hit the limitation of label size, when blob data
|
||||||
|
// is used as the very, very common layer.
|
||||||
|
if err := labels.Validate(key, value); err != nil {
|
||||||
|
log.G(ctx).Warnf("skip to append distribution label: %s", err)
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
info = content.Info{
|
||||||
|
Digest: desc.Digest,
|
||||||
|
Labels: map[string]string{
|
||||||
|
key: value,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
_, err = manager.Update(ctx, info, fmt.Sprintf("labels.%s", key))
|
||||||
|
return nil, err
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func appendDistributionSourceLabel(originLabel, repo string) string {
|
||||||
|
repos := []string{}
|
||||||
|
if originLabel != "" {
|
||||||
|
repos = strings.Split(originLabel, ",")
|
||||||
|
}
|
||||||
|
repos = append(repos, repo)
|
||||||
|
|
||||||
|
// use emtpy string to present duplicate items
|
||||||
|
for i := 1; i < len(repos); i++ {
|
||||||
|
tmp, j := repos[i], i-1
|
||||||
|
for ; j >= 0 && repos[j] >= tmp; j-- {
|
||||||
|
if repos[j] == tmp {
|
||||||
|
tmp = ""
|
||||||
|
}
|
||||||
|
repos[j+1] = repos[j]
|
||||||
|
}
|
||||||
|
repos[j+1] = tmp
|
||||||
|
}
|
||||||
|
|
||||||
|
i := 0
|
||||||
|
for ; i < len(repos) && repos[i] == ""; i++ {
|
||||||
|
}
|
||||||
|
|
||||||
|
return strings.Join(repos[i:], ",")
|
||||||
|
}
|
||||||
|
|
||||||
|
func distributionSourceLabelKey(source string) string {
|
||||||
|
return fmt.Sprintf("%s.%s", labelDistributionSource, source)
|
||||||
|
}
|
44
vendor/github.com/containerd/containerd/remotes/handlers.go
generated
vendored
44
vendor/github.com/containerd/containerd/remotes/handlers.go
generated
vendored
@ -156,7 +156,7 @@ func push(ctx context.Context, provider content.Provider, pusher Pusher, desc oc
|
|||||||
//
|
//
|
||||||
// Base handlers can be provided which will be called before any push specific
|
// Base handlers can be provided which will be called before any push specific
|
||||||
// handlers.
|
// handlers.
|
||||||
func PushContent(ctx context.Context, pusher Pusher, desc ocispec.Descriptor, provider content.Provider, platform platforms.MatchComparer, baseHandlers ...images.Handler) error {
|
func PushContent(ctx context.Context, pusher Pusher, desc ocispec.Descriptor, provider content.Provider, platform platforms.MatchComparer, wrapper func(h images.Handler) images.Handler) error {
|
||||||
var m sync.Mutex
|
var m sync.Mutex
|
||||||
manifestStack := []ocispec.Descriptor{}
|
manifestStack := []ocispec.Descriptor{}
|
||||||
|
|
||||||
@ -175,13 +175,16 @@ func PushContent(ctx context.Context, pusher Pusher, desc ocispec.Descriptor, pr
|
|||||||
|
|
||||||
pushHandler := PushHandler(pusher, provider)
|
pushHandler := PushHandler(pusher, provider)
|
||||||
|
|
||||||
handlers := append(baseHandlers,
|
var handler images.Handler = images.Handlers(
|
||||||
images.FilterPlatforms(images.ChildrenHandler(provider), platform),
|
images.FilterPlatforms(images.ChildrenHandler(provider), platform),
|
||||||
filterHandler,
|
filterHandler,
|
||||||
pushHandler,
|
pushHandler,
|
||||||
)
|
)
|
||||||
|
if wrapper != nil {
|
||||||
|
handler = wrapper(handler)
|
||||||
|
}
|
||||||
|
|
||||||
if err := images.Dispatch(ctx, images.Handlers(handlers...), nil, desc); err != nil {
|
if err := images.Dispatch(ctx, handler, nil, desc); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -203,3 +206,38 @@ func PushContent(ctx context.Context, pusher Pusher, desc ocispec.Descriptor, pr
|
|||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FilterManifestByPlatformHandler allows Handler to handle non-target
|
||||||
|
// platform's manifest and configuration data.
|
||||||
|
func FilterManifestByPlatformHandler(f images.HandlerFunc, m platforms.Matcher) images.HandlerFunc {
|
||||||
|
return func(ctx context.Context, desc ocispec.Descriptor) ([]ocispec.Descriptor, error) {
|
||||||
|
children, err := f(ctx, desc)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// no platform information
|
||||||
|
if desc.Platform == nil || m == nil {
|
||||||
|
return children, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var descs []ocispec.Descriptor
|
||||||
|
switch desc.MediaType {
|
||||||
|
case images.MediaTypeDockerSchema2Manifest, ocispec.MediaTypeImageManifest:
|
||||||
|
if m.Match(*desc.Platform) {
|
||||||
|
descs = children
|
||||||
|
} else {
|
||||||
|
for _, child := range children {
|
||||||
|
if child.MediaType == images.MediaTypeDockerSchema2Config ||
|
||||||
|
child.MediaType == ocispec.MediaTypeImageConfig {
|
||||||
|
|
||||||
|
descs = append(descs, child)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
descs = children
|
||||||
|
}
|
||||||
|
return descs, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
2
vendor/github.com/containerd/containerd/runtime/proc/proc.go
generated
vendored
2
vendor/github.com/containerd/containerd/runtime/proc/proc.go
generated
vendored
@ -72,7 +72,7 @@ type Process interface {
|
|||||||
// platform implementations
|
// platform implementations
|
||||||
type Platform interface {
|
type Platform interface {
|
||||||
CopyConsole(ctx context.Context, console console.Console, stdin, stdout, stderr string,
|
CopyConsole(ctx context.Context, console console.Console, stdin, stdout, stderr string,
|
||||||
wg, cwg *sync.WaitGroup) (console.Console, error)
|
wg *sync.WaitGroup) (console.Console, error)
|
||||||
ShutdownConsole(ctx context.Context, console console.Console) error
|
ShutdownConsole(ctx context.Context, console console.Console) error
|
||||||
Close() error
|
Close() error
|
||||||
}
|
}
|
||||||
|
27
vendor/github.com/containerd/containerd/runtime/v1/linux/bundle.go
generated
vendored
27
vendor/github.com/containerd/containerd/runtime/v1/linux/bundle.go
generated
vendored
@ -20,6 +20,7 @@ package linux
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"crypto/sha256"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
@ -103,7 +104,7 @@ func ShimLocal(c *Config, exchange *exchange.Exchange) ShimOpt {
|
|||||||
// ShimConnect is a ShimOpt for connecting to an existing remote shim
|
// ShimConnect is a ShimOpt for connecting to an existing remote shim
|
||||||
func ShimConnect(c *Config, onClose func()) ShimOpt {
|
func ShimConnect(c *Config, onClose func()) ShimOpt {
|
||||||
return func(b *bundle, ns string, ropts *runctypes.RuncOptions) (shim.Config, client.Opt) {
|
return func(b *bundle, ns string, ropts *runctypes.RuncOptions) (shim.Config, client.Opt) {
|
||||||
return b.shimConfig(ns, c, ropts), client.WithConnect(b.shimAddress(ns), onClose)
|
return b.shimConfig(ns, c, ropts), client.WithConnect(b.decideShimAddress(ns), onClose)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -127,10 +128,32 @@ func (b *bundle) Delete() error {
|
|||||||
return errors.Wrapf(err, "Failed to remove both bundle and workdir locations: %v", err2)
|
return errors.Wrapf(err, "Failed to remove both bundle and workdir locations: %v", err2)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *bundle) shimAddress(namespace string) string {
|
func (b *bundle) legacyShimAddress(namespace string) string {
|
||||||
return filepath.Join(string(filepath.Separator), "containerd-shim", namespace, b.id, "shim.sock")
|
return filepath.Join(string(filepath.Separator), "containerd-shim", namespace, b.id, "shim.sock")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (b *bundle) shimAddress(namespace string) string {
|
||||||
|
d := sha256.Sum256([]byte(filepath.Join(namespace, b.id)))
|
||||||
|
return filepath.Join(string(filepath.Separator), "containerd-shim", fmt.Sprintf("%x.sock", d))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *bundle) loadAddress() (string, error) {
|
||||||
|
addressPath := filepath.Join(b.path, "address")
|
||||||
|
data, err := ioutil.ReadFile(addressPath)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return string(data), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *bundle) decideShimAddress(namespace string) string {
|
||||||
|
address, err := b.loadAddress()
|
||||||
|
if err != nil {
|
||||||
|
return b.legacyShimAddress(namespace)
|
||||||
|
}
|
||||||
|
return address
|
||||||
|
}
|
||||||
|
|
||||||
func (b *bundle) shimConfig(namespace string, c *Config, runcOptions *runctypes.RuncOptions) shim.Config {
|
func (b *bundle) shimConfig(namespace string, c *Config, runcOptions *runctypes.RuncOptions) shim.Config {
|
||||||
var (
|
var (
|
||||||
criuPath string
|
criuPath string
|
||||||
|
48
vendor/github.com/containerd/containerd/runtime/v1/linux/proc/exec.go
generated
vendored
48
vendor/github.com/containerd/containerd/runtime/v1/linux/proc/exec.go
generated
vendored
@ -46,7 +46,7 @@ type execProcess struct {
|
|||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
id string
|
id string
|
||||||
console console.Console
|
console console.Console
|
||||||
io runc.IO
|
io *processIO
|
||||||
status int
|
status int
|
||||||
exited time.Time
|
exited time.Time
|
||||||
pid *safePid
|
pid *safePid
|
||||||
@ -172,29 +172,30 @@ func (e *execProcess) start(ctx context.Context) (err error) {
|
|||||||
// access e.pid until it is updated.
|
// access e.pid until it is updated.
|
||||||
e.pid.Lock()
|
e.pid.Lock()
|
||||||
defer e.pid.Unlock()
|
defer e.pid.Unlock()
|
||||||
|
|
||||||
var (
|
var (
|
||||||
socket *runc.Socket
|
socket *runc.Socket
|
||||||
pidfile = filepath.Join(e.path, fmt.Sprintf("%s.pid", e.id))
|
pio *processIO
|
||||||
|
pidFile = newExecPidFile(e.path, e.id)
|
||||||
)
|
)
|
||||||
if e.stdio.Terminal {
|
if e.stdio.Terminal {
|
||||||
if socket, err = runc.NewTempConsoleSocket(); err != nil {
|
if socket, err = runc.NewTempConsoleSocket(); err != nil {
|
||||||
return errors.Wrap(err, "failed to create runc console socket")
|
return errors.Wrap(err, "failed to create runc console socket")
|
||||||
}
|
}
|
||||||
defer socket.Close()
|
defer socket.Close()
|
||||||
} else if e.stdio.IsNull() {
|
|
||||||
if e.io, err = runc.NewNullIO(); err != nil {
|
|
||||||
return errors.Wrap(err, "creating new NULL IO")
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if e.io, err = runc.NewPipeIO(e.parent.IoUID, e.parent.IoGID, withConditionalIO(e.stdio)); err != nil {
|
if pio, err = createIO(ctx, e.id, e.parent.IoUID, e.parent.IoGID, e.stdio); err != nil {
|
||||||
return errors.Wrap(err, "failed to create runc io pipes")
|
return errors.Wrap(err, "failed to create init process I/O")
|
||||||
}
|
}
|
||||||
|
e.io = pio
|
||||||
}
|
}
|
||||||
opts := &runc.ExecOpts{
|
opts := &runc.ExecOpts{
|
||||||
PidFile: pidfile,
|
PidFile: pidFile.Path(),
|
||||||
IO: e.io,
|
|
||||||
Detach: true,
|
Detach: true,
|
||||||
}
|
}
|
||||||
|
if pio != nil {
|
||||||
|
opts.IO = pio.IO()
|
||||||
|
}
|
||||||
if socket != nil {
|
if socket != nil {
|
||||||
opts.ConsoleSocket = socket
|
opts.ConsoleSocket = socket
|
||||||
}
|
}
|
||||||
@ -203,14 +204,10 @@ func (e *execProcess) start(ctx context.Context) (err error) {
|
|||||||
return e.parent.runtimeError(err, "OCI runtime exec failed")
|
return e.parent.runtimeError(err, "OCI runtime exec failed")
|
||||||
}
|
}
|
||||||
if e.stdio.Stdin != "" {
|
if e.stdio.Stdin != "" {
|
||||||
sc, err := fifo.OpenFifo(context.Background(), e.stdio.Stdin, syscall.O_WRONLY|syscall.O_NONBLOCK, 0)
|
if err := e.openStdin(e.stdio.Stdin); err != nil {
|
||||||
if err != nil {
|
return err
|
||||||
return errors.Wrapf(err, "failed to open stdin fifo %s", e.stdio.Stdin)
|
|
||||||
}
|
}
|
||||||
e.closers = append(e.closers, sc)
|
|
||||||
e.stdin = sc
|
|
||||||
}
|
}
|
||||||
var copyWaitGroup sync.WaitGroup
|
|
||||||
ctx, cancel := context.WithTimeout(ctx, 30*time.Second)
|
ctx, cancel := context.WithTimeout(ctx, 30*time.Second)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
if socket != nil {
|
if socket != nil {
|
||||||
@ -218,16 +215,15 @@ func (e *execProcess) start(ctx context.Context) (err error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "failed to retrieve console master")
|
return errors.Wrap(err, "failed to retrieve console master")
|
||||||
}
|
}
|
||||||
if e.console, err = e.parent.Platform.CopyConsole(ctx, console, e.stdio.Stdin, e.stdio.Stdout, e.stdio.Stderr, &e.wg, ©WaitGroup); err != nil {
|
if e.console, err = e.parent.Platform.CopyConsole(ctx, console, e.stdio.Stdin, e.stdio.Stdout, e.stdio.Stderr, &e.wg); err != nil {
|
||||||
return errors.Wrap(err, "failed to start console copy")
|
return errors.Wrap(err, "failed to start console copy")
|
||||||
}
|
}
|
||||||
} else if !e.stdio.IsNull() {
|
} else {
|
||||||
if err := copyPipes(ctx, e.io, e.stdio.Stdin, e.stdio.Stdout, e.stdio.Stderr, &e.wg, ©WaitGroup); err != nil {
|
if err := pio.Copy(ctx, &e.wg); err != nil {
|
||||||
return errors.Wrap(err, "failed to start io pipe copy")
|
return errors.Wrap(err, "failed to start io pipe copy")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
copyWaitGroup.Wait()
|
pid, err := pidFile.Read()
|
||||||
pid, err := runc.ReadPidFile(opts.PidFile)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "failed to retrieve OCI runtime exec pid")
|
return errors.Wrap(err, "failed to retrieve OCI runtime exec pid")
|
||||||
}
|
}
|
||||||
@ -235,6 +231,16 @@ func (e *execProcess) start(ctx context.Context) (err error) {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e *execProcess) openStdin(path string) error {
|
||||||
|
sc, err := fifo.OpenFifo(context.Background(), path, syscall.O_WRONLY|syscall.O_NONBLOCK, 0)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrapf(err, "failed to open stdin fifo %s", path)
|
||||||
|
}
|
||||||
|
e.stdin = sc
|
||||||
|
e.closers = append(e.closers, sc)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (e *execProcess) Status(ctx context.Context) (string, error) {
|
func (e *execProcess) Status(ctx context.Context) (string, error) {
|
||||||
s, err := e.parent.Status(ctx)
|
s, err := e.parent.Status(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
93
vendor/github.com/containerd/containerd/runtime/v1/linux/proc/init.go
generated
vendored
93
vendor/github.com/containerd/containerd/runtime/v1/linux/proc/init.go
generated
vendored
@ -41,9 +41,6 @@ import (
|
|||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
// InitPidFile name of the file that contains the init pid
|
|
||||||
const InitPidFile = "init.pid"
|
|
||||||
|
|
||||||
// Init represents an initial process for a container
|
// Init represents an initial process for a container
|
||||||
type Init struct {
|
type Init struct {
|
||||||
wg sync.WaitGroup
|
wg sync.WaitGroup
|
||||||
@ -63,7 +60,7 @@ type Init struct {
|
|||||||
Bundle string
|
Bundle string
|
||||||
console console.Console
|
console console.Console
|
||||||
Platform proc.Platform
|
Platform proc.Platform
|
||||||
io runc.IO
|
io *processIO
|
||||||
runtime *runc.Runc
|
runtime *runc.Runc
|
||||||
status int
|
status int
|
||||||
exited time.Time
|
exited time.Time
|
||||||
@ -111,49 +108,33 @@ func New(id string, runtime *runc.Runc, stdio proc.Stdio) *Init {
|
|||||||
// Create the process with the provided config
|
// Create the process with the provided config
|
||||||
func (p *Init) Create(ctx context.Context, r *CreateConfig) error {
|
func (p *Init) Create(ctx context.Context, r *CreateConfig) error {
|
||||||
var (
|
var (
|
||||||
err error
|
err error
|
||||||
socket *runc.Socket
|
socket *runc.Socket
|
||||||
|
pio *processIO
|
||||||
|
pidFile = newPidFile(p.Bundle)
|
||||||
)
|
)
|
||||||
if r.Terminal {
|
if r.Terminal {
|
||||||
if socket, err = runc.NewTempConsoleSocket(); err != nil {
|
if socket, err = runc.NewTempConsoleSocket(); err != nil {
|
||||||
return errors.Wrap(err, "failed to create OCI runtime console socket")
|
return errors.Wrap(err, "failed to create OCI runtime console socket")
|
||||||
}
|
}
|
||||||
defer socket.Close()
|
defer socket.Close()
|
||||||
} else if hasNoIO(r) {
|
|
||||||
if p.io, err = runc.NewNullIO(); err != nil {
|
|
||||||
return errors.Wrap(err, "creating new NULL IO")
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if p.io, err = runc.NewPipeIO(p.IoUID, p.IoGID, withConditionalIO(p.stdio)); err != nil {
|
if pio, err = createIO(ctx, p.id, p.IoUID, p.IoGID, p.stdio); err != nil {
|
||||||
return errors.Wrap(err, "failed to create OCI runtime io pipes")
|
return errors.Wrap(err, "failed to create init process I/O")
|
||||||
}
|
}
|
||||||
|
p.io = pio
|
||||||
}
|
}
|
||||||
pidFile := filepath.Join(p.Bundle, InitPidFile)
|
|
||||||
if r.Checkpoint != "" {
|
if r.Checkpoint != "" {
|
||||||
opts := &runc.RestoreOpts{
|
return p.createCheckpointedState(r, pidFile)
|
||||||
CheckpointOpts: runc.CheckpointOpts{
|
|
||||||
ImagePath: r.Checkpoint,
|
|
||||||
WorkDir: p.CriuWorkPath,
|
|
||||||
ParentPath: r.ParentCheckpoint,
|
|
||||||
},
|
|
||||||
PidFile: pidFile,
|
|
||||||
IO: p.io,
|
|
||||||
NoPivot: p.NoPivotRoot,
|
|
||||||
Detach: true,
|
|
||||||
NoSubreaper: true,
|
|
||||||
}
|
|
||||||
p.initState = &createdCheckpointState{
|
|
||||||
p: p,
|
|
||||||
opts: opts,
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
opts := &runc.CreateOpts{
|
opts := &runc.CreateOpts{
|
||||||
PidFile: pidFile,
|
PidFile: pidFile.Path(),
|
||||||
IO: p.io,
|
|
||||||
NoPivot: p.NoPivotRoot,
|
NoPivot: p.NoPivotRoot,
|
||||||
NoNewKeyring: p.NoNewKeyring,
|
NoNewKeyring: p.NoNewKeyring,
|
||||||
}
|
}
|
||||||
|
if p.io != nil {
|
||||||
|
opts.IO = p.io.IO()
|
||||||
|
}
|
||||||
if socket != nil {
|
if socket != nil {
|
||||||
opts.ConsoleSocket = socket
|
opts.ConsoleSocket = socket
|
||||||
}
|
}
|
||||||
@ -161,14 +142,10 @@ func (p *Init) Create(ctx context.Context, r *CreateConfig) error {
|
|||||||
return p.runtimeError(err, "OCI runtime create failed")
|
return p.runtimeError(err, "OCI runtime create failed")
|
||||||
}
|
}
|
||||||
if r.Stdin != "" {
|
if r.Stdin != "" {
|
||||||
sc, err := fifo.OpenFifo(context.Background(), r.Stdin, syscall.O_WRONLY|syscall.O_NONBLOCK, 0)
|
if err := p.openStdin(r.Stdin); err != nil {
|
||||||
if err != nil {
|
return err
|
||||||
return errors.Wrapf(err, "failed to open stdin fifo %s", r.Stdin)
|
|
||||||
}
|
}
|
||||||
p.stdin = sc
|
|
||||||
p.closers = append(p.closers, sc)
|
|
||||||
}
|
}
|
||||||
var copyWaitGroup sync.WaitGroup
|
|
||||||
ctx, cancel := context.WithTimeout(ctx, 30*time.Second)
|
ctx, cancel := context.WithTimeout(ctx, 30*time.Second)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
if socket != nil {
|
if socket != nil {
|
||||||
@ -176,19 +153,17 @@ func (p *Init) Create(ctx context.Context, r *CreateConfig) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "failed to retrieve console master")
|
return errors.Wrap(err, "failed to retrieve console master")
|
||||||
}
|
}
|
||||||
console, err = p.Platform.CopyConsole(ctx, console, r.Stdin, r.Stdout, r.Stderr, &p.wg, ©WaitGroup)
|
console, err = p.Platform.CopyConsole(ctx, console, r.Stdin, r.Stdout, r.Stderr, &p.wg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "failed to start console copy")
|
return errors.Wrap(err, "failed to start console copy")
|
||||||
}
|
}
|
||||||
p.console = console
|
p.console = console
|
||||||
} else if !hasNoIO(r) {
|
} else {
|
||||||
if err := copyPipes(ctx, p.io, r.Stdin, r.Stdout, r.Stderr, &p.wg, ©WaitGroup); err != nil {
|
if err := pio.Copy(ctx, &p.wg); err != nil {
|
||||||
return errors.Wrap(err, "failed to start io pipe copy")
|
return errors.Wrap(err, "failed to start io pipe copy")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pid, err := pidFile.Read()
|
||||||
copyWaitGroup.Wait()
|
|
||||||
pid, err := runc.ReadPidFile(pidFile)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "failed to retrieve OCI runtime container pid")
|
return errors.Wrap(err, "failed to retrieve OCI runtime container pid")
|
||||||
}
|
}
|
||||||
@ -196,6 +171,36 @@ func (p *Init) Create(ctx context.Context, r *CreateConfig) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *Init) openStdin(path string) error {
|
||||||
|
sc, err := fifo.OpenFifo(context.Background(), path, syscall.O_WRONLY|syscall.O_NONBLOCK, 0)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrapf(err, "failed to open stdin fifo %s", path)
|
||||||
|
}
|
||||||
|
p.stdin = sc
|
||||||
|
p.closers = append(p.closers, sc)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Init) createCheckpointedState(r *CreateConfig, pidFile *pidFile) error {
|
||||||
|
opts := &runc.RestoreOpts{
|
||||||
|
CheckpointOpts: runc.CheckpointOpts{
|
||||||
|
ImagePath: r.Checkpoint,
|
||||||
|
WorkDir: p.CriuWorkPath,
|
||||||
|
ParentPath: r.ParentCheckpoint,
|
||||||
|
},
|
||||||
|
PidFile: pidFile.Path(),
|
||||||
|
IO: p.io.IO(),
|
||||||
|
NoPivot: p.NoPivotRoot,
|
||||||
|
Detach: true,
|
||||||
|
NoSubreaper: true,
|
||||||
|
}
|
||||||
|
p.initState = &createdCheckpointState{
|
||||||
|
p: p,
|
||||||
|
opts: opts,
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// Wait for the process to exit
|
// Wait for the process to exit
|
||||||
func (p *Init) Wait() {
|
func (p *Init) Wait() {
|
||||||
<-p.waitBlock
|
<-p.waitBlock
|
||||||
|
17
vendor/github.com/containerd/containerd/runtime/v1/linux/proc/init_state.go
generated
vendored
17
vendor/github.com/containerd/containerd/runtime/v1/linux/proc/init_state.go
generated
vendored
@ -20,12 +20,9 @@ package proc
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"sync"
|
|
||||||
"syscall"
|
|
||||||
|
|
||||||
"github.com/containerd/console"
|
"github.com/containerd/console"
|
||||||
"github.com/containerd/containerd/runtime/proc"
|
"github.com/containerd/containerd/runtime/proc"
|
||||||
"github.com/containerd/fifo"
|
|
||||||
runc "github.com/containerd/go-runc"
|
runc "github.com/containerd/go-runc"
|
||||||
google_protobuf "github.com/gogo/protobuf/types"
|
google_protobuf "github.com/gogo/protobuf/types"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
@ -172,31 +169,25 @@ func (s *createdCheckpointState) Start(ctx context.Context) error {
|
|||||||
return p.runtimeError(err, "OCI runtime restore failed")
|
return p.runtimeError(err, "OCI runtime restore failed")
|
||||||
}
|
}
|
||||||
if sio.Stdin != "" {
|
if sio.Stdin != "" {
|
||||||
sc, err := fifo.OpenFifo(context.Background(), sio.Stdin, syscall.O_WRONLY|syscall.O_NONBLOCK, 0)
|
if err := p.openStdin(sio.Stdin); err != nil {
|
||||||
if err != nil {
|
|
||||||
return errors.Wrapf(err, "failed to open stdin fifo %s", sio.Stdin)
|
return errors.Wrapf(err, "failed to open stdin fifo %s", sio.Stdin)
|
||||||
}
|
}
|
||||||
p.stdin = sc
|
|
||||||
p.closers = append(p.closers, sc)
|
|
||||||
}
|
}
|
||||||
var copyWaitGroup sync.WaitGroup
|
|
||||||
if socket != nil {
|
if socket != nil {
|
||||||
console, err := socket.ReceiveMaster()
|
console, err := socket.ReceiveMaster()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "failed to retrieve console master")
|
return errors.Wrap(err, "failed to retrieve console master")
|
||||||
}
|
}
|
||||||
console, err = p.Platform.CopyConsole(ctx, console, sio.Stdin, sio.Stdout, sio.Stderr, &p.wg, ©WaitGroup)
|
console, err = p.Platform.CopyConsole(ctx, console, sio.Stdin, sio.Stdout, sio.Stderr, &p.wg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "failed to start console copy")
|
return errors.Wrap(err, "failed to start console copy")
|
||||||
}
|
}
|
||||||
p.console = console
|
p.console = console
|
||||||
} else if !sio.IsNull() {
|
} else {
|
||||||
if err := copyPipes(ctx, p.io, sio.Stdin, sio.Stdout, sio.Stderr, &p.wg, ©WaitGroup); err != nil {
|
if err := p.io.Copy(ctx, &p.wg); err != nil {
|
||||||
return errors.Wrap(err, "failed to start io pipe copy")
|
return errors.Wrap(err, "failed to start io pipe copy")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
copyWaitGroup.Wait()
|
|
||||||
pid, err := runc.ReadPidFile(s.opts.PidFile)
|
pid, err := runc.ReadPidFile(s.opts.PidFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "failed to retrieve OCI runtime container pid")
|
return errors.Wrap(err, "failed to retrieve OCI runtime container pid")
|
||||||
|
215
vendor/github.com/containerd/containerd/runtime/v1/linux/proc/io.go
generated
vendored
215
vendor/github.com/containerd/containerd/runtime/v1/linux/proc/io.go
generated
vendored
@ -22,12 +22,18 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"path/filepath"
|
||||||
"sync"
|
"sync"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
|
"github.com/containerd/containerd/namespaces"
|
||||||
|
"github.com/containerd/containerd/runtime/proc"
|
||||||
"github.com/containerd/fifo"
|
"github.com/containerd/fifo"
|
||||||
runc "github.com/containerd/go-runc"
|
runc "github.com/containerd/go-runc"
|
||||||
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
var bufPool = sync.Pool{
|
var bufPool = sync.Pool{
|
||||||
@ -37,6 +43,84 @@ var bufPool = sync.Pool{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type processIO struct {
|
||||||
|
io runc.IO
|
||||||
|
|
||||||
|
uri *url.URL
|
||||||
|
copy bool
|
||||||
|
stdio proc.Stdio
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *processIO) Close() error {
|
||||||
|
if p.io != nil {
|
||||||
|
return p.io.Close()
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *processIO) IO() runc.IO {
|
||||||
|
return p.io
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *processIO) Copy(ctx context.Context, wg *sync.WaitGroup) error {
|
||||||
|
if !p.copy {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
var cwg sync.WaitGroup
|
||||||
|
if err := copyPipes(ctx, p.IO(), p.stdio.Stdin, p.stdio.Stdout, p.stdio.Stderr, wg, &cwg); err != nil {
|
||||||
|
return errors.Wrap(err, "unable to copy pipes")
|
||||||
|
}
|
||||||
|
cwg.Wait()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func createIO(ctx context.Context, id string, ioUID, ioGID int, stdio proc.Stdio) (*processIO, error) {
|
||||||
|
pio := &processIO{
|
||||||
|
stdio: stdio,
|
||||||
|
}
|
||||||
|
if stdio.IsNull() {
|
||||||
|
i, err := runc.NewNullIO()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
pio.io = i
|
||||||
|
return pio, nil
|
||||||
|
}
|
||||||
|
u, err := url.Parse(stdio.Stdout)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "unable to parse stdout uri")
|
||||||
|
}
|
||||||
|
if u.Scheme == "" {
|
||||||
|
u.Scheme = "fifo"
|
||||||
|
}
|
||||||
|
pio.uri = u
|
||||||
|
switch u.Scheme {
|
||||||
|
case "fifo":
|
||||||
|
pio.copy = true
|
||||||
|
pio.io, err = runc.NewPipeIO(ioUID, ioGID, withConditionalIO(stdio))
|
||||||
|
case "binary":
|
||||||
|
pio.io, err = newBinaryIO(ctx, id, u)
|
||||||
|
case "file":
|
||||||
|
if err := os.MkdirAll(filepath.Dir(u.Host), 0755); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
var f *os.File
|
||||||
|
f, err = os.OpenFile(u.Host, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
f.Close()
|
||||||
|
pio.copy = true
|
||||||
|
pio.io, err = runc.NewPipeIO(ioUID, ioGID, withConditionalIO(stdio))
|
||||||
|
default:
|
||||||
|
return nil, errors.Errorf("unknown STDIO scheme %s", u.Scheme)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return pio, nil
|
||||||
|
}
|
||||||
|
|
||||||
func copyPipes(ctx context.Context, rio runc.IO, stdin, stdout, stderr string, wg, cwg *sync.WaitGroup) error {
|
func copyPipes(ctx context.Context, rio runc.IO, stdin, stdout, stderr string, wg, cwg *sync.WaitGroup) error {
|
||||||
var sameFile io.WriteCloser
|
var sameFile io.WriteCloser
|
||||||
for _, i := range []struct {
|
for _, i := range []struct {
|
||||||
@ -143,3 +227,134 @@ func isFifo(path string) (bool, error) {
|
|||||||
}
|
}
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func newBinaryIO(ctx context.Context, id string, uri *url.URL) (runc.IO, error) {
|
||||||
|
ns, err := namespaces.NamespaceRequired(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
var args []string
|
||||||
|
for k, vs := range uri.Query() {
|
||||||
|
args = append(args, k)
|
||||||
|
if len(vs) > 0 {
|
||||||
|
args = append(args, vs[0])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ctx, cancel := context.WithCancel(ctx)
|
||||||
|
cmd := exec.CommandContext(ctx, uri.Host, args...)
|
||||||
|
cmd.Env = append(cmd.Env,
|
||||||
|
"CONTAINER_ID="+id,
|
||||||
|
"CONTAINER_NAMESPACE="+ns,
|
||||||
|
)
|
||||||
|
out, err := newPipe()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
serr, err := newPipe()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
r, w, err := os.Pipe()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
cmd.ExtraFiles = append(cmd.ExtraFiles, out.r, serr.r, w)
|
||||||
|
// don't need to register this with the reaper or wait when
|
||||||
|
// running inside a shim
|
||||||
|
if err := cmd.Start(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
// close our side of the pipe after start
|
||||||
|
w.Close()
|
||||||
|
// wait for the logging binary to be ready
|
||||||
|
b := make([]byte, 1)
|
||||||
|
if _, err := r.Read(b); err != nil && err != io.EOF {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &binaryIO{
|
||||||
|
cmd: cmd,
|
||||||
|
cancel: cancel,
|
||||||
|
out: out,
|
||||||
|
err: serr,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type binaryIO struct {
|
||||||
|
cmd *exec.Cmd
|
||||||
|
cancel func()
|
||||||
|
out, err *pipe
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *binaryIO) CloseAfterStart() (err error) {
|
||||||
|
for _, v := range []*pipe{
|
||||||
|
b.out,
|
||||||
|
b.err,
|
||||||
|
} {
|
||||||
|
if v != nil {
|
||||||
|
if cerr := v.r.Close(); err == nil {
|
||||||
|
err = cerr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *binaryIO) Close() (err error) {
|
||||||
|
b.cancel()
|
||||||
|
for _, v := range []*pipe{
|
||||||
|
b.out,
|
||||||
|
b.err,
|
||||||
|
} {
|
||||||
|
if v != nil {
|
||||||
|
if cerr := v.Close(); err == nil {
|
||||||
|
err = cerr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *binaryIO) Stdin() io.WriteCloser {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *binaryIO) Stdout() io.ReadCloser {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *binaryIO) Stderr() io.ReadCloser {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *binaryIO) Set(cmd *exec.Cmd) {
|
||||||
|
if b.out != nil {
|
||||||
|
cmd.Stdout = b.out.w
|
||||||
|
}
|
||||||
|
if b.err != nil {
|
||||||
|
cmd.Stderr = b.err.w
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func newPipe() (*pipe, error) {
|
||||||
|
r, w, err := os.Pipe()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &pipe{
|
||||||
|
r: r,
|
||||||
|
w: w,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type pipe struct {
|
||||||
|
r *os.File
|
||||||
|
w *os.File
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *pipe) Close() error {
|
||||||
|
err := p.w.Close()
|
||||||
|
if rerr := p.r.Close(); err == nil {
|
||||||
|
err = rerr
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
29
vendor/github.com/containerd/containerd/runtime/v1/linux/proc/utils.go
generated
vendored
29
vendor/github.com/containerd/containerd/runtime/v1/linux/proc/utils.go
generated
vendored
@ -20,8 +20,10 @@ package proc
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
@ -114,6 +116,29 @@ func checkKillError(err error) error {
|
|||||||
return errors.Wrapf(err, "unknown error after kill")
|
return errors.Wrapf(err, "unknown error after kill")
|
||||||
}
|
}
|
||||||
|
|
||||||
func hasNoIO(r *CreateConfig) bool {
|
// InitPidFile name of the file that contains the init pid
|
||||||
return r.Stdin == "" && r.Stdout == "" && r.Stderr == ""
|
const InitPidFile = "init.pid"
|
||||||
|
|
||||||
|
func newPidFile(bundle string) *pidFile {
|
||||||
|
return &pidFile{
|
||||||
|
path: filepath.Join(bundle, InitPidFile),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func newExecPidFile(bundle, id string) *pidFile {
|
||||||
|
return &pidFile{
|
||||||
|
path: filepath.Join(bundle, fmt.Sprintf("%s.pid", id)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type pidFile struct {
|
||||||
|
path string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *pidFile) Path() string {
|
||||||
|
return p.path
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *pidFile) Read() (int, error) {
|
||||||
|
return runc.ReadPidFile(p.path)
|
||||||
}
|
}
|
||||||
|
25
vendor/github.com/containerd/containerd/runtime/v1/shim/client/client.go
generated
vendored
25
vendor/github.com/containerd/containerd/runtime/v1/shim/client/client.go
generated
vendored
@ -20,10 +20,12 @@ package client
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"syscall"
|
"syscall"
|
||||||
@ -107,6 +109,10 @@ func WithStart(binary, address, daemonAddress, cgroup string, debug bool, exitHa
|
|||||||
"address": address,
|
"address": address,
|
||||||
"debug": debug,
|
"debug": debug,
|
||||||
}).Infof("shim %s started", binary)
|
}).Infof("shim %s started", binary)
|
||||||
|
|
||||||
|
if err := writeAddress(filepath.Join(config.Path, "address"), address); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
// set shim in cgroup if it is provided
|
// set shim in cgroup if it is provided
|
||||||
if cgroup != "" {
|
if cgroup != "" {
|
||||||
if err := setCgroup(cgroup, cmd); err != nil {
|
if err := setCgroup(cgroup, cmd); err != nil {
|
||||||
@ -166,6 +172,25 @@ func newCommand(binary, daemonAddress string, debug bool, config shim.Config, so
|
|||||||
return cmd, nil
|
return cmd, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// writeAddress writes a address file atomically
|
||||||
|
func writeAddress(path, address string) error {
|
||||||
|
path, err := filepath.Abs(path)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
tempPath := filepath.Join(filepath.Dir(path), fmt.Sprintf(".%s", filepath.Base(path)))
|
||||||
|
f, err := os.OpenFile(tempPath, os.O_RDWR|os.O_CREATE|os.O_EXCL|os.O_SYNC, 0666)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_, err = f.WriteString(address)
|
||||||
|
f.Close()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return os.Rename(tempPath, path)
|
||||||
|
}
|
||||||
|
|
||||||
func newSocket(address string) (*net.UnixListener, error) {
|
func newSocket(address string) (*net.UnixListener, error) {
|
||||||
if len(address) > 106 {
|
if len(address) > 106 {
|
||||||
return nil, errors.Errorf("%q: unix socket path too long (> 106)", address)
|
return nil, errors.Errorf("%q: unix socket path too long (> 106)", address)
|
||||||
|
4
vendor/github.com/containerd/containerd/runtime/v1/shim/service_linux.go
generated
vendored
4
vendor/github.com/containerd/containerd/runtime/v1/shim/service_linux.go
generated
vendored
@ -31,7 +31,7 @@ type linuxPlatform struct {
|
|||||||
epoller *console.Epoller
|
epoller *console.Epoller
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *linuxPlatform) CopyConsole(ctx context.Context, console console.Console, stdin, stdout, stderr string, wg, cwg *sync.WaitGroup) (console.Console, error) {
|
func (p *linuxPlatform) CopyConsole(ctx context.Context, console console.Console, stdin, stdout, stderr string, wg *sync.WaitGroup) (console.Console, error) {
|
||||||
if p.epoller == nil {
|
if p.epoller == nil {
|
||||||
return nil, errors.New("uninitialized epoller")
|
return nil, errors.New("uninitialized epoller")
|
||||||
}
|
}
|
||||||
@ -40,6 +40,7 @@ func (p *linuxPlatform) CopyConsole(ctx context.Context, console console.Console
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
var cwg sync.WaitGroup
|
||||||
|
|
||||||
if stdin != "" {
|
if stdin != "" {
|
||||||
in, err := fifo.OpenFifo(ctx, stdin, syscall.O_RDONLY, 0)
|
in, err := fifo.OpenFifo(ctx, stdin, syscall.O_RDONLY, 0)
|
||||||
@ -77,6 +78,7 @@ func (p *linuxPlatform) CopyConsole(ctx context.Context, console console.Console
|
|||||||
outw.Close()
|
outw.Close()
|
||||||
wg.Done()
|
wg.Done()
|
||||||
}()
|
}()
|
||||||
|
cwg.Wait()
|
||||||
return epollConsole, nil
|
return epollConsole, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
4
vendor/github.com/containerd/containerd/runtime/v1/shim/service_unix.go
generated
vendored
4
vendor/github.com/containerd/containerd/runtime/v1/shim/service_unix.go
generated
vendored
@ -31,7 +31,8 @@ import (
|
|||||||
type unixPlatform struct {
|
type unixPlatform struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *unixPlatform) CopyConsole(ctx context.Context, console console.Console, stdin, stdout, stderr string, wg, cwg *sync.WaitGroup) (console.Console, error) {
|
func (p *unixPlatform) CopyConsole(ctx context.Context, console console.Console, stdin, stdout, stderr string, wg *sync.WaitGroup) (console.Console, error) {
|
||||||
|
var cwg sync.WaitGroup
|
||||||
if stdin != "" {
|
if stdin != "" {
|
||||||
in, err := fifo.OpenFifo(ctx, stdin, syscall.O_RDONLY, 0)
|
in, err := fifo.OpenFifo(ctx, stdin, syscall.O_RDONLY, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -67,6 +68,7 @@ func (p *unixPlatform) CopyConsole(ctx context.Context, console console.Console,
|
|||||||
outw.Close()
|
outw.Close()
|
||||||
wg.Done()
|
wg.Done()
|
||||||
}()
|
}()
|
||||||
|
cwg.Wait()
|
||||||
return console, nil
|
return console, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
66
vendor/github.com/containerd/containerd/runtime/v2/README.md
generated
vendored
66
vendor/github.com/containerd/containerd/runtime/v2/README.md
generated
vendored
@ -169,7 +169,71 @@ The Runtime v2 supports an async event model. In order for the an upstream calle
|
|||||||
| Topic | Compliance | Description |
|
| Topic | Compliance | Description |
|
||||||
| ----- | ---------- | ----------- |
|
| ----- | ---------- | ----------- |
|
||||||
| `runtime.TaskExecAddedEventTopic` | MUST (follow `TaskCreateEventTopic` ) | When an exec is successfully added |
|
| `runtime.TaskExecAddedEventTopic` | MUST (follow `TaskCreateEventTopic` ) | When an exec is successfully added |
|
||||||
| `runtime.TaskExecStartedEventTopic` | MUST (follow `TaskExecStartedEventTopic`) | When an exec is successfully started |
|
| `runtime.TaskExecStartedEventTopic` | MUST (follow `TaskExecAddedEventTopic`) | When an exec is successfully started |
|
||||||
|
| `runtime.TaskExitEventTopic` | MUST (follow `TaskExecStartedEventTopic`) | When an exec (other than the init exec) exits expected or unexpected |
|
||||||
|
| `runtime.TaskDeleteEventTopic` | SHOULD (follow `TaskExitEventTopic` or `TaskExecAddedEventTopic` if never started) | When an exec is removed from a shim |
|
||||||
|
|
||||||
|
#### Logging
|
||||||
|
|
||||||
|
Shims may support pluggable logging via STDIO URIs.
|
||||||
|
Current supported schemes for logging are:
|
||||||
|
|
||||||
|
* fifo - Linux
|
||||||
|
* binary - Linux & Windows
|
||||||
|
* file - Linux & Windows
|
||||||
|
* npipe - Windows
|
||||||
|
|
||||||
|
Binary logging has the abilty to forward a container's STDIO to an external binary for consumption.
|
||||||
|
A sample logging driver that forwards the container's STDOUT and STDERR to `journald` is:
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"github.com/containerd/containerd/runtime/v2/logging"
|
||||||
|
"github.com/coreos/go-systemd/journal"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
logging.Run(log)
|
||||||
|
}
|
||||||
|
|
||||||
|
func log(ctx context.Context, config *logging.Config, ready func() error) error {
|
||||||
|
// construct any log metadata for the container
|
||||||
|
vars := map[string]string{
|
||||||
|
"SYSLOG_IDENTIFIER": fmt.Sprintf("%s:%s", config.Namespace, config.ID),
|
||||||
|
}
|
||||||
|
var wg sync.WaitGroup
|
||||||
|
wg.Add(2)
|
||||||
|
// forward both stdout and stderr to the journal
|
||||||
|
go copy(&wg, config.Stdout, journal.PriInfo, vars)
|
||||||
|
go copy(&wg, config.Stderr, journal.PriErr, vars)
|
||||||
|
|
||||||
|
// signal that we are ready and setup for the container to be started
|
||||||
|
if err := ready(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
wg.Wait()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func copy(wg *sync.WaitGroup, r io.Reader, pri journal.Priority, vars map[string]string) {
|
||||||
|
defer wg.Done()
|
||||||
|
s := bufio.NewScanner(r)
|
||||||
|
for s.Scan() {
|
||||||
|
if s.Err() != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
journal.Send(s.Text(), pri, vars)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
### Other
|
### Other
|
||||||
|
|
||||||
|
30
vendor/github.com/containerd/containerd/runtime/v2/manager.go
generated
vendored
30
vendor/github.com/containerd/containerd/runtime/v2/manager.go
generated
vendored
@ -29,11 +29,19 @@ import (
|
|||||||
"github.com/containerd/containerd/metadata"
|
"github.com/containerd/containerd/metadata"
|
||||||
"github.com/containerd/containerd/mount"
|
"github.com/containerd/containerd/mount"
|
||||||
"github.com/containerd/containerd/namespaces"
|
"github.com/containerd/containerd/namespaces"
|
||||||
|
"github.com/containerd/containerd/platforms"
|
||||||
"github.com/containerd/containerd/plugin"
|
"github.com/containerd/containerd/plugin"
|
||||||
"github.com/containerd/containerd/runtime"
|
"github.com/containerd/containerd/runtime"
|
||||||
|
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||||
bolt "go.etcd.io/bbolt"
|
bolt "go.etcd.io/bbolt"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Config for the v2 runtime
|
||||||
|
type Config struct {
|
||||||
|
// Supported platforms
|
||||||
|
Platforms []string `toml:"platforms"`
|
||||||
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
plugin.Register(&plugin.Registration{
|
plugin.Register(&plugin.Registration{
|
||||||
Type: plugin.RuntimePluginV2,
|
Type: plugin.RuntimePluginV2,
|
||||||
@ -41,8 +49,16 @@ func init() {
|
|||||||
Requires: []plugin.Type{
|
Requires: []plugin.Type{
|
||||||
plugin.MetadataPlugin,
|
plugin.MetadataPlugin,
|
||||||
},
|
},
|
||||||
|
Config: &Config{
|
||||||
|
Platforms: defaultPlatforms(),
|
||||||
|
},
|
||||||
InitFn: func(ic *plugin.InitContext) (interface{}, error) {
|
InitFn: func(ic *plugin.InitContext) (interface{}, error) {
|
||||||
ic.Meta.Platforms = supportedPlatforms()
|
supportedPlatforms, err := parsePlatforms(ic.Config.(*Config).Platforms)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
ic.Meta.Platforms = supportedPlatforms
|
||||||
if err := os.MkdirAll(ic.Root, 0711); err != nil {
|
if err := os.MkdirAll(ic.Root, 0711); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -262,3 +278,15 @@ func (m *TaskManager) cleanupWorkDirs(ctx context.Context) error {
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func parsePlatforms(platformStr []string) ([]ocispec.Platform, error) {
|
||||||
|
p := make([]ocispec.Platform, len(platformStr))
|
||||||
|
for i, v := range platformStr {
|
||||||
|
parsed, err := platforms.Parse(v)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
p[i] = parsed
|
||||||
|
}
|
||||||
|
return p, nil
|
||||||
|
}
|
||||||
|
5
vendor/github.com/containerd/containerd/runtime/v2/manager_unix.go
generated
vendored
5
vendor/github.com/containerd/containerd/runtime/v2/manager_unix.go
generated
vendored
@ -20,9 +20,8 @@ package v2
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/containerd/containerd/platforms"
|
"github.com/containerd/containerd/platforms"
|
||||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func supportedPlatforms() []ocispec.Platform {
|
func defaultPlatforms() []string {
|
||||||
return []ocispec.Platform{platforms.DefaultSpec()}
|
return []string{platforms.DefaultString()}
|
||||||
}
|
}
|
||||||
|
12
vendor/github.com/containerd/containerd/runtime/v2/manager_windows.go
generated
vendored
12
vendor/github.com/containerd/containerd/runtime/v2/manager_windows.go
generated
vendored
@ -20,15 +20,11 @@ package v2
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/containerd/containerd/platforms"
|
"github.com/containerd/containerd/platforms"
|
||||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func supportedPlatforms() []ocispec.Platform {
|
func defaultPlatforms() []string {
|
||||||
return []ocispec.Platform{
|
return []string{
|
||||||
platforms.DefaultSpec(),
|
platforms.DefaultString(),
|
||||||
{
|
"linux/amd64",
|
||||||
OS: "linux",
|
|
||||||
Architecture: "amd64",
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
5
vendor/github.com/containerd/containerd/runtime/v2/shim.go
generated
vendored
5
vendor/github.com/containerd/containerd/runtime/v2/shim.go
generated
vendored
@ -99,7 +99,9 @@ type shim struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *shim) Connect(ctx context.Context) error {
|
func (s *shim) Connect(ctx context.Context) error {
|
||||||
response, err := s.task.Connect(ctx, &task.ConnectRequest{})
|
response, err := s.task.Connect(ctx, &task.ConnectRequest{
|
||||||
|
ID: s.ID(),
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -317,6 +319,7 @@ func (s *shim) Wait(ctx context.Context) (*runtime.Exit, error) {
|
|||||||
|
|
||||||
func (s *shim) Checkpoint(ctx context.Context, path string, options *ptypes.Any) error {
|
func (s *shim) Checkpoint(ctx context.Context, path string, options *ptypes.Any) error {
|
||||||
request := &task.CheckpointTaskRequest{
|
request := &task.CheckpointTaskRequest{
|
||||||
|
ID: s.ID(),
|
||||||
Path: path,
|
Path: path,
|
||||||
Options: options,
|
Options: options,
|
||||||
}
|
}
|
||||||
|
20
vendor/github.com/containerd/containerd/runtime/v2/shim/util.go
generated
vendored
20
vendor/github.com/containerd/containerd/runtime/v2/shim/util.go
generated
vendored
@ -19,6 +19,7 @@ package shim
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
@ -150,3 +151,22 @@ func WriteAddress(path, address string) error {
|
|||||||
}
|
}
|
||||||
return os.Rename(tempPath, path)
|
return os.Rename(tempPath, path)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ErrNoAddress is returned when the address file has no content
|
||||||
|
var ErrNoAddress = errors.New("no shim address")
|
||||||
|
|
||||||
|
// ReadAddress returns the shim's abstract socket address from the path
|
||||||
|
func ReadAddress(path string) (string, error) {
|
||||||
|
path, err := filepath.Abs(path)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
data, err := ioutil.ReadFile(path)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
if len(data) == 0 {
|
||||||
|
return "", ErrNoAddress
|
||||||
|
}
|
||||||
|
return string(data), nil
|
||||||
|
}
|
||||||
|
5
vendor/github.com/containerd/containerd/runtime/v2/shim/util_unix.go
generated
vendored
5
vendor/github.com/containerd/containerd/runtime/v2/shim/util_unix.go
generated
vendored
@ -20,6 +20,8 @@ package shim
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"crypto/sha256"
|
||||||
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
@ -50,7 +52,8 @@ func SocketAddress(ctx context.Context, id string) (string, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
return filepath.Join(string(filepath.Separator), "containerd-shim", ns, id, "shim.sock"), nil
|
d := sha256.Sum256([]byte(filepath.Join(ns, id)))
|
||||||
|
return filepath.Join(string(filepath.Separator), "containerd-shim", fmt.Sprintf("%x.sock", d)), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// AnonDialer returns a dialer for an abstract socket
|
// AnonDialer returns a dialer for an abstract socket
|
||||||
|
2
vendor/github.com/containerd/containerd/runtime/v2/shim_windows.go
generated
vendored
2
vendor/github.com/containerd/containerd/runtime/v2/shim_windows.go
generated
vendored
@ -78,7 +78,7 @@ func openShimLog(ctx context.Context, bundle *Bundle) (io.ReadCloser, error) {
|
|||||||
time.Second*10,
|
time.Second*10,
|
||||||
)
|
)
|
||||||
if conerr != nil {
|
if conerr != nil {
|
||||||
dpc.conerr = errors.Wrap(err, "failed to connect to shim log")
|
dpc.conerr = errors.Wrap(conerr, "failed to connect to shim log")
|
||||||
}
|
}
|
||||||
dpc.c = c
|
dpc.c = c
|
||||||
dpc.wg.Done()
|
dpc.wg.Done()
|
||||||
|
199
vendor/github.com/containerd/containerd/runtime/v2/task/shim.pb.go
generated
vendored
199
vendor/github.com/containerd/containerd/runtime/v2/task/shim.pb.go
generated
vendored
@ -168,6 +168,7 @@ type StateResponse struct {
|
|||||||
Terminal bool `protobuf:"varint,8,opt,name=terminal,proto3" json:"terminal,omitempty"`
|
Terminal bool `protobuf:"varint,8,opt,name=terminal,proto3" json:"terminal,omitempty"`
|
||||||
ExitStatus uint32 `protobuf:"varint,9,opt,name=exit_status,json=exitStatus,proto3" json:"exit_status,omitempty"`
|
ExitStatus uint32 `protobuf:"varint,9,opt,name=exit_status,json=exitStatus,proto3" json:"exit_status,omitempty"`
|
||||||
ExitedAt time.Time `protobuf:"bytes,10,opt,name=exited_at,json=exitedAt,stdtime" json:"exited_at"`
|
ExitedAt time.Time `protobuf:"bytes,10,opt,name=exited_at,json=exitedAt,stdtime" json:"exited_at"`
|
||||||
|
ExecID string `protobuf:"bytes,11,opt,name=exec_id,json=execId,proto3" json:"exec_id,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *StateResponse) Reset() { *m = StateResponse{} }
|
func (m *StateResponse) Reset() { *m = StateResponse{} }
|
||||||
@ -767,6 +768,12 @@ func (m *StateResponse) MarshalTo(dAtA []byte) (int, error) {
|
|||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
i += n4
|
i += n4
|
||||||
|
if len(m.ExecID) > 0 {
|
||||||
|
dAtA[i] = 0x5a
|
||||||
|
i++
|
||||||
|
i = encodeVarintShim(dAtA, i, uint64(len(m.ExecID)))
|
||||||
|
i += copy(dAtA[i:], m.ExecID)
|
||||||
|
}
|
||||||
return i, nil
|
return i, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1492,6 +1499,10 @@ func (m *StateResponse) Size() (n int) {
|
|||||||
}
|
}
|
||||||
l = types.SizeOfStdTime(m.ExitedAt)
|
l = types.SizeOfStdTime(m.ExitedAt)
|
||||||
n += 1 + l + sovShim(uint64(l))
|
n += 1 + l + sovShim(uint64(l))
|
||||||
|
l = len(m.ExecID)
|
||||||
|
if l > 0 {
|
||||||
|
n += 1 + l + sovShim(uint64(l))
|
||||||
|
}
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1842,6 +1853,7 @@ func (this *StateResponse) String() string {
|
|||||||
`Terminal:` + fmt.Sprintf("%v", this.Terminal) + `,`,
|
`Terminal:` + fmt.Sprintf("%v", this.Terminal) + `,`,
|
||||||
`ExitStatus:` + fmt.Sprintf("%v", this.ExitStatus) + `,`,
|
`ExitStatus:` + fmt.Sprintf("%v", this.ExitStatus) + `,`,
|
||||||
`ExitedAt:` + strings.Replace(strings.Replace(this.ExitedAt.String(), "Timestamp", "google_protobuf3.Timestamp", 1), `&`, ``, 1) + `,`,
|
`ExitedAt:` + strings.Replace(strings.Replace(this.ExitedAt.String(), "Timestamp", "google_protobuf3.Timestamp", 1), `&`, ``, 1) + `,`,
|
||||||
|
`ExecID:` + fmt.Sprintf("%v", this.ExecID) + `,`,
|
||||||
`}`,
|
`}`,
|
||||||
}, "")
|
}, "")
|
||||||
return s
|
return s
|
||||||
@ -3793,6 +3805,35 @@ func (m *StateResponse) Unmarshal(dAtA []byte) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
iNdEx = postIndex
|
iNdEx = postIndex
|
||||||
|
case 11:
|
||||||
|
if wireType != 2 {
|
||||||
|
return fmt.Errorf("proto: wrong wireType = %d for field ExecID", wireType)
|
||||||
|
}
|
||||||
|
var stringLen uint64
|
||||||
|
for shift := uint(0); ; shift += 7 {
|
||||||
|
if shift >= 64 {
|
||||||
|
return ErrIntOverflowShim
|
||||||
|
}
|
||||||
|
if iNdEx >= l {
|
||||||
|
return io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
b := dAtA[iNdEx]
|
||||||
|
iNdEx++
|
||||||
|
stringLen |= (uint64(b) & 0x7F) << shift
|
||||||
|
if b < 0x80 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
intStringLen := int(stringLen)
|
||||||
|
if intStringLen < 0 {
|
||||||
|
return ErrInvalidLengthShim
|
||||||
|
}
|
||||||
|
postIndex := iNdEx + intStringLen
|
||||||
|
if postIndex > l {
|
||||||
|
return io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
m.ExecID = string(dAtA[iNdEx:postIndex])
|
||||||
|
iNdEx = postIndex
|
||||||
default:
|
default:
|
||||||
iNdEx = preIndex
|
iNdEx = preIndex
|
||||||
skippy, err := skipShim(dAtA[iNdEx:])
|
skippy, err := skipShim(dAtA[iNdEx:])
|
||||||
@ -5611,83 +5652,83 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var fileDescriptorShim = []byte{
|
var fileDescriptorShim = []byte{
|
||||||
// 1240 bytes of a gzipped FileDescriptorProto
|
// 1246 bytes of a gzipped FileDescriptorProto
|
||||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x58, 0xdb, 0x6f, 0x1b, 0xc5,
|
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x58, 0x5d, 0x6f, 0x1b, 0x45,
|
||||||
0x17, 0xee, 0xfa, 0xb2, 0xb6, 0x8f, 0xeb, 0x34, 0x9d, 0x5f, 0x9a, 0xdf, 0xd6, 0x95, 0x6c, 0x77,
|
0x17, 0xee, 0xfa, 0x63, 0x6d, 0x1f, 0xd7, 0x69, 0x3a, 0x6f, 0x9a, 0x77, 0xeb, 0x4a, 0xb6, 0xbb,
|
||||||
0x4b, 0x83, 0x01, 0xc9, 0x16, 0xae, 0xe0, 0x81, 0x48, 0xa0, 0xdc, 0xa8, 0x4c, 0x0b, 0x89, 0xb6,
|
0xa5, 0xc1, 0x80, 0x64, 0x0b, 0x57, 0x70, 0x41, 0x24, 0x50, 0xbe, 0xa8, 0x4c, 0x0b, 0x89, 0xb6,
|
||||||
0x45, 0x45, 0xbc, 0x58, 0x1b, 0xef, 0xc4, 0x5e, 0xc5, 0xde, 0x59, 0x76, 0x66, 0x73, 0x41, 0x42,
|
0x45, 0x45, 0xdc, 0x58, 0x1b, 0xef, 0xc4, 0x5e, 0xc5, 0xde, 0x59, 0x76, 0x66, 0xf3, 0x81, 0x84,
|
||||||
0xe2, 0x89, 0x07, 0x9e, 0xf8, 0xb3, 0xf2, 0xc0, 0x03, 0x12, 0x2f, 0xbc, 0x10, 0xa8, 0xff, 0x12,
|
0xc4, 0x15, 0x17, 0x5c, 0xf1, 0xb3, 0x72, 0x89, 0xc4, 0x0d, 0x37, 0x04, 0xea, 0x7f, 0xc0, 0x3f,
|
||||||
0x34, 0x17, 0xc7, 0x6b, 0x67, 0xd7, 0x4e, 0x2a, 0xbf, 0x44, 0x73, 0x76, 0xbe, 0x39, 0x33, 0xe7,
|
0x40, 0xf3, 0xe1, 0x78, 0xed, 0xec, 0xda, 0x49, 0xe5, 0x9b, 0x68, 0xce, 0xce, 0x33, 0x67, 0xe6,
|
||||||
0xcc, 0x77, 0xbe, 0x33, 0x31, 0x6c, 0xf6, 0x5c, 0xd6, 0x0f, 0x0f, 0x1b, 0x5d, 0x32, 0x6c, 0x76,
|
0x9c, 0x79, 0xce, 0x73, 0x26, 0x86, 0xcd, 0x9e, 0xcb, 0xfa, 0xe1, 0x61, 0xa3, 0x4b, 0x86, 0xcd,
|
||||||
0x89, 0xc7, 0x6c, 0xd7, 0xc3, 0x81, 0x13, 0x1d, 0x06, 0xa1, 0xc7, 0xdc, 0x21, 0x6e, 0x9e, 0xb4,
|
0x2e, 0xf1, 0x98, 0xed, 0x7a, 0x38, 0x70, 0xa2, 0xc3, 0x20, 0xf4, 0x98, 0x3b, 0xc4, 0xcd, 0x93,
|
||||||
0x9a, 0xcc, 0xa6, 0xc7, 0x4d, 0xda, 0x77, 0x87, 0x0d, 0x3f, 0x20, 0x8c, 0x20, 0x34, 0x81, 0x35,
|
0x56, 0x93, 0xd9, 0xf4, 0xb8, 0x49, 0xfb, 0xee, 0xb0, 0xe1, 0x07, 0x84, 0x11, 0x84, 0x26, 0xb0,
|
||||||
0xf8, 0x5c, 0xe3, 0xa4, 0x55, 0x7e, 0xd8, 0x23, 0xa4, 0x37, 0xc0, 0x4d, 0x81, 0x38, 0x0c, 0x8f,
|
0x06, 0x9f, 0x6b, 0x9c, 0xb4, 0xca, 0x0f, 0x7b, 0x84, 0xf4, 0x06, 0xb8, 0x29, 0x10, 0x87, 0xe1,
|
||||||
0x9a, 0xb6, 0x77, 0x2e, 0xe1, 0xe5, 0x47, 0xb3, 0x53, 0x78, 0xe8, 0xb3, 0xf1, 0xe4, 0x5a, 0x8f,
|
0x51, 0xd3, 0xf6, 0xce, 0x25, 0xbc, 0xfc, 0x68, 0x76, 0x0a, 0x0f, 0x7d, 0x36, 0x9e, 0x5c, 0xeb,
|
||||||
0xf4, 0x88, 0x18, 0x36, 0xf9, 0x48, 0x7d, 0xad, 0xce, 0x2e, 0xe1, 0x47, 0xa1, 0xcc, 0x1e, 0xfa,
|
0x91, 0x1e, 0x11, 0xc3, 0x26, 0x1f, 0xa9, 0xaf, 0xd5, 0xd9, 0x25, 0xfc, 0x28, 0x94, 0xd9, 0x43,
|
||||||
0x0a, 0xf0, 0xe9, 0xc2, 0xf3, 0xdb, 0xbe, 0xdb, 0x64, 0xe7, 0x3e, 0xa6, 0xcd, 0x21, 0x09, 0x3d,
|
0x5f, 0x01, 0x3e, 0x5d, 0x78, 0x7e, 0xdb, 0x77, 0x9b, 0xec, 0xdc, 0xc7, 0xb4, 0x39, 0x24, 0xa1,
|
||||||
0xa6, 0xd6, 0x7d, 0x76, 0x8b, 0x75, 0x22, 0x6c, 0x11, 0x9f, 0x58, 0x6b, 0xfe, 0x99, 0x82, 0xfb,
|
0xc7, 0xd4, 0xba, 0xcf, 0x6e, 0xb1, 0x4e, 0x84, 0x2d, 0xe2, 0x13, 0x6b, 0xcd, 0x3f, 0x52, 0x70,
|
||||||
0x3b, 0x01, 0xb6, 0x19, 0x7e, 0x6d, 0xd3, 0x63, 0x0b, 0xff, 0x10, 0x62, 0xca, 0xd0, 0x3a, 0xa4,
|
0x7f, 0x27, 0xc0, 0x36, 0xc3, 0xaf, 0x6d, 0x7a, 0x6c, 0xe1, 0x1f, 0x42, 0x4c, 0x19, 0x5a, 0x87,
|
||||||
0x5c, 0xc7, 0xd0, 0x6a, 0x5a, 0xbd, 0xb0, 0xad, 0x8f, 0x2e, 0xab, 0xa9, 0xf6, 0xae, 0x95, 0x72,
|
0x94, 0xeb, 0x18, 0x5a, 0x4d, 0xab, 0x17, 0xb6, 0xf5, 0xd1, 0x65, 0x35, 0xd5, 0xde, 0xb5, 0x52,
|
||||||
0x1d, 0xb4, 0x0e, 0xfa, 0x61, 0xe8, 0x39, 0x03, 0x6c, 0xa4, 0xf8, 0x9c, 0xa5, 0x2c, 0xd4, 0x04,
|
0xae, 0x83, 0xd6, 0x41, 0x3f, 0x0c, 0x3d, 0x67, 0x80, 0x8d, 0x14, 0x9f, 0xb3, 0x94, 0x85, 0x9a,
|
||||||
0x3d, 0x20, 0x84, 0x1d, 0x51, 0x23, 0x5d, 0x4b, 0xd7, 0x8b, 0xad, 0xff, 0x37, 0xa2, 0xd9, 0xe4,
|
0xa0, 0x07, 0x84, 0xb0, 0x23, 0x6a, 0xa4, 0x6b, 0xe9, 0x7a, 0xb1, 0xf5, 0xff, 0x46, 0x34, 0x9b,
|
||||||
0x1b, 0x37, 0xbe, 0xe6, 0x07, 0xb6, 0x14, 0x0c, 0x95, 0x21, 0xcf, 0x70, 0x30, 0x74, 0x3d, 0x7b,
|
0x7c, 0xe3, 0xc6, 0xd7, 0xfc, 0xc0, 0x96, 0x82, 0xa1, 0x32, 0xe4, 0x19, 0x0e, 0x86, 0xae, 0x67,
|
||||||
0x60, 0x64, 0x6a, 0x5a, 0x3d, 0x6f, 0x5d, 0xd9, 0x68, 0x0d, 0xb2, 0x94, 0x39, 0xae, 0x67, 0x64,
|
0x0f, 0x8c, 0x4c, 0x4d, 0xab, 0xe7, 0xad, 0x2b, 0x1b, 0xad, 0x41, 0x96, 0x32, 0xc7, 0xf5, 0x8c,
|
||||||
0xc5, 0x1e, 0xd2, 0xe0, 0x5b, 0x53, 0xe6, 0x90, 0x90, 0x19, 0xba, 0xdc, 0x5a, 0x5a, 0xea, 0x3b,
|
0xac, 0xd8, 0x43, 0x1a, 0x7c, 0x6b, 0xca, 0x1c, 0x12, 0x32, 0x43, 0x97, 0x5b, 0x4b, 0x4b, 0x7d,
|
||||||
0x0e, 0x02, 0x23, 0x77, 0xf5, 0x1d, 0x07, 0x01, 0xaa, 0x00, 0x74, 0xfb, 0xb8, 0x7b, 0xec, 0x13,
|
0xc7, 0x41, 0x60, 0xe4, 0xae, 0xbe, 0xe3, 0x20, 0x40, 0x15, 0x80, 0x6e, 0x1f, 0x77, 0x8f, 0x7d,
|
||||||
0xd7, 0x63, 0x46, 0x5e, 0xcc, 0x45, 0xbe, 0xa0, 0x8f, 0xe0, 0xbe, 0x6f, 0x07, 0xd8, 0x63, 0x9d,
|
0xe2, 0x7a, 0xcc, 0xc8, 0x8b, 0xb9, 0xc8, 0x17, 0xf4, 0x11, 0xdc, 0xf7, 0xed, 0x00, 0x7b, 0xac,
|
||||||
0x08, 0xac, 0x20, 0x60, 0xab, 0x72, 0x62, 0x67, 0x02, 0x6e, 0x40, 0x8e, 0xf8, 0xcc, 0x25, 0x1e,
|
0x13, 0x81, 0x15, 0x04, 0x6c, 0x55, 0x4e, 0xec, 0x4c, 0xc0, 0x0d, 0xc8, 0x11, 0x9f, 0xb9, 0xc4,
|
||||||
0x35, 0xa0, 0xa6, 0xd5, 0x8b, 0xad, 0xb5, 0x86, 0xbc, 0xcc, 0xc6, 0xf8, 0x32, 0x1b, 0x5b, 0xde,
|
0xa3, 0x06, 0xd4, 0xb4, 0x7a, 0xb1, 0xb5, 0xd6, 0x90, 0x97, 0xd9, 0x18, 0x5f, 0x66, 0x63, 0xcb,
|
||||||
0xb9, 0x35, 0x06, 0x99, 0x1b, 0x80, 0xa2, 0x49, 0xa5, 0x3e, 0xf1, 0x28, 0x46, 0xab, 0x90, 0xf6,
|
0x3b, 0xb7, 0xc6, 0x20, 0x73, 0x03, 0x50, 0x34, 0xa9, 0xd4, 0x27, 0x1e, 0xc5, 0x68, 0x15, 0xd2,
|
||||||
0x55, 0x5a, 0x4b, 0x16, 0x1f, 0x9a, 0x2f, 0xa1, 0xb4, 0x8b, 0x07, 0x98, 0xe1, 0x45, 0x89, 0x7f,
|
0xbe, 0x4a, 0x6b, 0xc9, 0xe2, 0x43, 0xf3, 0x25, 0x94, 0x76, 0xf1, 0x00, 0x33, 0xbc, 0x28, 0xf1,
|
||||||
0x02, 0x39, 0x7c, 0x86, 0xbb, 0x1d, 0xd7, 0x91, 0x99, 0xdf, 0x86, 0xd1, 0x65, 0x55, 0xdf, 0x3b,
|
0x4f, 0x20, 0x87, 0xcf, 0x70, 0xb7, 0xe3, 0x3a, 0x32, 0xf3, 0xdb, 0x30, 0xba, 0xac, 0xea, 0x7b,
|
||||||
0xc3, 0xdd, 0xf6, 0xae, 0xa5, 0xf3, 0xa9, 0xb6, 0x63, 0xfe, 0xa2, 0xc1, 0xca, 0xd8, 0x5d, 0xd2,
|
0x67, 0xb8, 0xdb, 0xde, 0xb5, 0x74, 0x3e, 0xd5, 0x76, 0xcc, 0x5f, 0x34, 0x58, 0x19, 0xbb, 0x4b,
|
||||||
0x96, 0xa8, 0x0a, 0x45, 0x7c, 0xe6, 0xb2, 0x0e, 0x65, 0x36, 0x0b, 0xa9, 0xf0, 0x56, 0xb2, 0x80,
|
0xda, 0x12, 0x55, 0xa1, 0x88, 0xcf, 0x5c, 0xd6, 0xa1, 0xcc, 0x66, 0x21, 0x15, 0xde, 0x4a, 0x16,
|
||||||
0x7f, 0x7a, 0x25, 0xbe, 0xa0, 0x2d, 0x28, 0x70, 0x0b, 0x3b, 0x1d, 0x9b, 0x19, 0x69, 0x11, 0x6d,
|
0xf0, 0x4f, 0xaf, 0xc4, 0x17, 0xb4, 0x05, 0x05, 0x6e, 0x61, 0xa7, 0x63, 0x33, 0x23, 0x2d, 0xa2,
|
||||||
0xf9, 0x5a, 0xb4, 0xaf, 0xc7, 0xd4, 0xdd, 0xce, 0x5f, 0x5c, 0x56, 0xef, 0xfc, 0xf6, 0x4f, 0x55,
|
0x2d, 0x5f, 0x8b, 0xf6, 0xf5, 0x98, 0xba, 0xdb, 0xf9, 0x8b, 0xcb, 0xea, 0x9d, 0xdf, 0xfe, 0xae,
|
||||||
0xb3, 0xf2, 0x72, 0xd9, 0x16, 0x33, 0xff, 0xd6, 0x00, 0xf1, 0xb3, 0x1d, 0x04, 0xa4, 0x8b, 0x29,
|
0x6a, 0x56, 0x5e, 0x2e, 0xdb, 0x62, 0xe6, 0x5f, 0x1a, 0x20, 0x7e, 0xb6, 0x83, 0x80, 0x74, 0x31,
|
||||||
0x5d, 0x46, 0x70, 0x53, 0x8c, 0x49, 0x27, 0x31, 0x26, 0x13, 0xcf, 0x98, 0x6c, 0x02, 0x63, 0xf4,
|
0xa5, 0xcb, 0x08, 0x6e, 0x8a, 0x31, 0xe9, 0x24, 0xc6, 0x64, 0xe2, 0x19, 0x93, 0x4d, 0x60, 0x8c,
|
||||||
0x29, 0xc6, 0xd4, 0x21, 0x43, 0x7d, 0xdc, 0x15, 0x3c, 0x4a, 0xba, 0x61, 0x81, 0x30, 0x1f, 0xc0,
|
0x3e, 0xc5, 0x98, 0x3a, 0x64, 0xa8, 0x8f, 0xbb, 0x82, 0x47, 0x49, 0x37, 0x2c, 0x10, 0xe6, 0x03,
|
||||||
0xff, 0xa6, 0xc2, 0x93, 0xc9, 0x36, 0x7f, 0x82, 0x55, 0x0b, 0x53, 0xf7, 0x47, 0x7c, 0xc0, 0xce,
|
0xf8, 0xdf, 0x54, 0x78, 0x32, 0xd9, 0xe6, 0x4f, 0xb0, 0x6a, 0x61, 0xea, 0xfe, 0x88, 0x0f, 0xd8,
|
||||||
0x97, 0x12, 0xf3, 0x1a, 0x64, 0x4f, 0x5d, 0x87, 0xf5, 0x45, 0xc0, 0x25, 0x4b, 0x1a, 0xfc, 0xfc,
|
0xf9, 0x52, 0x62, 0x5e, 0x83, 0xec, 0xa9, 0xeb, 0xb0, 0xbe, 0x08, 0xb8, 0x64, 0x49, 0x83, 0x9f,
|
||||||
0x7d, 0xec, 0xf6, 0xfa, 0x4c, 0x84, 0x5b, 0xb2, 0x94, 0x65, 0xbe, 0x80, 0xbb, 0xfc, 0x0a, 0x97,
|
0xbf, 0x8f, 0xdd, 0x5e, 0x9f, 0x89, 0x70, 0x4b, 0x96, 0xb2, 0xcc, 0x17, 0x70, 0x97, 0x5f, 0xe1,
|
||||||
0xc3, 0xa5, 0xdf, 0x53, 0x50, 0x52, 0xde, 0x14, 0x95, 0x6e, 0xab, 0x09, 0x8a, 0x7a, 0xe9, 0x09,
|
0x72, 0xb8, 0xf4, 0x6f, 0x0a, 0x4a, 0xca, 0x9b, 0xa2, 0xd2, 0x6d, 0x35, 0x41, 0x51, 0x2f, 0x3d,
|
||||||
0xf5, 0x9e, 0xf1, 0xc4, 0x0b, 0xd6, 0xf1, 0x83, 0xaf, 0xb4, 0x1e, 0x45, 0x55, 0xe2, 0xe4, 0x63,
|
0xa1, 0xde, 0x33, 0x9e, 0x78, 0xc1, 0x3a, 0x7e, 0xf0, 0x95, 0xd6, 0xa3, 0xa8, 0x4a, 0x9c, 0x7c,
|
||||||
0x25, 0x14, 0x92, 0x86, 0x96, 0x82, 0x2e, 0x49, 0x0d, 0xa2, 0xec, 0xc9, 0xcf, 0xb0, 0x67, 0xa6,
|
0xac, 0x84, 0x42, 0xd2, 0xd0, 0x52, 0xd0, 0x25, 0xa9, 0x41, 0x94, 0x3d, 0xf9, 0x19, 0xf6, 0xcc,
|
||||||
0x22, 0x0a, 0xf3, 0x2b, 0x02, 0xde, 0xa9, 0x22, 0x18, 0x14, 0x5f, 0xb8, 0x83, 0xc1, 0x52, 0x58,
|
0x54, 0x44, 0x61, 0x7e, 0x45, 0xc0, 0xbb, 0x54, 0x44, 0x34, 0xe7, 0xc5, 0xc4, 0x9c, 0x33, 0x28,
|
||||||
0xc1, 0x63, 0x74, 0x7b, 0xe3, 0x3a, 0x28, 0x59, 0xca, 0xe2, 0x09, 0xb7, 0x07, 0x63, 0x39, 0xe5,
|
0xbe, 0x70, 0x07, 0x83, 0xa5, 0x50, 0x87, 0x27, 0xc2, 0xed, 0x8d, 0x8b, 0xa5, 0x64, 0x29, 0x8b,
|
||||||
0x43, 0xb3, 0x0b, 0x2b, 0x3b, 0x03, 0x42, 0x71, 0x7b, 0x7f, 0x59, 0x74, 0x94, 0x57, 0x21, 0xeb,
|
0xdf, 0x8a, 0x3d, 0x18, 0x6b, 0x2e, 0x1f, 0x9a, 0x5d, 0x58, 0xd9, 0x19, 0x10, 0x8a, 0xdb, 0xfb,
|
||||||
0x4f, 0x1a, 0xe6, 0x53, 0x28, 0x1e, 0xb8, 0xce, 0xa2, 0x22, 0x37, 0xbf, 0x81, 0xbb, 0x12, 0xa6,
|
0xcb, 0xe2, 0xac, 0xbc, 0x2f, 0x59, 0xa4, 0xd2, 0x30, 0x9f, 0x42, 0xf1, 0xc0, 0x75, 0x16, 0x29,
|
||||||
0xe8, 0xf4, 0x39, 0x14, 0x7c, 0x59, 0x3f, 0x98, 0x1a, 0x9a, 0xe8, 0x1a, 0xb5, 0x58, 0x3e, 0xa8,
|
0x81, 0xf9, 0x0d, 0xdc, 0x95, 0x30, 0xc5, 0xb9, 0xcf, 0xa1, 0xe0, 0xcb, 0x22, 0xc3, 0xd4, 0xd0,
|
||||||
0x2a, 0x6b, 0x7b, 0x47, 0xc4, 0x9a, 0x2c, 0x31, 0x29, 0x3c, 0x98, 0x08, 0xf4, 0x4d, 0x7a, 0x17,
|
0x44, 0x6b, 0xa9, 0xc5, 0x92, 0x46, 0x95, 0x62, 0xdb, 0x3b, 0x22, 0xd6, 0x64, 0x89, 0x49, 0xe1,
|
||||||
0x82, 0x8c, 0x6f, 0xb3, 0xbe, 0x62, 0xa9, 0x18, 0x47, 0x75, 0x3d, 0x7d, 0x13, 0x5d, 0xef, 0xc0,
|
0xc1, 0x44, 0xc5, 0x6f, 0xd2, 0xe0, 0x10, 0x64, 0x7c, 0x9b, 0xf5, 0x15, 0x95, 0xc5, 0x38, 0x2a,
|
||||||
0xfd, 0x6f, 0x7d, 0xe7, 0x86, 0xcd, 0xb2, 0x05, 0x85, 0x00, 0x53, 0x12, 0x06, 0x5d, 0x2c, 0x75,
|
0xfe, 0xe9, 0x9b, 0x88, 0x7f, 0x07, 0xee, 0x7f, 0xeb, 0x3b, 0x37, 0xec, 0xa8, 0x2d, 0x28, 0x04,
|
||||||
0x36, 0xc9, 0xfd, 0x04, 0xa6, 0x6a, 0x38, 0x60, 0x4b, 0xa9, 0xe1, 0xc7, 0xa2, 0x84, 0xb9, 0xb3,
|
0x98, 0x92, 0x30, 0xe8, 0x62, 0x29, 0xc6, 0x49, 0xee, 0x27, 0x30, 0x55, 0xe8, 0x01, 0x5b, 0x4a,
|
||||||
0xc4, 0x06, 0xf4, 0x15, 0x14, 0xdf, 0xd8, 0xee, 0x72, 0xb6, 0x0b, 0xe0, 0xae, 0xf4, 0xa5, 0x76,
|
0xa1, 0x3f, 0x16, 0x75, 0xce, 0x9d, 0x25, 0x76, 0xa9, 0xaf, 0xa0, 0xf8, 0xc6, 0x76, 0x97, 0xb3,
|
||||||
0x9b, 0xa9, 0x2b, 0x6d, 0x7e, 0x5d, 0xa5, 0xde, 0xa9, 0xae, 0x36, 0xa4, 0xe6, 0x2d, 0x64, 0xdf,
|
0x5d, 0x00, 0x77, 0xa5, 0x2f, 0xb5, 0xdb, 0x4c, 0xf1, 0x69, 0xf3, 0x8b, 0x2f, 0xf5, 0x4e, 0xed,
|
||||||
0xa6, 0x54, 0xb3, 0x09, 0xfd, 0x3e, 0xe4, 0x5c, 0xb6, 0x99, 0x3c, 0x56, 0xd2, 0xc5, 0x48, 0x88,
|
0x68, 0x43, 0x0a, 0xe3, 0x42, 0xf6, 0x6d, 0x4a, 0xc9, 0x9b, 0xd0, 0xef, 0x43, 0xce, 0x65, 0x9b,
|
||||||
0x59, 0x87, 0x95, 0x1d, 0xe2, 0x79, 0xb8, 0xbb, 0x28, 0x4f, 0xa6, 0x0d, 0xf7, 0xae, 0x90, 0x6a,
|
0xc9, 0x63, 0x25, 0x5d, 0x8c, 0x84, 0x98, 0x75, 0x58, 0xd9, 0x21, 0x9e, 0x87, 0xbb, 0x8b, 0xf2,
|
||||||
0xa3, 0x87, 0x90, 0xe7, 0xaf, 0xcc, 0xce, 0x24, 0xf1, 0x39, 0x6e, 0x1f, 0xb8, 0x0e, 0x9f, 0xe2,
|
0x64, 0xda, 0x70, 0xef, 0x0a, 0xa9, 0x36, 0x7a, 0x08, 0x79, 0xfe, 0x14, 0xed, 0x4c, 0x12, 0x9f,
|
||||||
0x2f, 0x31, 0x31, 0x25, 0xfb, 0x70, 0x8e, 0xdb, 0x7c, 0xca, 0x80, 0xdc, 0x09, 0x0e, 0xa8, 0x4b,
|
0xe3, 0xf6, 0x81, 0xeb, 0xf0, 0x29, 0xfe, 0x5c, 0x13, 0x53, 0xb2, 0x59, 0xe7, 0xb8, 0xcd, 0xa7,
|
||||||
0x64, 0xb1, 0x15, 0xac, 0xb1, 0x69, 0x6e, 0xc2, 0xbd, 0x57, 0xfd, 0x90, 0x39, 0xe4, 0xd4, 0x5b,
|
0x0c, 0xc8, 0x9d, 0xe0, 0x80, 0xba, 0x44, 0x16, 0x5b, 0xc1, 0x1a, 0x9b, 0xe6, 0x26, 0xdc, 0x7b,
|
||||||
0x74, 0x6b, 0xab, 0x90, 0xf6, 0xc8, 0xa9, 0x70, 0x9d, 0xb7, 0xf8, 0x90, 0xa7, 0xeb, 0xc0, 0x0e,
|
0xd5, 0x0f, 0x99, 0x43, 0x4e, 0xbd, 0x45, 0xb7, 0xb6, 0x0a, 0x69, 0x8f, 0x9c, 0x0a, 0xd7, 0x79,
|
||||||
0xe9, 0xa2, 0x16, 0x61, 0xbe, 0x0f, 0x25, 0x0b, 0xd3, 0x70, 0xb8, 0x08, 0xd8, 0xfa, 0x15, 0x20,
|
0x8b, 0x0f, 0x79, 0xba, 0x0e, 0xec, 0x90, 0x2e, 0xea, 0x23, 0xe6, 0xfb, 0x50, 0xb2, 0x30, 0x0d,
|
||||||
0xc3, 0x6b, 0x01, 0xbd, 0x84, 0xac, 0x68, 0x17, 0x68, 0xaa, 0x88, 0xd5, 0x43, 0xba, 0x11, 0xed,
|
0x87, 0x8b, 0x80, 0xad, 0x5f, 0x01, 0x32, 0xbc, 0x16, 0xd0, 0x4b, 0xc8, 0x8a, 0x9e, 0x82, 0xa6,
|
||||||
0x4b, 0xe5, 0xc7, 0x73, 0x10, 0x2a, 0x69, 0x6f, 0x40, 0x97, 0xef, 0x27, 0xf4, 0x34, 0x0e, 0x7c,
|
0x8a, 0x58, 0xbd, 0xb6, 0x1b, 0xd1, 0xe6, 0x55, 0x7e, 0x3c, 0x07, 0xa1, 0x92, 0xf6, 0x06, 0x74,
|
||||||
0xed, 0xc1, 0x5a, 0xde, 0x58, 0x04, 0x53, 0x8e, 0xe5, 0x31, 0x03, 0x96, 0x78, 0xcc, 0xab, 0xd2,
|
0xf9, 0xc8, 0x42, 0x4f, 0xe3, 0xc0, 0xd7, 0x5e, 0xb5, 0xe5, 0x8d, 0x45, 0x30, 0xe5, 0x58, 0x1e,
|
||||||
0x4b, 0x3c, 0x66, 0xa4, 0x9e, 0xf6, 0x41, 0x97, 0xef, 0x2d, 0x14, 0x0b, 0x9e, 0x7a, 0xda, 0x95,
|
0x33, 0x60, 0x89, 0xc7, 0xbc, 0x2a, 0xbd, 0xc4, 0x63, 0x46, 0xea, 0x69, 0x1f, 0x74, 0xf9, 0x28,
|
||||||
0xcd, 0x79, 0x10, 0xe5, 0xb0, 0x0d, 0x19, 0x2e, 0x92, 0xa8, 0x1a, 0x87, 0x8d, 0xa8, 0x6c, 0xb9,
|
0x43, 0xb1, 0xe0, 0xa9, 0xf7, 0x5f, 0xd9, 0x9c, 0x07, 0x51, 0x0e, 0xdb, 0x90, 0xe1, 0x22, 0x89,
|
||||||
0x96, 0x0c, 0x50, 0xae, 0xb6, 0x20, 0x2b, 0xae, 0x3a, 0x3e, 0xd2, 0x28, 0x0b, 0xca, 0xeb, 0xd7,
|
0xaa, 0x71, 0xd8, 0x88, 0xca, 0x96, 0x6b, 0xc9, 0x00, 0xe5, 0x6a, 0x0b, 0xb2, 0xe2, 0xaa, 0xe3,
|
||||||
0xc8, 0xbf, 0xc7, 0xff, 0x99, 0x41, 0x3b, 0xa0, 0x4b, 0x16, 0xc4, 0x87, 0x37, 0xc5, 0x90, 0x44,
|
0x23, 0x8d, 0xb2, 0xa0, 0xbc, 0x7e, 0x8d, 0xfc, 0x7b, 0xfc, 0x3f, 0x1e, 0xb4, 0x03, 0xba, 0x64,
|
||||||
0x27, 0xfb, 0x00, 0x91, 0x87, 0xf4, 0x07, 0xb1, 0xf7, 0x14, 0xa7, 0xe3, 0x89, 0x0e, 0xbf, 0x80,
|
0x41, 0x7c, 0x78, 0x53, 0x0c, 0x49, 0x74, 0xb2, 0x0f, 0x10, 0x79, 0x6d, 0x7f, 0x10, 0x7b, 0x4f,
|
||||||
0x0c, 0x6f, 0xa5, 0xf1, 0x39, 0x8a, 0x34, 0xd9, 0x44, 0x07, 0x5f, 0x42, 0x86, 0x2b, 0x17, 0x8a,
|
0x71, 0x3a, 0x9e, 0xe8, 0xf0, 0x0b, 0xc8, 0xf0, 0x56, 0x1a, 0x9f, 0xa3, 0x48, 0x93, 0x4d, 0x74,
|
||||||
0xe5, 0xcc, 0xf5, 0x67, 0x6b, 0xa2, 0x9f, 0x36, 0x14, 0xae, 0x9e, 0x7b, 0xe8, 0xbd, 0x84, 0x0c,
|
0xf0, 0x25, 0x64, 0xb8, 0x72, 0xa1, 0x58, 0xce, 0x5c, 0x7f, 0xdb, 0x26, 0xfa, 0x69, 0x43, 0xe1,
|
||||||
0x4d, 0xbd, 0x06, 0x13, 0x5d, 0xed, 0x41, 0x4e, 0x35, 0x6a, 0x14, 0x4b, 0x93, 0xe9, 0x2e, 0x9e,
|
0xea, 0x4d, 0x88, 0xde, 0x4b, 0xc8, 0xd0, 0xd4, 0x93, 0x31, 0xd1, 0xd5, 0x1e, 0xe4, 0x54, 0xa3,
|
||||||
0xe8, 0xe6, 0x39, 0xe8, 0xb2, 0x3d, 0xc5, 0x97, 0xcd, 0xb5, 0xd6, 0x35, 0x27, 0xb4, 0x0c, 0x97,
|
0x46, 0xb1, 0x34, 0x99, 0xee, 0xe2, 0x89, 0x6e, 0x9e, 0x83, 0x2e, 0xdb, 0x53, 0x7c, 0xd9, 0x5c,
|
||||||
0xf2, 0xf8, 0x1c, 0x47, 0x1a, 0x46, 0x3c, 0x0f, 0xa7, 0xba, 0x80, 0x12, 0x06, 0x9a, 0x2c, 0x0c,
|
0x6b, 0x5d, 0x73, 0x42, 0xcb, 0x70, 0x29, 0x8f, 0xcf, 0x71, 0xa4, 0x61, 0xc4, 0xf3, 0x70, 0xaa,
|
||||||
0x74, 0xa1, 0x30, 0x4c, 0x58, 0x6d, 0x41, 0x4e, 0x09, 0x6c, 0x42, 0xa2, 0xa6, 0x74, 0xba, 0xfc,
|
0x0b, 0x28, 0x61, 0xa0, 0xc9, 0xc2, 0x40, 0x17, 0x0a, 0xc3, 0x84, 0xd5, 0x16, 0xe4, 0x94, 0xc0,
|
||||||
0x64, 0x2e, 0x46, 0xf9, 0x7c, 0x0e, 0xf9, 0xb1, 0xa2, 0xa2, 0xd8, 0x05, 0x33, 0x7a, 0x9b, 0x94,
|
0x26, 0x24, 0x6a, 0x4a, 0xa7, 0xcb, 0x4f, 0xe6, 0x62, 0x94, 0xcf, 0xe7, 0x90, 0x1f, 0x2b, 0x2a,
|
||||||
0xb5, 0xed, 0xfd, 0x8b, 0xb7, 0x95, 0x3b, 0x7f, 0xbd, 0xad, 0xdc, 0xf9, 0x79, 0x54, 0xd1, 0x2e,
|
0x8a, 0x5d, 0x30, 0xa3, 0xb7, 0x49, 0x59, 0xdb, 0xde, 0xbf, 0x78, 0x5b, 0xb9, 0xf3, 0xe7, 0xdb,
|
||||||
0x46, 0x15, 0xed, 0x8f, 0x51, 0x45, 0xfb, 0x77, 0x54, 0xd1, 0xbe, 0xff, 0xe4, 0xb6, 0xbf, 0x4c,
|
0xca, 0x9d, 0x9f, 0x47, 0x15, 0xed, 0x62, 0x54, 0xd1, 0x7e, 0x1f, 0x55, 0xb4, 0x7f, 0x46, 0x15,
|
||||||
0x6c, 0xf2, 0x3f, 0xdf, 0xa5, 0x0e, 0x75, 0xb1, 0xc5, 0xb3, 0xff, 0x02, 0x00, 0x00, 0xff, 0xff,
|
0xed, 0xfb, 0x4f, 0x6e, 0xfb, 0xf3, 0xc5, 0x26, 0xff, 0xf3, 0x5d, 0xea, 0x50, 0x17, 0x5b, 0x3c,
|
||||||
0x11, 0x4c, 0x17, 0x02, 0xdb, 0x10, 0x00, 0x00,
|
0xfb, 0x2f, 0x00, 0x00, 0xff, 0xff, 0x19, 0x17, 0x87, 0x57, 0x00, 0x11, 0x00, 0x00,
|
||||||
}
|
}
|
||||||
|
1
vendor/github.com/containerd/containerd/runtime/v2/task/shim.proto
generated
vendored
1
vendor/github.com/containerd/containerd/runtime/v2/task/shim.proto
generated
vendored
@ -99,6 +99,7 @@ message StateResponse {
|
|||||||
bool terminal = 8;
|
bool terminal = 8;
|
||||||
uint32 exit_status = 9;
|
uint32 exit_status = 9;
|
||||||
google.protobuf.Timestamp exited_at = 10 [(gogoproto.stdtime) = true, (gogoproto.nullable) = false];
|
google.protobuf.Timestamp exited_at = 10 [(gogoproto.stdtime) = true, (gogoproto.nullable) = false];
|
||||||
|
string exec_id = 11;
|
||||||
}
|
}
|
||||||
|
|
||||||
message KillRequest {
|
message KillRequest {
|
||||||
|
31
vendor/github.com/containerd/containerd/services/tasks/local.go
generated
vendored
31
vendor/github.com/containerd/containerd/services/tasks/local.go
generated
vendored
@ -24,6 +24,7 @@ import (
|
|||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
api "github.com/containerd/containerd/api/services/tasks/v1"
|
api "github.com/containerd/containerd/api/services/tasks/v1"
|
||||||
@ -687,8 +688,8 @@ func getCheckpointPath(runtime string, option *ptypes.Any) (string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var checkpointPath string
|
var checkpointPath string
|
||||||
switch runtime {
|
switch {
|
||||||
case "io.containerd.runc.v1":
|
case checkRuntime(runtime, "io.containerd.runc"):
|
||||||
v, err := typeurl.UnmarshalAny(option)
|
v, err := typeurl.UnmarshalAny(option)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
@ -699,7 +700,7 @@ func getCheckpointPath(runtime string, option *ptypes.Any) (string, error) {
|
|||||||
}
|
}
|
||||||
checkpointPath = opts.ImagePath
|
checkpointPath = opts.ImagePath
|
||||||
|
|
||||||
case "io.containerd.runtime.v1.linux":
|
case runtime == plugin.RuntimeLinuxV1:
|
||||||
v, err := typeurl.UnmarshalAny(option)
|
v, err := typeurl.UnmarshalAny(option)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
@ -721,8 +722,8 @@ func getRestorePath(runtime string, option *ptypes.Any) (string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var restorePath string
|
var restorePath string
|
||||||
switch runtime {
|
switch {
|
||||||
case "io.containerd.runc.v1":
|
case checkRuntime(runtime, "io.containerd.runc"):
|
||||||
v, err := typeurl.UnmarshalAny(option)
|
v, err := typeurl.UnmarshalAny(option)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
@ -732,8 +733,7 @@ func getRestorePath(runtime string, option *ptypes.Any) (string, error) {
|
|||||||
return "", fmt.Errorf("invalid task create option for %s", runtime)
|
return "", fmt.Errorf("invalid task create option for %s", runtime)
|
||||||
}
|
}
|
||||||
restorePath = opts.CriuImagePath
|
restorePath = opts.CriuImagePath
|
||||||
|
case runtime == plugin.RuntimeLinuxV1:
|
||||||
case "io.containerd.runtime.v1.linux":
|
|
||||||
v, err := typeurl.UnmarshalAny(option)
|
v, err := typeurl.UnmarshalAny(option)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
@ -747,3 +747,20 @@ func getRestorePath(runtime string, option *ptypes.Any) (string, error) {
|
|||||||
|
|
||||||
return restorePath, nil
|
return restorePath, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// checkRuntime returns true if the current runtime matches the expected
|
||||||
|
// runtime. Providing various parts of the runtime schema will match those
|
||||||
|
// parts of the expected runtime
|
||||||
|
func checkRuntime(current, expected string) bool {
|
||||||
|
cp := strings.Split(current, ".")
|
||||||
|
l := len(cp)
|
||||||
|
for i, p := range strings.Split(expected, ".") {
|
||||||
|
if i > l {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if p != cp[i] {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
60
vendor/github.com/containerd/containerd/signal_map_linux.go
generated
vendored
60
vendor/github.com/containerd/containerd/signal_map_linux.go
generated
vendored
@ -1,60 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright The containerd Authors.
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package containerd
|
|
||||||
|
|
||||||
import (
|
|
||||||
"syscall"
|
|
||||||
|
|
||||||
"golang.org/x/sys/unix"
|
|
||||||
)
|
|
||||||
|
|
||||||
var signalMap = map[string]syscall.Signal{
|
|
||||||
"ABRT": unix.SIGABRT,
|
|
||||||
"ALRM": unix.SIGALRM,
|
|
||||||
"BUS": unix.SIGBUS,
|
|
||||||
"CHLD": unix.SIGCHLD,
|
|
||||||
"CLD": unix.SIGCLD,
|
|
||||||
"CONT": unix.SIGCONT,
|
|
||||||
"FPE": unix.SIGFPE,
|
|
||||||
"HUP": unix.SIGHUP,
|
|
||||||
"ILL": unix.SIGILL,
|
|
||||||
"INT": unix.SIGINT,
|
|
||||||
"IO": unix.SIGIO,
|
|
||||||
"IOT": unix.SIGIOT,
|
|
||||||
"KILL": unix.SIGKILL,
|
|
||||||
"PIPE": unix.SIGPIPE,
|
|
||||||
"POLL": unix.SIGPOLL,
|
|
||||||
"PROF": unix.SIGPROF,
|
|
||||||
"PWR": unix.SIGPWR,
|
|
||||||
"QUIT": unix.SIGQUIT,
|
|
||||||
"SEGV": unix.SIGSEGV,
|
|
||||||
"STKFLT": unix.SIGSTKFLT,
|
|
||||||
"STOP": unix.SIGSTOP,
|
|
||||||
"SYS": unix.SIGSYS,
|
|
||||||
"TERM": unix.SIGTERM,
|
|
||||||
"TRAP": unix.SIGTRAP,
|
|
||||||
"TSTP": unix.SIGTSTP,
|
|
||||||
"TTIN": unix.SIGTTIN,
|
|
||||||
"TTOU": unix.SIGTTOU,
|
|
||||||
"URG": unix.SIGURG,
|
|
||||||
"USR1": unix.SIGUSR1,
|
|
||||||
"USR2": unix.SIGUSR2,
|
|
||||||
"VTALRM": unix.SIGVTALRM,
|
|
||||||
"WINCH": unix.SIGWINCH,
|
|
||||||
"XCPU": unix.SIGXCPU,
|
|
||||||
"XFSZ": unix.SIGXFSZ,
|
|
||||||
}
|
|
58
vendor/github.com/containerd/containerd/signal_map_unix.go
generated
vendored
58
vendor/github.com/containerd/containerd/signal_map_unix.go
generated
vendored
@ -1,58 +0,0 @@
|
|||||||
// +build darwin freebsd solaris
|
|
||||||
|
|
||||||
/*
|
|
||||||
Copyright The containerd Authors.
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package containerd
|
|
||||||
|
|
||||||
import (
|
|
||||||
"syscall"
|
|
||||||
|
|
||||||
"golang.org/x/sys/unix"
|
|
||||||
)
|
|
||||||
|
|
||||||
var signalMap = map[string]syscall.Signal{
|
|
||||||
"ABRT": unix.SIGABRT,
|
|
||||||
"ALRM": unix.SIGALRM,
|
|
||||||
"BUS": unix.SIGBUS,
|
|
||||||
"CHLD": unix.SIGCHLD,
|
|
||||||
"CONT": unix.SIGCONT,
|
|
||||||
"FPE": unix.SIGFPE,
|
|
||||||
"HUP": unix.SIGHUP,
|
|
||||||
"ILL": unix.SIGILL,
|
|
||||||
"INT": unix.SIGINT,
|
|
||||||
"IO": unix.SIGIO,
|
|
||||||
"IOT": unix.SIGIOT,
|
|
||||||
"KILL": unix.SIGKILL,
|
|
||||||
"PIPE": unix.SIGPIPE,
|
|
||||||
"PROF": unix.SIGPROF,
|
|
||||||
"QUIT": unix.SIGQUIT,
|
|
||||||
"SEGV": unix.SIGSEGV,
|
|
||||||
"STOP": unix.SIGSTOP,
|
|
||||||
"SYS": unix.SIGSYS,
|
|
||||||
"TERM": unix.SIGTERM,
|
|
||||||
"TRAP": unix.SIGTRAP,
|
|
||||||
"TSTP": unix.SIGTSTP,
|
|
||||||
"TTIN": unix.SIGTTIN,
|
|
||||||
"TTOU": unix.SIGTTOU,
|
|
||||||
"URG": unix.SIGURG,
|
|
||||||
"USR1": unix.SIGUSR1,
|
|
||||||
"USR2": unix.SIGUSR2,
|
|
||||||
"VTALRM": unix.SIGVTALRM,
|
|
||||||
"WINCH": unix.SIGWINCH,
|
|
||||||
"XCPU": unix.SIGXCPU,
|
|
||||||
"XFSZ": unix.SIGXFSZ,
|
|
||||||
}
|
|
24
vendor/github.com/containerd/containerd/signals.go
generated
vendored
24
vendor/github.com/containerd/containerd/signals.go
generated
vendored
@ -20,13 +20,11 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
"github.com/containerd/containerd/content"
|
"github.com/containerd/containerd/content"
|
||||||
"github.com/containerd/containerd/images"
|
"github.com/containerd/containerd/images"
|
||||||
"github.com/opencontainers/image-spec/specs-go/v1"
|
v1 "github.com/opencontainers/image-spec/specs-go/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
// StopSignalLabel is a well-known containerd label for storing the stop
|
// StopSignalLabel is a well-known containerd label for storing the stop
|
||||||
@ -83,23 +81,3 @@ func GetOCIStopSignal(ctx context.Context, image Image, defaultSignal string) (s
|
|||||||
|
|
||||||
return config.StopSignal, nil
|
return config.StopSignal, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ParseSignal parses a given string into a syscall.Signal
|
|
||||||
// it checks that the signal exists in the platform-appropriate signalMap
|
|
||||||
func ParseSignal(rawSignal string) (syscall.Signal, error) {
|
|
||||||
s, err := strconv.Atoi(rawSignal)
|
|
||||||
if err == nil {
|
|
||||||
sig := syscall.Signal(s)
|
|
||||||
for _, msig := range signalMap {
|
|
||||||
if sig == msig {
|
|
||||||
return sig, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -1, fmt.Errorf("unknown signal %q", rawSignal)
|
|
||||||
}
|
|
||||||
signal, ok := signalMap[strings.TrimPrefix(strings.ToUpper(rawSignal), "SIG")]
|
|
||||||
if !ok {
|
|
||||||
return -1, fmt.Errorf("unknown signal %q", rawSignal)
|
|
||||||
}
|
|
||||||
return signal, nil
|
|
||||||
}
|
|
||||||
|
47
vendor/github.com/containerd/containerd/signals_unix.go
generated
vendored
Normal file
47
vendor/github.com/containerd/containerd/signals_unix.go
generated
vendored
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
|
||||||
|
|
||||||
|
/*
|
||||||
|
Copyright The containerd Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package containerd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"syscall"
|
||||||
|
|
||||||
|
"golang.org/x/sys/unix"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ParseSignal parses a given string into a syscall.Signal
|
||||||
|
// the rawSignal can be a string with "SIG" prefix,
|
||||||
|
// or a signal number in string format.
|
||||||
|
func ParseSignal(rawSignal string) (syscall.Signal, error) {
|
||||||
|
s, err := strconv.Atoi(rawSignal)
|
||||||
|
if err == nil {
|
||||||
|
signal := syscall.Signal(s)
|
||||||
|
if unix.SignalName(signal) != "" {
|
||||||
|
return signal, nil
|
||||||
|
}
|
||||||
|
return -1, fmt.Errorf("unknown signal %q", rawSignal)
|
||||||
|
}
|
||||||
|
signal := unix.SignalNum(strings.ToUpper(rawSignal))
|
||||||
|
if signal == 0 {
|
||||||
|
return -1, fmt.Errorf("unknown signal %q", rawSignal)
|
||||||
|
}
|
||||||
|
return signal, nil
|
||||||
|
}
|
@ -17,6 +17,9 @@
|
|||||||
package containerd
|
package containerd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
"golang.org/x/sys/windows"
|
"golang.org/x/sys/windows"
|
||||||
@ -37,3 +40,24 @@ var signalMap = map[string]syscall.Signal{
|
|||||||
"ALRM": syscall.Signal(windows.SIGALRM),
|
"ALRM": syscall.Signal(windows.SIGALRM),
|
||||||
"TERM": syscall.Signal(windows.SIGTERM),
|
"TERM": syscall.Signal(windows.SIGTERM),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ParseSignal parses a given string into a syscall.Signal
|
||||||
|
// the rawSignal can be a string with "SIG" prefix,
|
||||||
|
// or a signal number in string format.
|
||||||
|
func ParseSignal(rawSignal string) (syscall.Signal, error) {
|
||||||
|
s, err := strconv.Atoi(rawSignal)
|
||||||
|
if err == nil {
|
||||||
|
sig := syscall.Signal(s)
|
||||||
|
for _, msig := range signalMap {
|
||||||
|
if sig == msig {
|
||||||
|
return sig, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1, fmt.Errorf("unknown signal %q", rawSignal)
|
||||||
|
}
|
||||||
|
signal, ok := signalMap[strings.TrimPrefix(strings.ToUpper(rawSignal), "SIG")]
|
||||||
|
if !ok {
|
||||||
|
return -1, fmt.Errorf("unknown signal %q", rawSignal)
|
||||||
|
}
|
||||||
|
return signal, nil
|
||||||
|
}
|
2
vendor/github.com/containerd/containerd/snapshots/snapshotter.go
generated
vendored
2
vendor/github.com/containerd/containerd/snapshots/snapshotter.go
generated
vendored
@ -163,7 +163,7 @@ func (u *Usage) Add(other Usage) {
|
|||||||
// key and descending from the empty parent "". To prevent our layer from being
|
// key and descending from the empty parent "". To prevent our layer from being
|
||||||
// garbage collected during unpacking, we add the `containerd.io/gc.root` label:
|
// garbage collected during unpacking, we add the `containerd.io/gc.root` label:
|
||||||
//
|
//
|
||||||
// noGcOpt := snapshotter.WithLabels(map[string]string{
|
// noGcOpt := snapshots.WithLabels(map[string]string{
|
||||||
// "containerd.io/gc.root": time.Now().UTC().Format(time.RFC3339),
|
// "containerd.io/gc.root": time.Now().UTC().Format(time.RFC3339),
|
||||||
// })
|
// })
|
||||||
// mounts, err := snapshotter.Prepare(ctx, key, "", noGcOpt)
|
// mounts, err := snapshotter.Prepare(ctx, key, "", noGcOpt)
|
||||||
|
31
vendor/github.com/containerd/containerd/task.go
generated
vendored
31
vendor/github.com/containerd/containerd/task.go
generated
vendored
@ -43,7 +43,7 @@ import (
|
|||||||
google_protobuf "github.com/gogo/protobuf/types"
|
google_protobuf "github.com/gogo/protobuf/types"
|
||||||
digest "github.com/opencontainers/go-digest"
|
digest "github.com/opencontainers/go-digest"
|
||||||
is "github.com/opencontainers/image-spec/specs-go"
|
is "github.com/opencontainers/image-spec/specs-go"
|
||||||
"github.com/opencontainers/image-spec/specs-go/v1"
|
v1 "github.com/opencontainers/image-spec/specs-go/v1"
|
||||||
specs "github.com/opencontainers/runtime-spec/specs-go"
|
specs "github.com/opencontainers/runtime-spec/specs-go"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
@ -117,6 +117,13 @@ type CheckpointTaskInfo struct {
|
|||||||
ParentCheckpoint digest.Digest
|
ParentCheckpoint digest.Digest
|
||||||
// Options hold runtime specific settings for checkpointing a task
|
// Options hold runtime specific settings for checkpointing a task
|
||||||
Options interface{}
|
Options interface{}
|
||||||
|
|
||||||
|
runtime string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Runtime name for the container
|
||||||
|
func (i *CheckpointTaskInfo) Runtime() string {
|
||||||
|
return i.runtime
|
||||||
}
|
}
|
||||||
|
|
||||||
// CheckpointTaskOpts allows the caller to set checkpoint options
|
// CheckpointTaskOpts allows the caller to set checkpoint options
|
||||||
@ -131,6 +138,12 @@ type TaskInfo struct {
|
|||||||
RootFS []mount.Mount
|
RootFS []mount.Mount
|
||||||
// Options hold runtime specific settings for task creation
|
// Options hold runtime specific settings for task creation
|
||||||
Options interface{}
|
Options interface{}
|
||||||
|
runtime string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Runtime name for the container
|
||||||
|
func (i *TaskInfo) Runtime() string {
|
||||||
|
return i.runtime
|
||||||
}
|
}
|
||||||
|
|
||||||
// Task is the executable object within containerd
|
// Task is the executable object within containerd
|
||||||
@ -401,11 +414,17 @@ func (t *task) Checkpoint(ctx context.Context, opts ...CheckpointTaskOpts) (Imag
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
defer done(ctx)
|
defer done(ctx)
|
||||||
|
cr, err := t.client.ContainerService().Get(ctx, t.id)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
request := &tasks.CheckpointTaskRequest{
|
request := &tasks.CheckpointTaskRequest{
|
||||||
ContainerID: t.id,
|
ContainerID: t.id,
|
||||||
}
|
}
|
||||||
var i CheckpointTaskInfo
|
i := CheckpointTaskInfo{
|
||||||
|
runtime: cr.Runtime.Name,
|
||||||
|
}
|
||||||
for _, o := range opts {
|
for _, o := range opts {
|
||||||
if err := o(&i); err != nil {
|
if err := o(&i); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -428,10 +447,6 @@ func (t *task) Checkpoint(ctx context.Context, opts ...CheckpointTaskOpts) (Imag
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
defer t.Resume(ctx)
|
defer t.Resume(ctx)
|
||||||
cr, err := t.client.ContainerService().Get(ctx, t.id)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
index := v1.Index{
|
index := v1.Index{
|
||||||
Versioned: is.Versioned{
|
Versioned: is.Versioned{
|
||||||
SchemaVersion: 2,
|
SchemaVersion: 2,
|
||||||
@ -642,12 +657,12 @@ func isCheckpointPathExist(runtime string, v interface{}) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch runtime {
|
switch runtime {
|
||||||
case "io.containerd.runc.v1":
|
case plugin.RuntimeRuncV1, plugin.RuntimeRuncV2:
|
||||||
if opts, ok := v.(*options.CheckpointOptions); ok && opts.ImagePath != "" {
|
if opts, ok := v.(*options.CheckpointOptions); ok && opts.ImagePath != "" {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
case "io.containerd.runtime.v1.linux":
|
case plugin.RuntimeLinuxV1:
|
||||||
if opts, ok := v.(*runctypes.CheckpointOptions); ok && opts.ImagePath != "" {
|
if opts, ok := v.(*runctypes.CheckpointOptions); ok && opts.ImagePath != "" {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
55
vendor/github.com/containerd/containerd/task_opts.go
generated
vendored
55
vendor/github.com/containerd/containerd/task_opts.go
generated
vendored
@ -34,11 +34,6 @@ import (
|
|||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
|
||||||
v1runtime = "io.containerd.runtime.v1.linux"
|
|
||||||
v2runtime = "io.containerd.runc.v1"
|
|
||||||
)
|
|
||||||
|
|
||||||
// NewTaskOpts allows the caller to set options on a new task
|
// NewTaskOpts allows the caller to set options on a new task
|
||||||
type NewTaskOpts func(context.Context, *Client, *TaskInfo) error
|
type NewTaskOpts func(context.Context, *Client, *TaskInfo) error
|
||||||
|
|
||||||
@ -97,25 +92,24 @@ func WithCheckpointName(name string) CheckpointTaskOpts {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// WithCheckpointImagePath sets image path for checkpoint option
|
// WithCheckpointImagePath sets image path for checkpoint option
|
||||||
func WithCheckpointImagePath(rt, path string) CheckpointTaskOpts {
|
func WithCheckpointImagePath(path string) CheckpointTaskOpts {
|
||||||
return func(r *CheckpointTaskInfo) error {
|
return func(r *CheckpointTaskInfo) error {
|
||||||
switch rt {
|
if CheckRuntime(r.Runtime(), "io.containerd.runc") {
|
||||||
case v1runtime:
|
|
||||||
if r.Options == nil {
|
|
||||||
r.Options = &runctypes.CheckpointOptions{}
|
|
||||||
}
|
|
||||||
opts, ok := r.Options.(*runctypes.CheckpointOptions)
|
|
||||||
if !ok {
|
|
||||||
return errors.New("invalid v1 checkpoint options format")
|
|
||||||
}
|
|
||||||
opts.ImagePath = path
|
|
||||||
case v2runtime:
|
|
||||||
if r.Options == nil {
|
if r.Options == nil {
|
||||||
r.Options = &options.CheckpointOptions{}
|
r.Options = &options.CheckpointOptions{}
|
||||||
}
|
}
|
||||||
opts, ok := r.Options.(*options.CheckpointOptions)
|
opts, ok := r.Options.(*options.CheckpointOptions)
|
||||||
if !ok {
|
if !ok {
|
||||||
return errors.New("invalid v2 checkpoint options format")
|
return errors.New("invalid v2 shim checkpoint options format")
|
||||||
|
}
|
||||||
|
opts.ImagePath = path
|
||||||
|
} else {
|
||||||
|
if r.Options == nil {
|
||||||
|
r.Options = &runctypes.CheckpointOptions{}
|
||||||
|
}
|
||||||
|
opts, ok := r.Options.(*runctypes.CheckpointOptions)
|
||||||
|
if !ok {
|
||||||
|
return errors.New("invalid v1 shim checkpoint options format")
|
||||||
}
|
}
|
||||||
opts.ImagePath = path
|
opts.ImagePath = path
|
||||||
}
|
}
|
||||||
@ -124,25 +118,24 @@ func WithCheckpointImagePath(rt, path string) CheckpointTaskOpts {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// WithRestoreImagePath sets image path for create option
|
// WithRestoreImagePath sets image path for create option
|
||||||
func WithRestoreImagePath(rt, path string) NewTaskOpts {
|
func WithRestoreImagePath(path string) NewTaskOpts {
|
||||||
return func(ctx context.Context, c *Client, ti *TaskInfo) error {
|
return func(ctx context.Context, c *Client, ti *TaskInfo) error {
|
||||||
switch rt {
|
if CheckRuntime(ti.Runtime(), "io.containerd.runc") {
|
||||||
case v1runtime:
|
|
||||||
if ti.Options == nil {
|
|
||||||
ti.Options = &runctypes.CreateOptions{}
|
|
||||||
}
|
|
||||||
opts, ok := ti.Options.(*runctypes.CreateOptions)
|
|
||||||
if !ok {
|
|
||||||
return errors.New("invalid v1 create options format")
|
|
||||||
}
|
|
||||||
opts.CriuImagePath = path
|
|
||||||
case v2runtime:
|
|
||||||
if ti.Options == nil {
|
if ti.Options == nil {
|
||||||
ti.Options = &options.Options{}
|
ti.Options = &options.Options{}
|
||||||
}
|
}
|
||||||
opts, ok := ti.Options.(*options.Options)
|
opts, ok := ti.Options.(*options.Options)
|
||||||
if !ok {
|
if !ok {
|
||||||
return errors.New("invalid v2 create options format")
|
return errors.New("invalid v2 shim create options format")
|
||||||
|
}
|
||||||
|
opts.CriuImagePath = path
|
||||||
|
} else {
|
||||||
|
if ti.Options == nil {
|
||||||
|
ti.Options = &runctypes.CreateOptions{}
|
||||||
|
}
|
||||||
|
opts, ok := ti.Options.(*runctypes.CreateOptions)
|
||||||
|
if !ok {
|
||||||
|
return errors.New("invalid v1 shim create options format")
|
||||||
}
|
}
|
||||||
opts.CriuImagePath = path
|
opts.CriuImagePath = path
|
||||||
}
|
}
|
||||||
|
58
vendor/github.com/containerd/containerd/task_opts_unix.go
generated
vendored
58
vendor/github.com/containerd/containerd/task_opts_unix.go
generated
vendored
@ -22,36 +22,58 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/containerd/containerd/runtime/linux/runctypes"
|
"github.com/containerd/containerd/runtime/linux/runctypes"
|
||||||
|
"github.com/containerd/containerd/runtime/v2/runc/options"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
// WithNoNewKeyring causes tasks not to be created with a new keyring for secret storage.
|
// WithNoNewKeyring causes tasks not to be created with a new keyring for secret storage.
|
||||||
// There is an upper limit on the number of keyrings in a linux system
|
// There is an upper limit on the number of keyrings in a linux system
|
||||||
func WithNoNewKeyring(ctx context.Context, c *Client, ti *TaskInfo) error {
|
func WithNoNewKeyring(ctx context.Context, c *Client, ti *TaskInfo) error {
|
||||||
if ti.Options == nil {
|
if CheckRuntime(ti.Runtime(), "io.containerd.runc") {
|
||||||
ti.Options = &runctypes.CreateOptions{}
|
if ti.Options == nil {
|
||||||
|
ti.Options = &options.Options{}
|
||||||
|
}
|
||||||
|
opts, ok := ti.Options.(*options.Options)
|
||||||
|
if !ok {
|
||||||
|
return errors.New("invalid v2 shim create options format")
|
||||||
|
}
|
||||||
|
opts.NoNewKeyring = true
|
||||||
|
} else {
|
||||||
|
if ti.Options == nil {
|
||||||
|
ti.Options = &runctypes.CreateOptions{}
|
||||||
|
}
|
||||||
|
opts, ok := ti.Options.(*runctypes.CreateOptions)
|
||||||
|
if !ok {
|
||||||
|
return errors.New("could not cast TaskInfo Options to CreateOptions")
|
||||||
|
}
|
||||||
|
opts.NoNewKeyring = true
|
||||||
}
|
}
|
||||||
opts, ok := ti.Options.(*runctypes.CreateOptions)
|
|
||||||
if !ok {
|
|
||||||
return errors.New("could not cast TaskInfo Options to CreateOptions")
|
|
||||||
}
|
|
||||||
|
|
||||||
opts.NoNewKeyring = true
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithNoPivotRoot instructs the runtime not to you pivot_root
|
// WithNoPivotRoot instructs the runtime not to you pivot_root
|
||||||
func WithNoPivotRoot(_ context.Context, _ *Client, info *TaskInfo) error {
|
func WithNoPivotRoot(_ context.Context, _ *Client, ti *TaskInfo) error {
|
||||||
if info.Options == nil {
|
if CheckRuntime(ti.Runtime(), "io.containerd.runc") {
|
||||||
info.Options = &runctypes.CreateOptions{
|
if ti.Options == nil {
|
||||||
NoPivotRoot: true,
|
ti.Options = &options.Options{}
|
||||||
}
|
}
|
||||||
return nil
|
opts, ok := ti.Options.(*options.Options)
|
||||||
|
if !ok {
|
||||||
|
return errors.New("invalid v2 shim create options format")
|
||||||
|
}
|
||||||
|
opts.NoPivotRoot = true
|
||||||
|
} else {
|
||||||
|
if ti.Options == nil {
|
||||||
|
ti.Options = &runctypes.CreateOptions{
|
||||||
|
NoPivotRoot: true,
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
opts, ok := ti.Options.(*runctypes.CreateOptions)
|
||||||
|
if !ok {
|
||||||
|
return errors.New("invalid options type, expected runctypes.CreateOptions")
|
||||||
|
}
|
||||||
|
opts.NoPivotRoot = true
|
||||||
}
|
}
|
||||||
opts, ok := info.Options.(*runctypes.CreateOptions)
|
|
||||||
if !ok {
|
|
||||||
return errors.New("invalid options type, expected runctypes.CreateOptions")
|
|
||||||
}
|
|
||||||
opts.NoPivotRoot = true
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
15
vendor/github.com/containerd/containerd/vendor.conf
generated
vendored
15
vendor/github.com/containerd/containerd/vendor.conf
generated
vendored
@ -1,6 +1,6 @@
|
|||||||
github.com/containerd/go-runc 5a6d9f37cfa36b15efba46dc7ea349fa9b7143c3
|
github.com/containerd/go-runc 5a6d9f37cfa36b15efba46dc7ea349fa9b7143c3
|
||||||
github.com/containerd/console c12b1e7919c14469339a5d38f2f8ed9b64a9de23
|
github.com/containerd/console c12b1e7919c14469339a5d38f2f8ed9b64a9de23
|
||||||
github.com/containerd/cgroups 1152b960fcee041f50df15cdc67c29dbccf801ef
|
github.com/containerd/cgroups dbea6f2bd41658b84b00417ceefa416b979cbf10
|
||||||
github.com/containerd/typeurl a93fcdb778cd272c6e9b3028b2f42d813e785d40
|
github.com/containerd/typeurl a93fcdb778cd272c6e9b3028b2f42d813e785d40
|
||||||
github.com/containerd/fifo 3d5202aec260678c48179c56f40e6f38a095738c
|
github.com/containerd/fifo 3d5202aec260678c48179c56f40e6f38a095738c
|
||||||
github.com/containerd/btrfs 2e1aa0ddf94f91fa282b6ed87c23bf0d64911244
|
github.com/containerd/btrfs 2e1aa0ddf94f91fa282b6ed87c23bf0d64911244
|
||||||
@ -19,20 +19,21 @@ github.com/matttproud/golang_protobuf_extensions v1.0.0
|
|||||||
github.com/gogo/protobuf v1.0.0
|
github.com/gogo/protobuf v1.0.0
|
||||||
github.com/gogo/googleapis 08a7655d27152912db7aaf4f983275eaf8d128ef
|
github.com/gogo/googleapis 08a7655d27152912db7aaf4f983275eaf8d128ef
|
||||||
github.com/golang/protobuf v1.1.0
|
github.com/golang/protobuf v1.1.0
|
||||||
github.com/opencontainers/runtime-spec eba862dc2470385a233c7507392675cbeadf7353 # v1.0.1-45-geba862d
|
github.com/opencontainers/runtime-spec 29686dbc5559d93fb1ef402eeda3e35c38d75af4 # v1.0.1-59-g29686db
|
||||||
github.com/opencontainers/runc 12f6a991201fdb8f82579582d5e00e28fba06d0a
|
github.com/opencontainers/runc 2b18fe1d885ee5083ef9f0838fee39b62d653e30
|
||||||
github.com/sirupsen/logrus v1.0.3
|
github.com/konsorten/go-windows-terminal-sequences v1.0.1
|
||||||
|
github.com/sirupsen/logrus v1.3.0
|
||||||
github.com/urfave/cli 7bc6a0acffa589f415f88aca16cc1de5ffd66f9c
|
github.com/urfave/cli 7bc6a0acffa589f415f88aca16cc1de5ffd66f9c
|
||||||
golang.org/x/net b3756b4b77d7b13260a0a2ec658753cf48922eac
|
golang.org/x/net b3756b4b77d7b13260a0a2ec658753cf48922eac
|
||||||
google.golang.org/grpc v1.12.0
|
google.golang.org/grpc v1.12.0
|
||||||
github.com/pkg/errors v0.8.0
|
github.com/pkg/errors v0.8.0
|
||||||
github.com/opencontainers/go-digest c9281466c8b2f606084ac71339773efd177436e7
|
github.com/opencontainers/go-digest c9281466c8b2f606084ac71339773efd177436e7
|
||||||
golang.org/x/sys 1b2967e3c290b7c545b3db0deeda16e9be4f98a2 https://github.com/golang/sys
|
golang.org/x/sys d455e41777fca6e8a5a79e34a14b8368bc11d9ba https://github.com/golang/sys
|
||||||
github.com/opencontainers/image-spec v1.0.1
|
github.com/opencontainers/image-spec v1.0.1
|
||||||
golang.org/x/sync 42b317875d0fa942474b76e1b46a6060d720ae6e
|
golang.org/x/sync 42b317875d0fa942474b76e1b46a6060d720ae6e
|
||||||
github.com/BurntSushi/toml a368813c5e648fee92e5f6c30e3944ff9d5e8895
|
github.com/BurntSushi/toml a368813c5e648fee92e5f6c30e3944ff9d5e8895
|
||||||
github.com/grpc-ecosystem/go-grpc-prometheus 6b7015e65d366bf3f19b2b2a000a831940f0f7e0
|
github.com/grpc-ecosystem/go-grpc-prometheus 6b7015e65d366bf3f19b2b2a000a831940f0f7e0
|
||||||
github.com/Microsoft/go-winio v0.4.11
|
github.com/Microsoft/go-winio v0.4.12
|
||||||
github.com/Microsoft/hcsshim v0.8.5
|
github.com/Microsoft/hcsshim v0.8.5
|
||||||
google.golang.org/genproto d80a6e20e776b0b17a324d0ba1ab50a39c8e8944
|
google.golang.org/genproto d80a6e20e776b0b17a324d0ba1ab50a39c8e8944
|
||||||
golang.org/x/text 19e51611da83d6be54ddafce4a4af510cb3e9ea4
|
golang.org/x/text 19e51611da83d6be54ddafce4a4af510cb3e9ea4
|
||||||
@ -40,7 +41,7 @@ github.com/containerd/ttrpc f02858b1457c5ca3aaec3a0803eb0d59f96e41d6
|
|||||||
github.com/syndtr/gocapability db04d3cc01c8b54962a58ec7e491717d06cfcc16
|
github.com/syndtr/gocapability db04d3cc01c8b54962a58ec7e491717d06cfcc16
|
||||||
gotest.tools v2.1.0
|
gotest.tools v2.1.0
|
||||||
github.com/google/go-cmp v0.1.0
|
github.com/google/go-cmp v0.1.0
|
||||||
go.etcd.io/bbolt v1.3.1-etcd.8
|
go.etcd.io/bbolt v1.3.2
|
||||||
|
|
||||||
# cri dependencies
|
# cri dependencies
|
||||||
github.com/containerd/cri 4dd6735020f5596dd41738f8c4f5cb07fa804c5e # master
|
github.com/containerd/cri 4dd6735020f5596dd41738f8c4f5cb07fa804c5e # master
|
||||||
|
354
vendor/github.com/hashicorp/errwrap/LICENSE
generated
vendored
354
vendor/github.com/hashicorp/errwrap/LICENSE
generated
vendored
@ -1,354 +0,0 @@
|
|||||||
Mozilla Public License, version 2.0
|
|
||||||
|
|
||||||
1. Definitions
|
|
||||||
|
|
||||||
1.1. “Contributor”
|
|
||||||
|
|
||||||
means each individual or legal entity that creates, contributes to the
|
|
||||||
creation of, or owns Covered Software.
|
|
||||||
|
|
||||||
1.2. “Contributor Version”
|
|
||||||
|
|
||||||
means the combination of the Contributions of others (if any) used by a
|
|
||||||
Contributor and that particular Contributor’s Contribution.
|
|
||||||
|
|
||||||
1.3. “Contribution”
|
|
||||||
|
|
||||||
means Covered Software of a particular Contributor.
|
|
||||||
|
|
||||||
1.4. “Covered Software”
|
|
||||||
|
|
||||||
means Source Code Form to which the initial Contributor has attached the
|
|
||||||
notice in Exhibit A, the Executable Form of such Source Code Form, and
|
|
||||||
Modifications of such Source Code Form, in each case including portions
|
|
||||||
thereof.
|
|
||||||
|
|
||||||
1.5. “Incompatible With Secondary Licenses”
|
|
||||||
means
|
|
||||||
|
|
||||||
a. that the initial Contributor has attached the notice described in
|
|
||||||
Exhibit B to the Covered Software; or
|
|
||||||
|
|
||||||
b. that the Covered Software was made available under the terms of version
|
|
||||||
1.1 or earlier of the License, but not also under the terms of a
|
|
||||||
Secondary License.
|
|
||||||
|
|
||||||
1.6. “Executable Form”
|
|
||||||
|
|
||||||
means any form of the work other than Source Code Form.
|
|
||||||
|
|
||||||
1.7. “Larger Work”
|
|
||||||
|
|
||||||
means a work that combines Covered Software with other material, in a separate
|
|
||||||
file or files, that is not Covered Software.
|
|
||||||
|
|
||||||
1.8. “License”
|
|
||||||
|
|
||||||
means this document.
|
|
||||||
|
|
||||||
1.9. “Licensable”
|
|
||||||
|
|
||||||
means having the right to grant, to the maximum extent possible, whether at the
|
|
||||||
time of the initial grant or subsequently, any and all of the rights conveyed by
|
|
||||||
this License.
|
|
||||||
|
|
||||||
1.10. “Modifications”
|
|
||||||
|
|
||||||
means any of the following:
|
|
||||||
|
|
||||||
a. any file in Source Code Form that results from an addition to, deletion
|
|
||||||
from, or modification of the contents of Covered Software; or
|
|
||||||
|
|
||||||
b. any new file in Source Code Form that contains any Covered Software.
|
|
||||||
|
|
||||||
1.11. “Patent Claims” of a Contributor
|
|
||||||
|
|
||||||
means any patent claim(s), including without limitation, method, process,
|
|
||||||
and apparatus claims, in any patent Licensable by such Contributor that
|
|
||||||
would be infringed, but for the grant of the License, by the making,
|
|
||||||
using, selling, offering for sale, having made, import, or transfer of
|
|
||||||
either its Contributions or its Contributor Version.
|
|
||||||
|
|
||||||
1.12. “Secondary License”
|
|
||||||
|
|
||||||
means either the GNU General Public License, Version 2.0, the GNU Lesser
|
|
||||||
General Public License, Version 2.1, the GNU Affero General Public
|
|
||||||
License, Version 3.0, or any later versions of those licenses.
|
|
||||||
|
|
||||||
1.13. “Source Code Form”
|
|
||||||
|
|
||||||
means the form of the work preferred for making modifications.
|
|
||||||
|
|
||||||
1.14. “You” (or “Your”)
|
|
||||||
|
|
||||||
means an individual or a legal entity exercising rights under this
|
|
||||||
License. For legal entities, “You” includes any entity that controls, is
|
|
||||||
controlled by, or is under common control with You. For purposes of this
|
|
||||||
definition, “control” means (a) the power, direct or indirect, to cause
|
|
||||||
the direction or management of such entity, whether by contract or
|
|
||||||
otherwise, or (b) ownership of more than fifty percent (50%) of the
|
|
||||||
outstanding shares or beneficial ownership of such entity.
|
|
||||||
|
|
||||||
|
|
||||||
2. License Grants and Conditions
|
|
||||||
|
|
||||||
2.1. Grants
|
|
||||||
|
|
||||||
Each Contributor hereby grants You a world-wide, royalty-free,
|
|
||||||
non-exclusive license:
|
|
||||||
|
|
||||||
a. under intellectual property rights (other than patent or trademark)
|
|
||||||
Licensable by such Contributor to use, reproduce, make available,
|
|
||||||
modify, display, perform, distribute, and otherwise exploit its
|
|
||||||
Contributions, either on an unmodified basis, with Modifications, or as
|
|
||||||
part of a Larger Work; and
|
|
||||||
|
|
||||||
b. under Patent Claims of such Contributor to make, use, sell, offer for
|
|
||||||
sale, have made, import, and otherwise transfer either its Contributions
|
|
||||||
or its Contributor Version.
|
|
||||||
|
|
||||||
2.2. Effective Date
|
|
||||||
|
|
||||||
The licenses granted in Section 2.1 with respect to any Contribution become
|
|
||||||
effective for each Contribution on the date the Contributor first distributes
|
|
||||||
such Contribution.
|
|
||||||
|
|
||||||
2.3. Limitations on Grant Scope
|
|
||||||
|
|
||||||
The licenses granted in this Section 2 are the only rights granted under this
|
|
||||||
License. No additional rights or licenses will be implied from the distribution
|
|
||||||
or licensing of Covered Software under this License. Notwithstanding Section
|
|
||||||
2.1(b) above, no patent license is granted by a Contributor:
|
|
||||||
|
|
||||||
a. for any code that a Contributor has removed from Covered Software; or
|
|
||||||
|
|
||||||
b. for infringements caused by: (i) Your and any other third party’s
|
|
||||||
modifications of Covered Software, or (ii) the combination of its
|
|
||||||
Contributions with other software (except as part of its Contributor
|
|
||||||
Version); or
|
|
||||||
|
|
||||||
c. under Patent Claims infringed by Covered Software in the absence of its
|
|
||||||
Contributions.
|
|
||||||
|
|
||||||
This License does not grant any rights in the trademarks, service marks, or
|
|
||||||
logos of any Contributor (except as may be necessary to comply with the
|
|
||||||
notice requirements in Section 3.4).
|
|
||||||
|
|
||||||
2.4. Subsequent Licenses
|
|
||||||
|
|
||||||
No Contributor makes additional grants as a result of Your choice to
|
|
||||||
distribute the Covered Software under a subsequent version of this License
|
|
||||||
(see Section 10.2) or under the terms of a Secondary License (if permitted
|
|
||||||
under the terms of Section 3.3).
|
|
||||||
|
|
||||||
2.5. Representation
|
|
||||||
|
|
||||||
Each Contributor represents that the Contributor believes its Contributions
|
|
||||||
are its original creation(s) or it has sufficient rights to grant the
|
|
||||||
rights to its Contributions conveyed by this License.
|
|
||||||
|
|
||||||
2.6. Fair Use
|
|
||||||
|
|
||||||
This License is not intended to limit any rights You have under applicable
|
|
||||||
copyright doctrines of fair use, fair dealing, or other equivalents.
|
|
||||||
|
|
||||||
2.7. Conditions
|
|
||||||
|
|
||||||
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in
|
|
||||||
Section 2.1.
|
|
||||||
|
|
||||||
|
|
||||||
3. Responsibilities
|
|
||||||
|
|
||||||
3.1. Distribution of Source Form
|
|
||||||
|
|
||||||
All distribution of Covered Software in Source Code Form, including any
|
|
||||||
Modifications that You create or to which You contribute, must be under the
|
|
||||||
terms of this License. You must inform recipients that the Source Code Form
|
|
||||||
of the Covered Software is governed by the terms of this License, and how
|
|
||||||
they can obtain a copy of this License. You may not attempt to alter or
|
|
||||||
restrict the recipients’ rights in the Source Code Form.
|
|
||||||
|
|
||||||
3.2. Distribution of Executable Form
|
|
||||||
|
|
||||||
If You distribute Covered Software in Executable Form then:
|
|
||||||
|
|
||||||
a. such Covered Software must also be made available in Source Code Form,
|
|
||||||
as described in Section 3.1, and You must inform recipients of the
|
|
||||||
Executable Form how they can obtain a copy of such Source Code Form by
|
|
||||||
reasonable means in a timely manner, at a charge no more than the cost
|
|
||||||
of distribution to the recipient; and
|
|
||||||
|
|
||||||
b. You may distribute such Executable Form under the terms of this License,
|
|
||||||
or sublicense it under different terms, provided that the license for
|
|
||||||
the Executable Form does not attempt to limit or alter the recipients’
|
|
||||||
rights in the Source Code Form under this License.
|
|
||||||
|
|
||||||
3.3. Distribution of a Larger Work
|
|
||||||
|
|
||||||
You may create and distribute a Larger Work under terms of Your choice,
|
|
||||||
provided that You also comply with the requirements of this License for the
|
|
||||||
Covered Software. If the Larger Work is a combination of Covered Software
|
|
||||||
with a work governed by one or more Secondary Licenses, and the Covered
|
|
||||||
Software is not Incompatible With Secondary Licenses, this License permits
|
|
||||||
You to additionally distribute such Covered Software under the terms of
|
|
||||||
such Secondary License(s), so that the recipient of the Larger Work may, at
|
|
||||||
their option, further distribute the Covered Software under the terms of
|
|
||||||
either this License or such Secondary License(s).
|
|
||||||
|
|
||||||
3.4. Notices
|
|
||||||
|
|
||||||
You may not remove or alter the substance of any license notices (including
|
|
||||||
copyright notices, patent notices, disclaimers of warranty, or limitations
|
|
||||||
of liability) contained within the Source Code Form of the Covered
|
|
||||||
Software, except that You may alter any license notices to the extent
|
|
||||||
required to remedy known factual inaccuracies.
|
|
||||||
|
|
||||||
3.5. Application of Additional Terms
|
|
||||||
|
|
||||||
You may choose to offer, and to charge a fee for, warranty, support,
|
|
||||||
indemnity or liability obligations to one or more recipients of Covered
|
|
||||||
Software. However, You may do so only on Your own behalf, and not on behalf
|
|
||||||
of any Contributor. You must make it absolutely clear that any such
|
|
||||||
warranty, support, indemnity, or liability obligation is offered by You
|
|
||||||
alone, and You hereby agree to indemnify every Contributor for any
|
|
||||||
liability incurred by such Contributor as a result of warranty, support,
|
|
||||||
indemnity or liability terms You offer. You may include additional
|
|
||||||
disclaimers of warranty and limitations of liability specific to any
|
|
||||||
jurisdiction.
|
|
||||||
|
|
||||||
4. Inability to Comply Due to Statute or Regulation
|
|
||||||
|
|
||||||
If it is impossible for You to comply with any of the terms of this License
|
|
||||||
with respect to some or all of the Covered Software due to statute, judicial
|
|
||||||
order, or regulation then You must: (a) comply with the terms of this License
|
|
||||||
to the maximum extent possible; and (b) describe the limitations and the code
|
|
||||||
they affect. Such description must be placed in a text file included with all
|
|
||||||
distributions of the Covered Software under this License. Except to the
|
|
||||||
extent prohibited by statute or regulation, such description must be
|
|
||||||
sufficiently detailed for a recipient of ordinary skill to be able to
|
|
||||||
understand it.
|
|
||||||
|
|
||||||
5. Termination
|
|
||||||
|
|
||||||
5.1. The rights granted under this License will terminate automatically if You
|
|
||||||
fail to comply with any of its terms. However, if You become compliant,
|
|
||||||
then the rights granted under this License from a particular Contributor
|
|
||||||
are reinstated (a) provisionally, unless and until such Contributor
|
|
||||||
explicitly and finally terminates Your grants, and (b) on an ongoing basis,
|
|
||||||
if such Contributor fails to notify You of the non-compliance by some
|
|
||||||
reasonable means prior to 60 days after You have come back into compliance.
|
|
||||||
Moreover, Your grants from a particular Contributor are reinstated on an
|
|
||||||
ongoing basis if such Contributor notifies You of the non-compliance by
|
|
||||||
some reasonable means, this is the first time You have received notice of
|
|
||||||
non-compliance with this License from such Contributor, and You become
|
|
||||||
compliant prior to 30 days after Your receipt of the notice.
|
|
||||||
|
|
||||||
5.2. If You initiate litigation against any entity by asserting a patent
|
|
||||||
infringement claim (excluding declaratory judgment actions, counter-claims,
|
|
||||||
and cross-claims) alleging that a Contributor Version directly or
|
|
||||||
indirectly infringes any patent, then the rights granted to You by any and
|
|
||||||
all Contributors for the Covered Software under Section 2.1 of this License
|
|
||||||
shall terminate.
|
|
||||||
|
|
||||||
5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user
|
|
||||||
license agreements (excluding distributors and resellers) which have been
|
|
||||||
validly granted by You or Your distributors under this License prior to
|
|
||||||
termination shall survive termination.
|
|
||||||
|
|
||||||
6. Disclaimer of Warranty
|
|
||||||
|
|
||||||
Covered Software is provided under this License on an “as is” basis, without
|
|
||||||
warranty of any kind, either expressed, implied, or statutory, including,
|
|
||||||
without limitation, warranties that the Covered Software is free of defects,
|
|
||||||
merchantable, fit for a particular purpose or non-infringing. The entire
|
|
||||||
risk as to the quality and performance of the Covered Software is with You.
|
|
||||||
Should any Covered Software prove defective in any respect, You (not any
|
|
||||||
Contributor) assume the cost of any necessary servicing, repair, or
|
|
||||||
correction. This disclaimer of warranty constitutes an essential part of this
|
|
||||||
License. No use of any Covered Software is authorized under this License
|
|
||||||
except under this disclaimer.
|
|
||||||
|
|
||||||
7. Limitation of Liability
|
|
||||||
|
|
||||||
Under no circumstances and under no legal theory, whether tort (including
|
|
||||||
negligence), contract, or otherwise, shall any Contributor, or anyone who
|
|
||||||
distributes Covered Software as permitted above, be liable to You for any
|
|
||||||
direct, indirect, special, incidental, or consequential damages of any
|
|
||||||
character including, without limitation, damages for lost profits, loss of
|
|
||||||
goodwill, work stoppage, computer failure or malfunction, or any and all
|
|
||||||
other commercial damages or losses, even if such party shall have been
|
|
||||||
informed of the possibility of such damages. This limitation of liability
|
|
||||||
shall not apply to liability for death or personal injury resulting from such
|
|
||||||
party’s negligence to the extent applicable law prohibits such limitation.
|
|
||||||
Some jurisdictions do not allow the exclusion or limitation of incidental or
|
|
||||||
consequential damages, so this exclusion and limitation may not apply to You.
|
|
||||||
|
|
||||||
8. Litigation
|
|
||||||
|
|
||||||
Any litigation relating to this License may be brought only in the courts of
|
|
||||||
a jurisdiction where the defendant maintains its principal place of business
|
|
||||||
and such litigation shall be governed by laws of that jurisdiction, without
|
|
||||||
reference to its conflict-of-law provisions. Nothing in this Section shall
|
|
||||||
prevent a party’s ability to bring cross-claims or counter-claims.
|
|
||||||
|
|
||||||
9. Miscellaneous
|
|
||||||
|
|
||||||
This License represents the complete agreement concerning the subject matter
|
|
||||||
hereof. If any provision of this License is held to be unenforceable, such
|
|
||||||
provision shall be reformed only to the extent necessary to make it
|
|
||||||
enforceable. Any law or regulation which provides that the language of a
|
|
||||||
contract shall be construed against the drafter shall not be used to construe
|
|
||||||
this License against a Contributor.
|
|
||||||
|
|
||||||
|
|
||||||
10. Versions of the License
|
|
||||||
|
|
||||||
10.1. New Versions
|
|
||||||
|
|
||||||
Mozilla Foundation is the license steward. Except as provided in Section
|
|
||||||
10.3, no one other than the license steward has the right to modify or
|
|
||||||
publish new versions of this License. Each version will be given a
|
|
||||||
distinguishing version number.
|
|
||||||
|
|
||||||
10.2. Effect of New Versions
|
|
||||||
|
|
||||||
You may distribute the Covered Software under the terms of the version of
|
|
||||||
the License under which You originally received the Covered Software, or
|
|
||||||
under the terms of any subsequent version published by the license
|
|
||||||
steward.
|
|
||||||
|
|
||||||
10.3. Modified Versions
|
|
||||||
|
|
||||||
If you create software not governed by this License, and you want to
|
|
||||||
create a new license for such software, you may create and use a modified
|
|
||||||
version of this License if you rename the license and remove any
|
|
||||||
references to the name of the license steward (except to note that such
|
|
||||||
modified license differs from this License).
|
|
||||||
|
|
||||||
10.4. Distributing Source Code Form that is Incompatible With Secondary Licenses
|
|
||||||
If You choose to distribute Source Code Form that is Incompatible With
|
|
||||||
Secondary Licenses under the terms of this version of the License, the
|
|
||||||
notice described in Exhibit B of this License must be attached.
|
|
||||||
|
|
||||||
Exhibit A - Source Code Form License Notice
|
|
||||||
|
|
||||||
This Source Code Form is subject to the
|
|
||||||
terms of the Mozilla Public License, v.
|
|
||||||
2.0. If a copy of the MPL was not
|
|
||||||
distributed with this file, You can
|
|
||||||
obtain one at
|
|
||||||
http://mozilla.org/MPL/2.0/.
|
|
||||||
|
|
||||||
If it is not possible or desirable to put the notice in a particular file, then
|
|
||||||
You may include the notice in a location (such as a LICENSE file in a relevant
|
|
||||||
directory) where a recipient would be likely to look for such a notice.
|
|
||||||
|
|
||||||
You may add additional accurate notices of copyright ownership.
|
|
||||||
|
|
||||||
Exhibit B - “Incompatible With Secondary Licenses” Notice
|
|
||||||
|
|
||||||
This Source Code Form is “Incompatible
|
|
||||||
With Secondary Licenses”, as defined by
|
|
||||||
the Mozilla Public License, v. 2.0.
|
|
||||||
|
|
89
vendor/github.com/hashicorp/errwrap/README.md
generated
vendored
89
vendor/github.com/hashicorp/errwrap/README.md
generated
vendored
@ -1,89 +0,0 @@
|
|||||||
# errwrap
|
|
||||||
|
|
||||||
`errwrap` is a package for Go that formalizes the pattern of wrapping errors
|
|
||||||
and checking if an error contains another error.
|
|
||||||
|
|
||||||
There is a common pattern in Go of taking a returned `error` value and
|
|
||||||
then wrapping it (such as with `fmt.Errorf`) before returning it. The problem
|
|
||||||
with this pattern is that you completely lose the original `error` structure.
|
|
||||||
|
|
||||||
Arguably the _correct_ approach is that you should make a custom structure
|
|
||||||
implementing the `error` interface, and have the original error as a field
|
|
||||||
on that structure, such [as this example](http://golang.org/pkg/os/#PathError).
|
|
||||||
This is a good approach, but you have to know the entire chain of possible
|
|
||||||
rewrapping that happens, when you might just care about one.
|
|
||||||
|
|
||||||
`errwrap` formalizes this pattern (it doesn't matter what approach you use
|
|
||||||
above) by giving a single interface for wrapping errors, checking if a specific
|
|
||||||
error is wrapped, and extracting that error.
|
|
||||||
|
|
||||||
## Installation and Docs
|
|
||||||
|
|
||||||
Install using `go get github.com/hashicorp/errwrap`.
|
|
||||||
|
|
||||||
Full documentation is available at
|
|
||||||
http://godoc.org/github.com/hashicorp/errwrap
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
#### Basic Usage
|
|
||||||
|
|
||||||
Below is a very basic example of its usage:
|
|
||||||
|
|
||||||
```go
|
|
||||||
// A function that always returns an error, but wraps it, like a real
|
|
||||||
// function might.
|
|
||||||
func tryOpen() error {
|
|
||||||
_, err := os.Open("/i/dont/exist")
|
|
||||||
if err != nil {
|
|
||||||
return errwrap.Wrapf("Doesn't exist: {{err}}", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
err := tryOpen()
|
|
||||||
|
|
||||||
// We can use the Contains helpers to check if an error contains
|
|
||||||
// another error. It is safe to do this with a nil error, or with
|
|
||||||
// an error that doesn't even use the errwrap package.
|
|
||||||
if errwrap.Contains(err, ErrNotExist) {
|
|
||||||
// Do something
|
|
||||||
}
|
|
||||||
if errwrap.ContainsType(err, new(os.PathError)) {
|
|
||||||
// Do something
|
|
||||||
}
|
|
||||||
|
|
||||||
// Or we can use the associated `Get` functions to just extract
|
|
||||||
// a specific error. This would return nil if that specific error doesn't
|
|
||||||
// exist.
|
|
||||||
perr := errwrap.GetType(err, new(os.PathError))
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Custom Types
|
|
||||||
|
|
||||||
If you're already making custom types that properly wrap errors, then
|
|
||||||
you can get all the functionality of `errwraps.Contains` and such by
|
|
||||||
implementing the `Wrapper` interface with just one function. Example:
|
|
||||||
|
|
||||||
```go
|
|
||||||
type AppError {
|
|
||||||
Code ErrorCode
|
|
||||||
Err error
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *AppError) WrappedErrors() []error {
|
|
||||||
return []error{e.Err}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Now this works:
|
|
||||||
|
|
||||||
```go
|
|
||||||
err := &AppError{Err: fmt.Errorf("an error")}
|
|
||||||
if errwrap.ContainsType(err, fmt.Errorf("")) {
|
|
||||||
// This will work!
|
|
||||||
}
|
|
||||||
```
|
|
169
vendor/github.com/hashicorp/errwrap/errwrap.go
generated
vendored
169
vendor/github.com/hashicorp/errwrap/errwrap.go
generated
vendored
@ -1,169 +0,0 @@
|
|||||||
// Package errwrap implements methods to formalize error wrapping in Go.
|
|
||||||
//
|
|
||||||
// All of the top-level functions that take an `error` are built to be able
|
|
||||||
// to take any error, not just wrapped errors. This allows you to use errwrap
|
|
||||||
// without having to type-check and type-cast everywhere.
|
|
||||||
package errwrap
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"reflect"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
// WalkFunc is the callback called for Walk.
|
|
||||||
type WalkFunc func(error)
|
|
||||||
|
|
||||||
// Wrapper is an interface that can be implemented by custom types to
|
|
||||||
// have all the Contains, Get, etc. functions in errwrap work.
|
|
||||||
//
|
|
||||||
// When Walk reaches a Wrapper, it will call the callback for every
|
|
||||||
// wrapped error in addition to the wrapper itself. Since all the top-level
|
|
||||||
// functions in errwrap use Walk, this means that all those functions work
|
|
||||||
// with your custom type.
|
|
||||||
type Wrapper interface {
|
|
||||||
WrappedErrors() []error
|
|
||||||
}
|
|
||||||
|
|
||||||
// Wrap defines that outer wraps inner, returning an error type that
|
|
||||||
// can be cleanly used with the other methods in this package, such as
|
|
||||||
// Contains, GetAll, etc.
|
|
||||||
//
|
|
||||||
// This function won't modify the error message at all (the outer message
|
|
||||||
// will be used).
|
|
||||||
func Wrap(outer, inner error) error {
|
|
||||||
return &wrappedError{
|
|
||||||
Outer: outer,
|
|
||||||
Inner: inner,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Wrapf wraps an error with a formatting message. This is similar to using
|
|
||||||
// `fmt.Errorf` to wrap an error. If you're using `fmt.Errorf` to wrap
|
|
||||||
// errors, you should replace it with this.
|
|
||||||
//
|
|
||||||
// format is the format of the error message. The string '{{err}}' will
|
|
||||||
// be replaced with the original error message.
|
|
||||||
func Wrapf(format string, err error) error {
|
|
||||||
outerMsg := "<nil>"
|
|
||||||
if err != nil {
|
|
||||||
outerMsg = err.Error()
|
|
||||||
}
|
|
||||||
|
|
||||||
outer := errors.New(strings.Replace(
|
|
||||||
format, "{{err}}", outerMsg, -1))
|
|
||||||
|
|
||||||
return Wrap(outer, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Contains checks if the given error contains an error with the
|
|
||||||
// message msg. If err is not a wrapped error, this will always return
|
|
||||||
// false unless the error itself happens to match this msg.
|
|
||||||
func Contains(err error, msg string) bool {
|
|
||||||
return len(GetAll(err, msg)) > 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// ContainsType checks if the given error contains an error with
|
|
||||||
// the same concrete type as v. If err is not a wrapped error, this will
|
|
||||||
// check the err itself.
|
|
||||||
func ContainsType(err error, v interface{}) bool {
|
|
||||||
return len(GetAllType(err, v)) > 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get is the same as GetAll but returns the deepest matching error.
|
|
||||||
func Get(err error, msg string) error {
|
|
||||||
es := GetAll(err, msg)
|
|
||||||
if len(es) > 0 {
|
|
||||||
return es[len(es)-1]
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetType is the same as GetAllType but returns the deepest matching error.
|
|
||||||
func GetType(err error, v interface{}) error {
|
|
||||||
es := GetAllType(err, v)
|
|
||||||
if len(es) > 0 {
|
|
||||||
return es[len(es)-1]
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetAll gets all the errors that might be wrapped in err with the
|
|
||||||
// given message. The order of the errors is such that the outermost
|
|
||||||
// matching error (the most recent wrap) is index zero, and so on.
|
|
||||||
func GetAll(err error, msg string) []error {
|
|
||||||
var result []error
|
|
||||||
|
|
||||||
Walk(err, func(err error) {
|
|
||||||
if err.Error() == msg {
|
|
||||||
result = append(result, err)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetAllType gets all the errors that are the same type as v.
|
|
||||||
//
|
|
||||||
// The order of the return value is the same as described in GetAll.
|
|
||||||
func GetAllType(err error, v interface{}) []error {
|
|
||||||
var result []error
|
|
||||||
|
|
||||||
var search string
|
|
||||||
if v != nil {
|
|
||||||
search = reflect.TypeOf(v).String()
|
|
||||||
}
|
|
||||||
Walk(err, func(err error) {
|
|
||||||
var needle string
|
|
||||||
if err != nil {
|
|
||||||
needle = reflect.TypeOf(err).String()
|
|
||||||
}
|
|
||||||
|
|
||||||
if needle == search {
|
|
||||||
result = append(result, err)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
// Walk walks all the wrapped errors in err and calls the callback. If
|
|
||||||
// err isn't a wrapped error, this will be called once for err. If err
|
|
||||||
// is a wrapped error, the callback will be called for both the wrapper
|
|
||||||
// that implements error as well as the wrapped error itself.
|
|
||||||
func Walk(err error, cb WalkFunc) {
|
|
||||||
if err == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
switch e := err.(type) {
|
|
||||||
case *wrappedError:
|
|
||||||
cb(e.Outer)
|
|
||||||
Walk(e.Inner, cb)
|
|
||||||
case Wrapper:
|
|
||||||
cb(err)
|
|
||||||
|
|
||||||
for _, err := range e.WrappedErrors() {
|
|
||||||
Walk(err, cb)
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
cb(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// wrappedError is an implementation of error that has both the
|
|
||||||
// outer and inner errors.
|
|
||||||
type wrappedError struct {
|
|
||||||
Outer error
|
|
||||||
Inner error
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *wrappedError) Error() string {
|
|
||||||
return w.Outer.Error()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *wrappedError) WrappedErrors() []error {
|
|
||||||
return []error{w.Outer, w.Inner}
|
|
||||||
}
|
|
353
vendor/github.com/hashicorp/go-multierror/LICENSE
generated
vendored
353
vendor/github.com/hashicorp/go-multierror/LICENSE
generated
vendored
@ -1,353 +0,0 @@
|
|||||||
Mozilla Public License, version 2.0
|
|
||||||
|
|
||||||
1. Definitions
|
|
||||||
|
|
||||||
1.1. “Contributor”
|
|
||||||
|
|
||||||
means each individual or legal entity that creates, contributes to the
|
|
||||||
creation of, or owns Covered Software.
|
|
||||||
|
|
||||||
1.2. “Contributor Version”
|
|
||||||
|
|
||||||
means the combination of the Contributions of others (if any) used by a
|
|
||||||
Contributor and that particular Contributor’s Contribution.
|
|
||||||
|
|
||||||
1.3. “Contribution”
|
|
||||||
|
|
||||||
means Covered Software of a particular Contributor.
|
|
||||||
|
|
||||||
1.4. “Covered Software”
|
|
||||||
|
|
||||||
means Source Code Form to which the initial Contributor has attached the
|
|
||||||
notice in Exhibit A, the Executable Form of such Source Code Form, and
|
|
||||||
Modifications of such Source Code Form, in each case including portions
|
|
||||||
thereof.
|
|
||||||
|
|
||||||
1.5. “Incompatible With Secondary Licenses”
|
|
||||||
means
|
|
||||||
|
|
||||||
a. that the initial Contributor has attached the notice described in
|
|
||||||
Exhibit B to the Covered Software; or
|
|
||||||
|
|
||||||
b. that the Covered Software was made available under the terms of version
|
|
||||||
1.1 or earlier of the License, but not also under the terms of a
|
|
||||||
Secondary License.
|
|
||||||
|
|
||||||
1.6. “Executable Form”
|
|
||||||
|
|
||||||
means any form of the work other than Source Code Form.
|
|
||||||
|
|
||||||
1.7. “Larger Work”
|
|
||||||
|
|
||||||
means a work that combines Covered Software with other material, in a separate
|
|
||||||
file or files, that is not Covered Software.
|
|
||||||
|
|
||||||
1.8. “License”
|
|
||||||
|
|
||||||
means this document.
|
|
||||||
|
|
||||||
1.9. “Licensable”
|
|
||||||
|
|
||||||
means having the right to grant, to the maximum extent possible, whether at the
|
|
||||||
time of the initial grant or subsequently, any and all of the rights conveyed by
|
|
||||||
this License.
|
|
||||||
|
|
||||||
1.10. “Modifications”
|
|
||||||
|
|
||||||
means any of the following:
|
|
||||||
|
|
||||||
a. any file in Source Code Form that results from an addition to, deletion
|
|
||||||
from, or modification of the contents of Covered Software; or
|
|
||||||
|
|
||||||
b. any new file in Source Code Form that contains any Covered Software.
|
|
||||||
|
|
||||||
1.11. “Patent Claims” of a Contributor
|
|
||||||
|
|
||||||
means any patent claim(s), including without limitation, method, process,
|
|
||||||
and apparatus claims, in any patent Licensable by such Contributor that
|
|
||||||
would be infringed, but for the grant of the License, by the making,
|
|
||||||
using, selling, offering for sale, having made, import, or transfer of
|
|
||||||
either its Contributions or its Contributor Version.
|
|
||||||
|
|
||||||
1.12. “Secondary License”
|
|
||||||
|
|
||||||
means either the GNU General Public License, Version 2.0, the GNU Lesser
|
|
||||||
General Public License, Version 2.1, the GNU Affero General Public
|
|
||||||
License, Version 3.0, or any later versions of those licenses.
|
|
||||||
|
|
||||||
1.13. “Source Code Form”
|
|
||||||
|
|
||||||
means the form of the work preferred for making modifications.
|
|
||||||
|
|
||||||
1.14. “You” (or “Your”)
|
|
||||||
|
|
||||||
means an individual or a legal entity exercising rights under this
|
|
||||||
License. For legal entities, “You” includes any entity that controls, is
|
|
||||||
controlled by, or is under common control with You. For purposes of this
|
|
||||||
definition, “control” means (a) the power, direct or indirect, to cause
|
|
||||||
the direction or management of such entity, whether by contract or
|
|
||||||
otherwise, or (b) ownership of more than fifty percent (50%) of the
|
|
||||||
outstanding shares or beneficial ownership of such entity.
|
|
||||||
|
|
||||||
|
|
||||||
2. License Grants and Conditions
|
|
||||||
|
|
||||||
2.1. Grants
|
|
||||||
|
|
||||||
Each Contributor hereby grants You a world-wide, royalty-free,
|
|
||||||
non-exclusive license:
|
|
||||||
|
|
||||||
a. under intellectual property rights (other than patent or trademark)
|
|
||||||
Licensable by such Contributor to use, reproduce, make available,
|
|
||||||
modify, display, perform, distribute, and otherwise exploit its
|
|
||||||
Contributions, either on an unmodified basis, with Modifications, or as
|
|
||||||
part of a Larger Work; and
|
|
||||||
|
|
||||||
b. under Patent Claims of such Contributor to make, use, sell, offer for
|
|
||||||
sale, have made, import, and otherwise transfer either its Contributions
|
|
||||||
or its Contributor Version.
|
|
||||||
|
|
||||||
2.2. Effective Date
|
|
||||||
|
|
||||||
The licenses granted in Section 2.1 with respect to any Contribution become
|
|
||||||
effective for each Contribution on the date the Contributor first distributes
|
|
||||||
such Contribution.
|
|
||||||
|
|
||||||
2.3. Limitations on Grant Scope
|
|
||||||
|
|
||||||
The licenses granted in this Section 2 are the only rights granted under this
|
|
||||||
License. No additional rights or licenses will be implied from the distribution
|
|
||||||
or licensing of Covered Software under this License. Notwithstanding Section
|
|
||||||
2.1(b) above, no patent license is granted by a Contributor:
|
|
||||||
|
|
||||||
a. for any code that a Contributor has removed from Covered Software; or
|
|
||||||
|
|
||||||
b. for infringements caused by: (i) Your and any other third party’s
|
|
||||||
modifications of Covered Software, or (ii) the combination of its
|
|
||||||
Contributions with other software (except as part of its Contributor
|
|
||||||
Version); or
|
|
||||||
|
|
||||||
c. under Patent Claims infringed by Covered Software in the absence of its
|
|
||||||
Contributions.
|
|
||||||
|
|
||||||
This License does not grant any rights in the trademarks, service marks, or
|
|
||||||
logos of any Contributor (except as may be necessary to comply with the
|
|
||||||
notice requirements in Section 3.4).
|
|
||||||
|
|
||||||
2.4. Subsequent Licenses
|
|
||||||
|
|
||||||
No Contributor makes additional grants as a result of Your choice to
|
|
||||||
distribute the Covered Software under a subsequent version of this License
|
|
||||||
(see Section 10.2) or under the terms of a Secondary License (if permitted
|
|
||||||
under the terms of Section 3.3).
|
|
||||||
|
|
||||||
2.5. Representation
|
|
||||||
|
|
||||||
Each Contributor represents that the Contributor believes its Contributions
|
|
||||||
are its original creation(s) or it has sufficient rights to grant the
|
|
||||||
rights to its Contributions conveyed by this License.
|
|
||||||
|
|
||||||
2.6. Fair Use
|
|
||||||
|
|
||||||
This License is not intended to limit any rights You have under applicable
|
|
||||||
copyright doctrines of fair use, fair dealing, or other equivalents.
|
|
||||||
|
|
||||||
2.7. Conditions
|
|
||||||
|
|
||||||
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in
|
|
||||||
Section 2.1.
|
|
||||||
|
|
||||||
|
|
||||||
3. Responsibilities
|
|
||||||
|
|
||||||
3.1. Distribution of Source Form
|
|
||||||
|
|
||||||
All distribution of Covered Software in Source Code Form, including any
|
|
||||||
Modifications that You create or to which You contribute, must be under the
|
|
||||||
terms of this License. You must inform recipients that the Source Code Form
|
|
||||||
of the Covered Software is governed by the terms of this License, and how
|
|
||||||
they can obtain a copy of this License. You may not attempt to alter or
|
|
||||||
restrict the recipients’ rights in the Source Code Form.
|
|
||||||
|
|
||||||
3.2. Distribution of Executable Form
|
|
||||||
|
|
||||||
If You distribute Covered Software in Executable Form then:
|
|
||||||
|
|
||||||
a. such Covered Software must also be made available in Source Code Form,
|
|
||||||
as described in Section 3.1, and You must inform recipients of the
|
|
||||||
Executable Form how they can obtain a copy of such Source Code Form by
|
|
||||||
reasonable means in a timely manner, at a charge no more than the cost
|
|
||||||
of distribution to the recipient; and
|
|
||||||
|
|
||||||
b. You may distribute such Executable Form under the terms of this License,
|
|
||||||
or sublicense it under different terms, provided that the license for
|
|
||||||
the Executable Form does not attempt to limit or alter the recipients’
|
|
||||||
rights in the Source Code Form under this License.
|
|
||||||
|
|
||||||
3.3. Distribution of a Larger Work
|
|
||||||
|
|
||||||
You may create and distribute a Larger Work under terms of Your choice,
|
|
||||||
provided that You also comply with the requirements of this License for the
|
|
||||||
Covered Software. If the Larger Work is a combination of Covered Software
|
|
||||||
with a work governed by one or more Secondary Licenses, and the Covered
|
|
||||||
Software is not Incompatible With Secondary Licenses, this License permits
|
|
||||||
You to additionally distribute such Covered Software under the terms of
|
|
||||||
such Secondary License(s), so that the recipient of the Larger Work may, at
|
|
||||||
their option, further distribute the Covered Software under the terms of
|
|
||||||
either this License or such Secondary License(s).
|
|
||||||
|
|
||||||
3.4. Notices
|
|
||||||
|
|
||||||
You may not remove or alter the substance of any license notices (including
|
|
||||||
copyright notices, patent notices, disclaimers of warranty, or limitations
|
|
||||||
of liability) contained within the Source Code Form of the Covered
|
|
||||||
Software, except that You may alter any license notices to the extent
|
|
||||||
required to remedy known factual inaccuracies.
|
|
||||||
|
|
||||||
3.5. Application of Additional Terms
|
|
||||||
|
|
||||||
You may choose to offer, and to charge a fee for, warranty, support,
|
|
||||||
indemnity or liability obligations to one or more recipients of Covered
|
|
||||||
Software. However, You may do so only on Your own behalf, and not on behalf
|
|
||||||
of any Contributor. You must make it absolutely clear that any such
|
|
||||||
warranty, support, indemnity, or liability obligation is offered by You
|
|
||||||
alone, and You hereby agree to indemnify every Contributor for any
|
|
||||||
liability incurred by such Contributor as a result of warranty, support,
|
|
||||||
indemnity or liability terms You offer. You may include additional
|
|
||||||
disclaimers of warranty and limitations of liability specific to any
|
|
||||||
jurisdiction.
|
|
||||||
|
|
||||||
4. Inability to Comply Due to Statute or Regulation
|
|
||||||
|
|
||||||
If it is impossible for You to comply with any of the terms of this License
|
|
||||||
with respect to some or all of the Covered Software due to statute, judicial
|
|
||||||
order, or regulation then You must: (a) comply with the terms of this License
|
|
||||||
to the maximum extent possible; and (b) describe the limitations and the code
|
|
||||||
they affect. Such description must be placed in a text file included with all
|
|
||||||
distributions of the Covered Software under this License. Except to the
|
|
||||||
extent prohibited by statute or regulation, such description must be
|
|
||||||
sufficiently detailed for a recipient of ordinary skill to be able to
|
|
||||||
understand it.
|
|
||||||
|
|
||||||
5. Termination
|
|
||||||
|
|
||||||
5.1. The rights granted under this License will terminate automatically if You
|
|
||||||
fail to comply with any of its terms. However, if You become compliant,
|
|
||||||
then the rights granted under this License from a particular Contributor
|
|
||||||
are reinstated (a) provisionally, unless and until such Contributor
|
|
||||||
explicitly and finally terminates Your grants, and (b) on an ongoing basis,
|
|
||||||
if such Contributor fails to notify You of the non-compliance by some
|
|
||||||
reasonable means prior to 60 days after You have come back into compliance.
|
|
||||||
Moreover, Your grants from a particular Contributor are reinstated on an
|
|
||||||
ongoing basis if such Contributor notifies You of the non-compliance by
|
|
||||||
some reasonable means, this is the first time You have received notice of
|
|
||||||
non-compliance with this License from such Contributor, and You become
|
|
||||||
compliant prior to 30 days after Your receipt of the notice.
|
|
||||||
|
|
||||||
5.2. If You initiate litigation against any entity by asserting a patent
|
|
||||||
infringement claim (excluding declaratory judgment actions, counter-claims,
|
|
||||||
and cross-claims) alleging that a Contributor Version directly or
|
|
||||||
indirectly infringes any patent, then the rights granted to You by any and
|
|
||||||
all Contributors for the Covered Software under Section 2.1 of this License
|
|
||||||
shall terminate.
|
|
||||||
|
|
||||||
5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user
|
|
||||||
license agreements (excluding distributors and resellers) which have been
|
|
||||||
validly granted by You or Your distributors under this License prior to
|
|
||||||
termination shall survive termination.
|
|
||||||
|
|
||||||
6. Disclaimer of Warranty
|
|
||||||
|
|
||||||
Covered Software is provided under this License on an “as is” basis, without
|
|
||||||
warranty of any kind, either expressed, implied, or statutory, including,
|
|
||||||
without limitation, warranties that the Covered Software is free of defects,
|
|
||||||
merchantable, fit for a particular purpose or non-infringing. The entire
|
|
||||||
risk as to the quality and performance of the Covered Software is with You.
|
|
||||||
Should any Covered Software prove defective in any respect, You (not any
|
|
||||||
Contributor) assume the cost of any necessary servicing, repair, or
|
|
||||||
correction. This disclaimer of warranty constitutes an essential part of this
|
|
||||||
License. No use of any Covered Software is authorized under this License
|
|
||||||
except under this disclaimer.
|
|
||||||
|
|
||||||
7. Limitation of Liability
|
|
||||||
|
|
||||||
Under no circumstances and under no legal theory, whether tort (including
|
|
||||||
negligence), contract, or otherwise, shall any Contributor, or anyone who
|
|
||||||
distributes Covered Software as permitted above, be liable to You for any
|
|
||||||
direct, indirect, special, incidental, or consequential damages of any
|
|
||||||
character including, without limitation, damages for lost profits, loss of
|
|
||||||
goodwill, work stoppage, computer failure or malfunction, or any and all
|
|
||||||
other commercial damages or losses, even if such party shall have been
|
|
||||||
informed of the possibility of such damages. This limitation of liability
|
|
||||||
shall not apply to liability for death or personal injury resulting from such
|
|
||||||
party’s negligence to the extent applicable law prohibits such limitation.
|
|
||||||
Some jurisdictions do not allow the exclusion or limitation of incidental or
|
|
||||||
consequential damages, so this exclusion and limitation may not apply to You.
|
|
||||||
|
|
||||||
8. Litigation
|
|
||||||
|
|
||||||
Any litigation relating to this License may be brought only in the courts of
|
|
||||||
a jurisdiction where the defendant maintains its principal place of business
|
|
||||||
and such litigation shall be governed by laws of that jurisdiction, without
|
|
||||||
reference to its conflict-of-law provisions. Nothing in this Section shall
|
|
||||||
prevent a party’s ability to bring cross-claims or counter-claims.
|
|
||||||
|
|
||||||
9. Miscellaneous
|
|
||||||
|
|
||||||
This License represents the complete agreement concerning the subject matter
|
|
||||||
hereof. If any provision of this License is held to be unenforceable, such
|
|
||||||
provision shall be reformed only to the extent necessary to make it
|
|
||||||
enforceable. Any law or regulation which provides that the language of a
|
|
||||||
contract shall be construed against the drafter shall not be used to construe
|
|
||||||
this License against a Contributor.
|
|
||||||
|
|
||||||
|
|
||||||
10. Versions of the License
|
|
||||||
|
|
||||||
10.1. New Versions
|
|
||||||
|
|
||||||
Mozilla Foundation is the license steward. Except as provided in Section
|
|
||||||
10.3, no one other than the license steward has the right to modify or
|
|
||||||
publish new versions of this License. Each version will be given a
|
|
||||||
distinguishing version number.
|
|
||||||
|
|
||||||
10.2. Effect of New Versions
|
|
||||||
|
|
||||||
You may distribute the Covered Software under the terms of the version of
|
|
||||||
the License under which You originally received the Covered Software, or
|
|
||||||
under the terms of any subsequent version published by the license
|
|
||||||
steward.
|
|
||||||
|
|
||||||
10.3. Modified Versions
|
|
||||||
|
|
||||||
If you create software not governed by this License, and you want to
|
|
||||||
create a new license for such software, you may create and use a modified
|
|
||||||
version of this License if you rename the license and remove any
|
|
||||||
references to the name of the license steward (except to note that such
|
|
||||||
modified license differs from this License).
|
|
||||||
|
|
||||||
10.4. Distributing Source Code Form that is Incompatible With Secondary Licenses
|
|
||||||
If You choose to distribute Source Code Form that is Incompatible With
|
|
||||||
Secondary Licenses under the terms of this version of the License, the
|
|
||||||
notice described in Exhibit B of this License must be attached.
|
|
||||||
|
|
||||||
Exhibit A - Source Code Form License Notice
|
|
||||||
|
|
||||||
This Source Code Form is subject to the
|
|
||||||
terms of the Mozilla Public License, v.
|
|
||||||
2.0. If a copy of the MPL was not
|
|
||||||
distributed with this file, You can
|
|
||||||
obtain one at
|
|
||||||
http://mozilla.org/MPL/2.0/.
|
|
||||||
|
|
||||||
If it is not possible or desirable to put the notice in a particular file, then
|
|
||||||
You may include the notice in a location (such as a LICENSE file in a relevant
|
|
||||||
directory) where a recipient would be likely to look for such a notice.
|
|
||||||
|
|
||||||
You may add additional accurate notices of copyright ownership.
|
|
||||||
|
|
||||||
Exhibit B - “Incompatible With Secondary Licenses” Notice
|
|
||||||
|
|
||||||
This Source Code Form is “Incompatible
|
|
||||||
With Secondary Licenses”, as defined by
|
|
||||||
the Mozilla Public License, v. 2.0.
|
|
97
vendor/github.com/hashicorp/go-multierror/README.md
generated
vendored
97
vendor/github.com/hashicorp/go-multierror/README.md
generated
vendored
@ -1,97 +0,0 @@
|
|||||||
# go-multierror
|
|
||||||
|
|
||||||
[][travis]
|
|
||||||
[][godocs]
|
|
||||||
|
|
||||||
[travis]: https://travis-ci.org/hashicorp/go-multierror
|
|
||||||
[godocs]: https://godoc.org/github.com/hashicorp/go-multierror
|
|
||||||
|
|
||||||
`go-multierror` is a package for Go that provides a mechanism for
|
|
||||||
representing a list of `error` values as a single `error`.
|
|
||||||
|
|
||||||
This allows a function in Go to return an `error` that might actually
|
|
||||||
be a list of errors. If the caller knows this, they can unwrap the
|
|
||||||
list and access the errors. If the caller doesn't know, the error
|
|
||||||
formats to a nice human-readable format.
|
|
||||||
|
|
||||||
`go-multierror` implements the
|
|
||||||
[errwrap](https://github.com/hashicorp/errwrap) interface so that it can
|
|
||||||
be used with that library, as well.
|
|
||||||
|
|
||||||
## Installation and Docs
|
|
||||||
|
|
||||||
Install using `go get github.com/hashicorp/go-multierror`.
|
|
||||||
|
|
||||||
Full documentation is available at
|
|
||||||
http://godoc.org/github.com/hashicorp/go-multierror
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
go-multierror is easy to use and purposely built to be unobtrusive in
|
|
||||||
existing Go applications/libraries that may not be aware of it.
|
|
||||||
|
|
||||||
**Building a list of errors**
|
|
||||||
|
|
||||||
The `Append` function is used to create a list of errors. This function
|
|
||||||
behaves a lot like the Go built-in `append` function: it doesn't matter
|
|
||||||
if the first argument is nil, a `multierror.Error`, or any other `error`,
|
|
||||||
the function behaves as you would expect.
|
|
||||||
|
|
||||||
```go
|
|
||||||
var result error
|
|
||||||
|
|
||||||
if err := step1(); err != nil {
|
|
||||||
result = multierror.Append(result, err)
|
|
||||||
}
|
|
||||||
if err := step2(); err != nil {
|
|
||||||
result = multierror.Append(result, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return result
|
|
||||||
```
|
|
||||||
|
|
||||||
**Customizing the formatting of the errors**
|
|
||||||
|
|
||||||
By specifying a custom `ErrorFormat`, you can customize the format
|
|
||||||
of the `Error() string` function:
|
|
||||||
|
|
||||||
```go
|
|
||||||
var result *multierror.Error
|
|
||||||
|
|
||||||
// ... accumulate errors here, maybe using Append
|
|
||||||
|
|
||||||
if result != nil {
|
|
||||||
result.ErrorFormat = func([]error) string {
|
|
||||||
return "errors!"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**Accessing the list of errors**
|
|
||||||
|
|
||||||
`multierror.Error` implements `error` so if the caller doesn't know about
|
|
||||||
multierror, it will work just fine. But if you're aware a multierror might
|
|
||||||
be returned, you can use type switches to access the list of errors:
|
|
||||||
|
|
||||||
```go
|
|
||||||
if err := something(); err != nil {
|
|
||||||
if merr, ok := err.(*multierror.Error); ok {
|
|
||||||
// Use merr.Errors
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**Returning a multierror only if there are errors**
|
|
||||||
|
|
||||||
If you build a `multierror.Error`, you can use the `ErrorOrNil` function
|
|
||||||
to return an `error` implementation only if there are errors to return:
|
|
||||||
|
|
||||||
```go
|
|
||||||
var result *multierror.Error
|
|
||||||
|
|
||||||
// ... accumulate errors here
|
|
||||||
|
|
||||||
// Return the `error` only if errors were added to the multierror, otherwise
|
|
||||||
// return nil since there are no errors.
|
|
||||||
return result.ErrorOrNil()
|
|
||||||
```
|
|
41
vendor/github.com/hashicorp/go-multierror/append.go
generated
vendored
41
vendor/github.com/hashicorp/go-multierror/append.go
generated
vendored
@ -1,41 +0,0 @@
|
|||||||
package multierror
|
|
||||||
|
|
||||||
// Append is a helper function that will append more errors
|
|
||||||
// onto an Error in order to create a larger multi-error.
|
|
||||||
//
|
|
||||||
// If err is not a multierror.Error, then it will be turned into
|
|
||||||
// one. If any of the errs are multierr.Error, they will be flattened
|
|
||||||
// one level into err.
|
|
||||||
func Append(err error, errs ...error) *Error {
|
|
||||||
switch err := err.(type) {
|
|
||||||
case *Error:
|
|
||||||
// Typed nils can reach here, so initialize if we are nil
|
|
||||||
if err == nil {
|
|
||||||
err = new(Error)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Go through each error and flatten
|
|
||||||
for _, e := range errs {
|
|
||||||
switch e := e.(type) {
|
|
||||||
case *Error:
|
|
||||||
if e != nil {
|
|
||||||
err.Errors = append(err.Errors, e.Errors...)
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
if e != nil {
|
|
||||||
err.Errors = append(err.Errors, e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return err
|
|
||||||
default:
|
|
||||||
newErrs := make([]error, 0, len(errs)+1)
|
|
||||||
if err != nil {
|
|
||||||
newErrs = append(newErrs, err)
|
|
||||||
}
|
|
||||||
newErrs = append(newErrs, errs...)
|
|
||||||
|
|
||||||
return Append(&Error{}, newErrs...)
|
|
||||||
}
|
|
||||||
}
|
|
26
vendor/github.com/hashicorp/go-multierror/flatten.go
generated
vendored
26
vendor/github.com/hashicorp/go-multierror/flatten.go
generated
vendored
@ -1,26 +0,0 @@
|
|||||||
package multierror
|
|
||||||
|
|
||||||
// Flatten flattens the given error, merging any *Errors together into
|
|
||||||
// a single *Error.
|
|
||||||
func Flatten(err error) error {
|
|
||||||
// If it isn't an *Error, just return the error as-is
|
|
||||||
if _, ok := err.(*Error); !ok {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Otherwise, make the result and flatten away!
|
|
||||||
flatErr := new(Error)
|
|
||||||
flatten(err, flatErr)
|
|
||||||
return flatErr
|
|
||||||
}
|
|
||||||
|
|
||||||
func flatten(err error, flatErr *Error) {
|
|
||||||
switch err := err.(type) {
|
|
||||||
case *Error:
|
|
||||||
for _, e := range err.Errors {
|
|
||||||
flatten(e, flatErr)
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
flatErr.Errors = append(flatErr.Errors, err)
|
|
||||||
}
|
|
||||||
}
|
|
27
vendor/github.com/hashicorp/go-multierror/format.go
generated
vendored
27
vendor/github.com/hashicorp/go-multierror/format.go
generated
vendored
@ -1,27 +0,0 @@
|
|||||||
package multierror
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ErrorFormatFunc is a function callback that is called by Error to
|
|
||||||
// turn the list of errors into a string.
|
|
||||||
type ErrorFormatFunc func([]error) string
|
|
||||||
|
|
||||||
// ListFormatFunc is a basic formatter that outputs the number of errors
|
|
||||||
// that occurred along with a bullet point list of the errors.
|
|
||||||
func ListFormatFunc(es []error) string {
|
|
||||||
if len(es) == 1 {
|
|
||||||
return fmt.Sprintf("1 error occurred:\n\n* %s", es[0])
|
|
||||||
}
|
|
||||||
|
|
||||||
points := make([]string, len(es))
|
|
||||||
for i, err := range es {
|
|
||||||
points[i] = fmt.Sprintf("* %s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return fmt.Sprintf(
|
|
||||||
"%d errors occurred:\n\n%s",
|
|
||||||
len(es), strings.Join(points, "\n"))
|
|
||||||
}
|
|
51
vendor/github.com/hashicorp/go-multierror/multierror.go
generated
vendored
51
vendor/github.com/hashicorp/go-multierror/multierror.go
generated
vendored
@ -1,51 +0,0 @@
|
|||||||
package multierror
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Error is an error type to track multiple errors. This is used to
|
|
||||||
// accumulate errors in cases and return them as a single "error".
|
|
||||||
type Error struct {
|
|
||||||
Errors []error
|
|
||||||
ErrorFormat ErrorFormatFunc
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *Error) Error() string {
|
|
||||||
fn := e.ErrorFormat
|
|
||||||
if fn == nil {
|
|
||||||
fn = ListFormatFunc
|
|
||||||
}
|
|
||||||
|
|
||||||
return fn(e.Errors)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ErrorOrNil returns an error interface if this Error represents
|
|
||||||
// a list of errors, or returns nil if the list of errors is empty. This
|
|
||||||
// function is useful at the end of accumulation to make sure that the value
|
|
||||||
// returned represents the existence of errors.
|
|
||||||
func (e *Error) ErrorOrNil() error {
|
|
||||||
if e == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
if len(e.Errors) == 0 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return e
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *Error) GoString() string {
|
|
||||||
return fmt.Sprintf("*%#v", *e)
|
|
||||||
}
|
|
||||||
|
|
||||||
// WrappedErrors returns the list of errors that this Error is wrapping.
|
|
||||||
// It is an implementatin of the errwrap.Wrapper interface so that
|
|
||||||
// multierror.Error can be used with that library.
|
|
||||||
//
|
|
||||||
// This method is not safe to be called concurrently and is no different
|
|
||||||
// than accessing the Errors field directly. It is implementd only to
|
|
||||||
// satisfy the errwrap.Wrapper interface.
|
|
||||||
func (e *Error) WrappedErrors() []error {
|
|
||||||
return e.Errors
|
|
||||||
}
|
|
37
vendor/github.com/hashicorp/go-multierror/prefix.go
generated
vendored
37
vendor/github.com/hashicorp/go-multierror/prefix.go
generated
vendored
@ -1,37 +0,0 @@
|
|||||||
package multierror
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/hashicorp/errwrap"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Prefix is a helper function that will prefix some text
|
|
||||||
// to the given error. If the error is a multierror.Error, then
|
|
||||||
// it will be prefixed to each wrapped error.
|
|
||||||
//
|
|
||||||
// This is useful to use when appending multiple multierrors
|
|
||||||
// together in order to give better scoping.
|
|
||||||
func Prefix(err error, prefix string) error {
|
|
||||||
if err == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
format := fmt.Sprintf("%s {{err}}", prefix)
|
|
||||||
switch err := err.(type) {
|
|
||||||
case *Error:
|
|
||||||
// Typed nils can reach here, so initialize if we are nil
|
|
||||||
if err == nil {
|
|
||||||
err = new(Error)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Wrap each of the errors
|
|
||||||
for i, e := range err.Errors {
|
|
||||||
err.Errors[i] = errwrap.Wrapf(format, e)
|
|
||||||
}
|
|
||||||
|
|
||||||
return err
|
|
||||||
default:
|
|
||||||
return errwrap.Wrapf(format, err)
|
|
||||||
}
|
|
||||||
}
|
|
191
vendor/github.com/opencontainers/runtime-tools/LICENSE
generated
vendored
191
vendor/github.com/opencontainers/runtime-tools/LICENSE
generated
vendored
@ -1,191 +0,0 @@
|
|||||||
|
|
||||||
Apache License
|
|
||||||
Version 2.0, January 2004
|
|
||||||
http://www.apache.org/licenses/
|
|
||||||
|
|
||||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
||||||
|
|
||||||
1. Definitions.
|
|
||||||
|
|
||||||
"License" shall mean the terms and conditions for use, reproduction,
|
|
||||||
and distribution as defined by Sections 1 through 9 of this document.
|
|
||||||
|
|
||||||
"Licensor" shall mean the copyright owner or entity authorized by
|
|
||||||
the copyright owner that is granting the License.
|
|
||||||
|
|
||||||
"Legal Entity" shall mean the union of the acting entity and all
|
|
||||||
other entities that control, are controlled by, or are under common
|
|
||||||
control with that entity. For the purposes of this definition,
|
|
||||||
"control" means (i) the power, direct or indirect, to cause the
|
|
||||||
direction or management of such entity, whether by contract or
|
|
||||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
||||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
||||||
|
|
||||||
"You" (or "Your") shall mean an individual or Legal Entity
|
|
||||||
exercising permissions granted by this License.
|
|
||||||
|
|
||||||
"Source" form shall mean the preferred form for making modifications,
|
|
||||||
including but not limited to software source code, documentation
|
|
||||||
source, and configuration files.
|
|
||||||
|
|
||||||
"Object" form shall mean any form resulting from mechanical
|
|
||||||
transformation or translation of a Source form, including but
|
|
||||||
not limited to compiled object code, generated documentation,
|
|
||||||
and conversions to other media types.
|
|
||||||
|
|
||||||
"Work" shall mean the work of authorship, whether in Source or
|
|
||||||
Object form, made available under the License, as indicated by a
|
|
||||||
copyright notice that is included in or attached to the work
|
|
||||||
(an example is provided in the Appendix below).
|
|
||||||
|
|
||||||
"Derivative Works" shall mean any work, whether in Source or Object
|
|
||||||
form, that is based on (or derived from) the Work and for which the
|
|
||||||
editorial revisions, annotations, elaborations, or other modifications
|
|
||||||
represent, as a whole, an original work of authorship. For the purposes
|
|
||||||
of this License, Derivative Works shall not include works that remain
|
|
||||||
separable from, or merely link (or bind by name) to the interfaces of,
|
|
||||||
the Work and Derivative Works thereof.
|
|
||||||
|
|
||||||
"Contribution" shall mean any work of authorship, including
|
|
||||||
the original version of the Work and any modifications or additions
|
|
||||||
to that Work or Derivative Works thereof, that is intentionally
|
|
||||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
|
||||||
or by an individual or Legal Entity authorized to submit on behalf of
|
|
||||||
the copyright owner. For the purposes of this definition, "submitted"
|
|
||||||
means any form of electronic, verbal, or written communication sent
|
|
||||||
to the Licensor or its representatives, including but not limited to
|
|
||||||
communication on electronic mailing lists, source code control systems,
|
|
||||||
and issue tracking systems that are managed by, or on behalf of, the
|
|
||||||
Licensor for the purpose of discussing and improving the Work, but
|
|
||||||
excluding communication that is conspicuously marked or otherwise
|
|
||||||
designated in writing by the copyright owner as "Not a Contribution."
|
|
||||||
|
|
||||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
||||||
on behalf of whom a Contribution has been received by Licensor and
|
|
||||||
subsequently incorporated within the Work.
|
|
||||||
|
|
||||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
||||||
this License, each Contributor hereby grants to You a perpetual,
|
|
||||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
||||||
copyright license to reproduce, prepare Derivative Works of,
|
|
||||||
publicly display, publicly perform, sublicense, and distribute the
|
|
||||||
Work and such Derivative Works in Source or Object form.
|
|
||||||
|
|
||||||
3. Grant of Patent License. Subject to the terms and conditions of
|
|
||||||
this License, each Contributor hereby grants to You a perpetual,
|
|
||||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
||||||
(except as stated in this section) patent license to make, have made,
|
|
||||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
||||||
where such license applies only to those patent claims licensable
|
|
||||||
by such Contributor that are necessarily infringed by their
|
|
||||||
Contribution(s) alone or by combination of their Contribution(s)
|
|
||||||
with the Work to which such Contribution(s) was submitted. If You
|
|
||||||
institute patent litigation against any entity (including a
|
|
||||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
||||||
or a Contribution incorporated within the Work constitutes direct
|
|
||||||
or contributory patent infringement, then any patent licenses
|
|
||||||
granted to You under this License for that Work shall terminate
|
|
||||||
as of the date such litigation is filed.
|
|
||||||
|
|
||||||
4. Redistribution. You may reproduce and distribute copies of the
|
|
||||||
Work or Derivative Works thereof in any medium, with or without
|
|
||||||
modifications, and in Source or Object form, provided that You
|
|
||||||
meet the following conditions:
|
|
||||||
|
|
||||||
(a) You must give any other recipients of the Work or
|
|
||||||
Derivative Works a copy of this License; and
|
|
||||||
|
|
||||||
(b) You must cause any modified files to carry prominent notices
|
|
||||||
stating that You changed the files; and
|
|
||||||
|
|
||||||
(c) You must retain, in the Source form of any Derivative Works
|
|
||||||
that You distribute, all copyright, patent, trademark, and
|
|
||||||
attribution notices from the Source form of the Work,
|
|
||||||
excluding those notices that do not pertain to any part of
|
|
||||||
the Derivative Works; and
|
|
||||||
|
|
||||||
(d) If the Work includes a "NOTICE" text file as part of its
|
|
||||||
distribution, then any Derivative Works that You distribute must
|
|
||||||
include a readable copy of the attribution notices contained
|
|
||||||
within such NOTICE file, excluding those notices that do not
|
|
||||||
pertain to any part of the Derivative Works, in at least one
|
|
||||||
of the following places: within a NOTICE text file distributed
|
|
||||||
as part of the Derivative Works; within the Source form or
|
|
||||||
documentation, if provided along with the Derivative Works; or,
|
|
||||||
within a display generated by the Derivative Works, if and
|
|
||||||
wherever such third-party notices normally appear. The contents
|
|
||||||
of the NOTICE file are for informational purposes only and
|
|
||||||
do not modify the License. You may add Your own attribution
|
|
||||||
notices within Derivative Works that You distribute, alongside
|
|
||||||
or as an addendum to the NOTICE text from the Work, provided
|
|
||||||
that such additional attribution notices cannot be construed
|
|
||||||
as modifying the License.
|
|
||||||
|
|
||||||
You may add Your own copyright statement to Your modifications and
|
|
||||||
may provide additional or different license terms and conditions
|
|
||||||
for use, reproduction, or distribution of Your modifications, or
|
|
||||||
for any such Derivative Works as a whole, provided Your use,
|
|
||||||
reproduction, and distribution of the Work otherwise complies with
|
|
||||||
the conditions stated in this License.
|
|
||||||
|
|
||||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
||||||
any Contribution intentionally submitted for inclusion in the Work
|
|
||||||
by You to the Licensor shall be under the terms and conditions of
|
|
||||||
this License, without any additional terms or conditions.
|
|
||||||
Notwithstanding the above, nothing herein shall supersede or modify
|
|
||||||
the terms of any separate license agreement you may have executed
|
|
||||||
with Licensor regarding such Contributions.
|
|
||||||
|
|
||||||
6. Trademarks. This License does not grant permission to use the trade
|
|
||||||
names, trademarks, service marks, or product names of the Licensor,
|
|
||||||
except as required for reasonable and customary use in describing the
|
|
||||||
origin of the Work and reproducing the content of the NOTICE file.
|
|
||||||
|
|
||||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
||||||
agreed to in writing, Licensor provides the Work (and each
|
|
||||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
||||||
implied, including, without limitation, any warranties or conditions
|
|
||||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
||||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
||||||
appropriateness of using or redistributing the Work and assume any
|
|
||||||
risks associated with Your exercise of permissions under this License.
|
|
||||||
|
|
||||||
8. Limitation of Liability. In no event and under no legal theory,
|
|
||||||
whether in tort (including negligence), contract, or otherwise,
|
|
||||||
unless required by applicable law (such as deliberate and grossly
|
|
||||||
negligent acts) or agreed to in writing, shall any Contributor be
|
|
||||||
liable to You for damages, including any direct, indirect, special,
|
|
||||||
incidental, or consequential damages of any character arising as a
|
|
||||||
result of this License or out of the use or inability to use the
|
|
||||||
Work (including but not limited to damages for loss of goodwill,
|
|
||||||
work stoppage, computer failure or malfunction, or any and all
|
|
||||||
other commercial damages or losses), even if such Contributor
|
|
||||||
has been advised of the possibility of such damages.
|
|
||||||
|
|
||||||
9. Accepting Warranty or Additional Liability. While redistributing
|
|
||||||
the Work or Derivative Works thereof, You may choose to offer,
|
|
||||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
||||||
or other liability obligations and/or rights consistent with this
|
|
||||||
License. However, in accepting such obligations, You may act only
|
|
||||||
on Your own behalf and on Your sole responsibility, not on behalf
|
|
||||||
of any other Contributor, and only if You agree to indemnify,
|
|
||||||
defend, and hold each Contributor harmless for any liability
|
|
||||||
incurred by, or claims asserted against, such Contributor by reason
|
|
||||||
of your accepting any such warranty or additional liability.
|
|
||||||
|
|
||||||
END OF TERMS AND CONDITIONS
|
|
||||||
|
|
||||||
Copyright 2015 The Linux Foundation.
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
128
vendor/github.com/opencontainers/runtime-tools/README.md
generated
vendored
128
vendor/github.com/opencontainers/runtime-tools/README.md
generated
vendored
@ -1,128 +0,0 @@
|
|||||||
# oci-runtime-tool [](https://travis-ci.org/opencontainers/runtime-tools) [](https://goreportcard.com/report/github.com/opencontainers/runtime-tools)
|
|
||||||
|
|
||||||
oci-runtime-tool is a collection of tools for working with the [OCI runtime specification][runtime-spec].
|
|
||||||
To build from source code, runtime-tools requires Go 1.7.x or above.
|
|
||||||
|
|
||||||
## Generating an OCI runtime spec configuration files
|
|
||||||
|
|
||||||
[`oci-runtime-tool generate`][generate.1] generates [configuration JSON][config.json] for an [OCI bundle][bundle].
|
|
||||||
[OCI-compatible runtimes][runtime-spec] like [runC][] expect to read the configuration from `config.json`.
|
|
||||||
|
|
||||||
```console
|
|
||||||
$ oci-runtime-tool generate --output config.json
|
|
||||||
$ cat config.json
|
|
||||||
{
|
|
||||||
"ociVersion": "0.5.0",
|
|
||||||
…
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Validating an OCI bundle
|
|
||||||
|
|
||||||
[`oci-runtime-tool validate`][validate.1] validates an OCI bundle.
|
|
||||||
The error message will be printed if the OCI bundle failed the validation procedure.
|
|
||||||
|
|
||||||
```console
|
|
||||||
$ oci-runtime-tool generate
|
|
||||||
$ oci-runtime-tool validate
|
|
||||||
INFO[0000] Bundle validation succeeded.
|
|
||||||
```
|
|
||||||
|
|
||||||
## Testing OCI runtimes
|
|
||||||
|
|
||||||
The runtime validation suite uses [node-tap][], which is packaged for some distributions (for example, it is in [Debian's `node-tap` package][debian-node-tap]).
|
|
||||||
If your distribution does not package node-tap, you can install [npm][] (for example, from [Gentoo's `nodejs` package][gentoo-nodejs]) and use it:
|
|
||||||
|
|
||||||
```console
|
|
||||||
$ npm install tap
|
|
||||||
```
|
|
||||||
|
|
||||||
Build the validation executables:
|
|
||||||
|
|
||||||
```console
|
|
||||||
$ make runtimetest validation-executables
|
|
||||||
```
|
|
||||||
|
|
||||||
Runtime validation currently [only supports](docs/runtime-compliance-testing.md) the [OCI Runtime Command Line Interface](docs/command-line-interface.md).
|
|
||||||
If we add support for alternative APIs in the future, runtime validation will gain an option to select the desired runtime API.
|
|
||||||
For the command line interface, the `RUNTIME` option selects the runtime command (`funC` in the [OCI Runtime Command Line Interface](docs/command-line-interface.md)).
|
|
||||||
|
|
||||||
```
|
|
||||||
$ sudo make RUNTIME=runc localvalidation
|
|
||||||
RUNTIME=runc tap validation/pidfile.t validation/linux_cgroups_hugetlb.t validation/linux_cgroups_memory.t validation/linux_rootfs_propagation_shared.t validation/kill.t validation/create.t validation/poststart.t validation/linux_cgroups_network.t validation/poststop_fail.t validation/linux_readonly_paths.t validation/prestart_fail.t validation/hooks_stdin.t validation/default.t validation/linux_masked_paths.t validation/poststop.t validation/misc_props.t validation/prestart.t validation/poststart_fail.t validation/mounts.t validation/linux_cgroups_relative_pids.t validation/process_user.t validation/process.t validation/hooks.t validation/process_capabilities_fail.t validation/process_rlimits_fail.t validation/linux_cgroups_relative_cpus.t validation/process_rlimits.t validation/linux_cgroups_relative_blkio.t validation/linux_sysctl.t validation/linux_seccomp.t validation/linux_devices.t validation/start.t validation/linux_cgroups_pids.t validation/process_capabilities.t validation/process_oom_score_adj.t validation/linux_cgroups_relative_hugetlb.t validation/linux_cgroups_cpus.t validation/linux_cgroups_relative_memory.t validation/state.t validation/root_readonly_true.t validation/linux_cgroups_blkio.t validation/linux_rootfs_propagation_unbindable.t validation/delete.t validation/linux_cgroups_relative_network.t validation/hostname.t validation/killsig.t validation/linux_uid_mappings.t
|
|
||||||
validation/pidfile.t .failed to create the container
|
|
||||||
container_linux.go:348: starting container process caused "process_linux.go:402: container init caused \"process_linux.go:367: setting cgroup config for procHooks process caused \\\"failed to write 56892210544640 to hugetlb.1GB.limit_in_bytes: open /sys/fs/cgroup/hugetlb/cgrouptest/hugetlb.1GB.limit_in_bytes: permission denied\\\"\""
|
|
||||||
exit status 1
|
|
||||||
validation/pidfile.t .................................. 1/1 315ms
|
|
||||||
validation/linux_cgroups_hugetlb.t .................... 0/1
|
|
||||||
not ok validation/linux_cgroups_hugetlb.t
|
|
||||||
timeout: 30000
|
|
||||||
file: validation/linux_cgroups_hugetlb.t
|
|
||||||
command: validation/linux_cgroups_hugetlb.t
|
|
||||||
args: []
|
|
||||||
stdio:
|
|
||||||
- 0
|
|
||||||
- pipe
|
|
||||||
- 2
|
|
||||||
cwd: /…/go/src/github.com/opencontainers/runtime-tools
|
|
||||||
exitCode: 1
|
|
||||||
|
|
||||||
validation/linux_cgroups_memory.t ..................... 9/9
|
|
||||||
validation/linux_rootfs_propagation_shared.t ...... 252/282
|
|
||||||
not ok shared root propagation exposes "/target348456609/mount892511628/example376408222"
|
|
||||||
|
|
||||||
Skipped: 29
|
|
||||||
/dev/null (default device) has unconfigured permissions
|
|
||||||
…
|
|
||||||
total ........................................... 4381/4962
|
|
||||||
|
|
||||||
|
|
||||||
4381 passing (1m)
|
|
||||||
567 pending
|
|
||||||
14 failing
|
|
||||||
|
|
||||||
make: *** [Makefile:44: localvalidation] Error 1
|
|
||||||
```
|
|
||||||
|
|
||||||
You can also run an individual test executable directly:
|
|
||||||
|
|
||||||
```console
|
|
||||||
$ RUNTIME=runc validation/default.t
|
|
||||||
TAP version 13
|
|
||||||
ok 1 - has expected hostname
|
|
||||||
---
|
|
||||||
{
|
|
||||||
"actual": "mrsdalloway",
|
|
||||||
"expected": "mrsdalloway"
|
|
||||||
}
|
|
||||||
...
|
|
||||||
…
|
|
||||||
ok 287 # SKIP linux.gidMappings not set
|
|
||||||
1..287
|
|
||||||
```
|
|
||||||
|
|
||||||
If you cannot install node-tap, you can probably run the test suite with another [TAP consumer][tap-consumers].
|
|
||||||
For example, with [`prove`][prove]:
|
|
||||||
|
|
||||||
```console
|
|
||||||
$ sudo make TAP='prove -Q -j9' RUNTIME=runc VALIDATION_TESTS=validation/pidfile.t localvalidation
|
|
||||||
RUNTIME=runc prove -Q -j9 validation/pidfile.t
|
|
||||||
All tests successful.
|
|
||||||
Files=1, Tests=1, 0 wallclock secs ( 0.01 usr 0.01 sys + 0.03 cusr 0.03 csys = 0.08 CPU)
|
|
||||||
Result: PASS
|
|
||||||
```
|
|
||||||
|
|
||||||
[bundle]: https://github.com/opencontainers/runtime-spec/blob/master/bundle.md
|
|
||||||
[config.json]: https://github.com/opencontainers/runtime-spec/blob/master/config.md
|
|
||||||
[debian-node-tap]: https://packages.debian.org/stretch/node-tap
|
|
||||||
[debian-nodejs]: https://packages.debian.org/stretch/nodejs
|
|
||||||
[gentoo-nodejs]: https://packages.gentoo.org/packages/net-libs/nodejs
|
|
||||||
[node-tap]: http://www.node-tap.org/
|
|
||||||
[npm]: https://www.npmjs.com/
|
|
||||||
[prove]: http://search.cpan.org/~leont/Test-Harness-3.39/bin/prove
|
|
||||||
[runC]: https://github.com/opencontainers/runc
|
|
||||||
[runtime-spec]: https://github.com/opencontainers/runtime-spec
|
|
||||||
[tap-consumers]: https://testanything.org/consumers.html
|
|
||||||
|
|
||||||
[generate.1]: man/oci-runtime-tool-generate.1.md
|
|
||||||
[validate.1]: man/oci-runtime-tool-validate.1.md
|
|
122
vendor/github.com/opencontainers/runtime-tools/error/error.go
generated
vendored
122
vendor/github.com/opencontainers/runtime-tools/error/error.go
generated
vendored
@ -1,122 +0,0 @@
|
|||||||
// Package error implements generic tooling for tracking RFC 2119
|
|
||||||
// violations and linking back to the appropriate specification section.
|
|
||||||
package error
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Level represents the RFC 2119 compliance levels
|
|
||||||
type Level int
|
|
||||||
|
|
||||||
const (
|
|
||||||
// MAY-level
|
|
||||||
|
|
||||||
// May represents 'MAY' in RFC 2119.
|
|
||||||
May Level = iota
|
|
||||||
// Optional represents 'OPTIONAL' in RFC 2119.
|
|
||||||
Optional
|
|
||||||
|
|
||||||
// SHOULD-level
|
|
||||||
|
|
||||||
// Should represents 'SHOULD' in RFC 2119.
|
|
||||||
Should
|
|
||||||
// ShouldNot represents 'SHOULD NOT' in RFC 2119.
|
|
||||||
ShouldNot
|
|
||||||
// Recommended represents 'RECOMMENDED' in RFC 2119.
|
|
||||||
Recommended
|
|
||||||
// NotRecommended represents 'NOT RECOMMENDED' in RFC 2119.
|
|
||||||
NotRecommended
|
|
||||||
|
|
||||||
// MUST-level
|
|
||||||
|
|
||||||
// Must represents 'MUST' in RFC 2119
|
|
||||||
Must
|
|
||||||
// MustNot represents 'MUST NOT' in RFC 2119.
|
|
||||||
MustNot
|
|
||||||
// Shall represents 'SHALL' in RFC 2119.
|
|
||||||
Shall
|
|
||||||
// ShallNot represents 'SHALL NOT' in RFC 2119.
|
|
||||||
ShallNot
|
|
||||||
// Required represents 'REQUIRED' in RFC 2119.
|
|
||||||
Required
|
|
||||||
)
|
|
||||||
|
|
||||||
// Error represents an error with compliance level and specification reference.
|
|
||||||
type Error struct {
|
|
||||||
// Level represents the RFC 2119 compliance level.
|
|
||||||
Level Level
|
|
||||||
|
|
||||||
// Reference is a URL for the violated specification requirement.
|
|
||||||
Reference string
|
|
||||||
|
|
||||||
// Err holds additional details about the violation.
|
|
||||||
Err error
|
|
||||||
}
|
|
||||||
|
|
||||||
// ParseLevel takes a string level and returns the RFC 2119 compliance level constant.
|
|
||||||
func ParseLevel(level string) (Level, error) {
|
|
||||||
switch strings.ToUpper(level) {
|
|
||||||
case "MAY":
|
|
||||||
fallthrough
|
|
||||||
case "OPTIONAL":
|
|
||||||
return May, nil
|
|
||||||
case "SHOULD":
|
|
||||||
fallthrough
|
|
||||||
case "SHOULDNOT":
|
|
||||||
fallthrough
|
|
||||||
case "RECOMMENDED":
|
|
||||||
fallthrough
|
|
||||||
case "NOTRECOMMENDED":
|
|
||||||
return Should, nil
|
|
||||||
case "MUST":
|
|
||||||
fallthrough
|
|
||||||
case "MUSTNOT":
|
|
||||||
fallthrough
|
|
||||||
case "SHALL":
|
|
||||||
fallthrough
|
|
||||||
case "SHALLNOT":
|
|
||||||
fallthrough
|
|
||||||
case "REQUIRED":
|
|
||||||
return Must, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
var l Level
|
|
||||||
return l, fmt.Errorf("%q is not a valid compliance level", level)
|
|
||||||
}
|
|
||||||
|
|
||||||
// String takes a RFC 2119 compliance level constant and returns a string representation.
|
|
||||||
func (level Level) String() string {
|
|
||||||
switch level {
|
|
||||||
case May:
|
|
||||||
return "MAY"
|
|
||||||
case Optional:
|
|
||||||
return "OPTIONAL"
|
|
||||||
case Should:
|
|
||||||
return "SHOULD"
|
|
||||||
case ShouldNot:
|
|
||||||
return "SHOULD NOT"
|
|
||||||
case Recommended:
|
|
||||||
return "RECOMMENDED"
|
|
||||||
case NotRecommended:
|
|
||||||
return "NOT RECOMMENDED"
|
|
||||||
case Must:
|
|
||||||
return "MUST"
|
|
||||||
case MustNot:
|
|
||||||
return "MUST NOT"
|
|
||||||
case Shall:
|
|
||||||
return "SHALL"
|
|
||||||
case ShallNot:
|
|
||||||
return "SHALL NOT"
|
|
||||||
case Required:
|
|
||||||
return "REQUIRED"
|
|
||||||
}
|
|
||||||
|
|
||||||
panic(fmt.Sprintf("%d is not a valid compliance level", level))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Error returns the error message with specification reference.
|
|
||||||
func (err *Error) Error() string {
|
|
||||||
return fmt.Sprintf("%s\nRefer to: %s", err.Err.Error(), err.Reference)
|
|
||||||
}
|
|
48
vendor/github.com/opencontainers/runtime-tools/filepath/abs.go
generated
vendored
48
vendor/github.com/opencontainers/runtime-tools/filepath/abs.go
generated
vendored
@ -1,48 +0,0 @@
|
|||||||
package filepath
|
|
||||||
|
|
||||||
import (
|
|
||||||
"regexp"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
var windowsAbs = regexp.MustCompile(`^[a-zA-Z]:\\.*$`)
|
|
||||||
|
|
||||||
// Abs is a version of path/filepath's Abs with an explicit operating
|
|
||||||
// system and current working directory.
|
|
||||||
func Abs(os, path, cwd string) (_ string, err error) {
|
|
||||||
if IsAbs(os, path) {
|
|
||||||
return Clean(os, path), nil
|
|
||||||
}
|
|
||||||
return Clean(os, Join(os, cwd, path)), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsAbs is a version of path/filepath's IsAbs with an explicit
|
|
||||||
// operating system.
|
|
||||||
func IsAbs(os, path string) bool {
|
|
||||||
if os == "windows" {
|
|
||||||
// FIXME: copy hideous logic from Go's
|
|
||||||
// src/path/filepath/path_windows.go into somewhere where we can
|
|
||||||
// put 3-clause BSD licensed code.
|
|
||||||
return windowsAbs.MatchString(path)
|
|
||||||
}
|
|
||||||
sep := Separator(os)
|
|
||||||
|
|
||||||
// POSIX has [1]:
|
|
||||||
//
|
|
||||||
// > If a pathname begins with two successive <slash> characters,
|
|
||||||
// > the first component following the leading <slash> characters
|
|
||||||
// > may be interpreted in an implementation-defined manner,
|
|
||||||
// > although more than two leading <slash> characters shall be
|
|
||||||
// > treated as a single <slash> character.
|
|
||||||
//
|
|
||||||
// And Boost treats // as non-absolute [2], but Linux [3,4], Python
|
|
||||||
// [5] and Go [6] all treat // as absolute.
|
|
||||||
//
|
|
||||||
// [1]: http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_13
|
|
||||||
// [2]: https://github.com/boostorg/filesystem/blob/boost-1.64.0/test/path_test.cpp#L861
|
|
||||||
// [3]: http://man7.org/linux/man-pages/man7/path_resolution.7.html
|
|
||||||
// [4]: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/filesystems/path-lookup.md?h=v4.12#n41
|
|
||||||
// [5]: https://github.com/python/cpython/blob/v3.6.1/Lib/posixpath.py#L64-L66
|
|
||||||
// [6]: https://go.googlesource.com/go/+/go1.8.3/src/path/path.go#199
|
|
||||||
return strings.HasPrefix(path, string(sep))
|
|
||||||
}
|
|
32
vendor/github.com/opencontainers/runtime-tools/filepath/ancestor.go
generated
vendored
32
vendor/github.com/opencontainers/runtime-tools/filepath/ancestor.go
generated
vendored
@ -1,32 +0,0 @@
|
|||||||
package filepath
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
// IsAncestor returns true when pathB is an strict ancestor of pathA,
|
|
||||||
// and false where the paths are equal or pathB is outside of pathA.
|
|
||||||
// Paths that are not absolute will be made absolute with Abs.
|
|
||||||
func IsAncestor(os, pathA, pathB, cwd string) (_ bool, err error) {
|
|
||||||
if pathA == pathB {
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
pathA, err = Abs(os, pathA, cwd)
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
pathB, err = Abs(os, pathB, cwd)
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
sep := Separator(os)
|
|
||||||
if !strings.HasSuffix(pathA, string(sep)) {
|
|
||||||
pathA = fmt.Sprintf("%s%c", pathA, sep)
|
|
||||||
}
|
|
||||||
if pathA == pathB {
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
return strings.HasPrefix(pathB, pathA), nil
|
|
||||||
}
|
|
74
vendor/github.com/opencontainers/runtime-tools/filepath/clean.go
generated
vendored
74
vendor/github.com/opencontainers/runtime-tools/filepath/clean.go
generated
vendored
@ -1,74 +0,0 @@
|
|||||||
package filepath
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Clean is an explicit-OS version of path/filepath's Clean.
|
|
||||||
func Clean(os, path string) string {
|
|
||||||
abs := IsAbs(os, path)
|
|
||||||
sep := Separator(os)
|
|
||||||
elements := strings.Split(path, string(sep))
|
|
||||||
|
|
||||||
// Replace multiple Separator elements with a single one.
|
|
||||||
for i := 0; i < len(elements); i++ {
|
|
||||||
if len(elements[i]) == 0 {
|
|
||||||
elements = append(elements[:i], elements[i+1:]...)
|
|
||||||
i--
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Eliminate each . path name element (the current directory).
|
|
||||||
for i := 0; i < len(elements); i++ {
|
|
||||||
if elements[i] == "." && len(elements) > 1 {
|
|
||||||
elements = append(elements[:i], elements[i+1:]...)
|
|
||||||
i--
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Eliminate each inner .. path name element (the parent directory)
|
|
||||||
// along with the non-.. element that precedes it.
|
|
||||||
for i := 1; i < len(elements); i++ {
|
|
||||||
if i == 1 && abs && sep == '\\' {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if i > 0 && elements[i] == ".." {
|
|
||||||
elements = append(elements[:i-1], elements[i+1:]...)
|
|
||||||
i -= 2
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Eliminate .. elements that begin a rooted path:
|
|
||||||
// that is, replace "/.." by "/" at the beginning of a path,
|
|
||||||
// assuming Separator is '/'.
|
|
||||||
offset := 0
|
|
||||||
if sep == '\\' {
|
|
||||||
offset = 1
|
|
||||||
}
|
|
||||||
if abs {
|
|
||||||
for len(elements) > offset && elements[offset] == ".." {
|
|
||||||
elements = append(elements[:offset], elements[offset+1:]...)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cleaned := strings.Join(elements, string(sep))
|
|
||||||
if abs {
|
|
||||||
if sep == '/' {
|
|
||||||
cleaned = fmt.Sprintf("%c%s", sep, cleaned)
|
|
||||||
} else if len(elements) == 1 {
|
|
||||||
cleaned = fmt.Sprintf("%s%c", cleaned, sep)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the result of this process is an empty string, Clean returns
|
|
||||||
// the string ".".
|
|
||||||
if len(cleaned) == 0 {
|
|
||||||
cleaned = "."
|
|
||||||
}
|
|
||||||
|
|
||||||
if cleaned == path {
|
|
||||||
return path
|
|
||||||
}
|
|
||||||
return Clean(os, cleaned)
|
|
||||||
}
|
|
6
vendor/github.com/opencontainers/runtime-tools/filepath/doc.go
generated
vendored
6
vendor/github.com/opencontainers/runtime-tools/filepath/doc.go
generated
vendored
@ -1,6 +0,0 @@
|
|||||||
// Package filepath implements Go's filepath package with explicit
|
|
||||||
// operating systems (and for some functions and explicit working
|
|
||||||
// directory). This allows tools built for one OS to operate on paths
|
|
||||||
// targeting another OS. For example, a Linux build can determine
|
|
||||||
// whether a path is absolute on Linux or on Windows.
|
|
||||||
package filepath
|
|
9
vendor/github.com/opencontainers/runtime-tools/filepath/join.go
generated
vendored
9
vendor/github.com/opencontainers/runtime-tools/filepath/join.go
generated
vendored
@ -1,9 +0,0 @@
|
|||||||
package filepath
|
|
||||||
|
|
||||||
import "strings"
|
|
||||||
|
|
||||||
// Join is an explicit-OS version of path/filepath's Join.
|
|
||||||
func Join(os string, elem ...string) string {
|
|
||||||
sep := Separator(os)
|
|
||||||
return Clean(os, strings.Join(elem, string(sep)))
|
|
||||||
}
|
|
9
vendor/github.com/opencontainers/runtime-tools/filepath/separator.go
generated
vendored
9
vendor/github.com/opencontainers/runtime-tools/filepath/separator.go
generated
vendored
@ -1,9 +0,0 @@
|
|||||||
package filepath
|
|
||||||
|
|
||||||
// Separator is an explicit-OS version of path/filepath's Separator.
|
|
||||||
func Separator(os string) rune {
|
|
||||||
if os == "windows" {
|
|
||||||
return '\\'
|
|
||||||
}
|
|
||||||
return '/'
|
|
||||||
}
|
|
173
vendor/github.com/opencontainers/runtime-tools/generate/config.go
generated
vendored
173
vendor/github.com/opencontainers/runtime-tools/generate/config.go
generated
vendored
@ -1,173 +0,0 @@
|
|||||||
package generate
|
|
||||||
|
|
||||||
import (
|
|
||||||
rspec "github.com/opencontainers/runtime-spec/specs-go"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (g *Generator) initConfig() {
|
|
||||||
if g.Config == nil {
|
|
||||||
g.Config = &rspec.Spec{}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (g *Generator) initConfigProcess() {
|
|
||||||
g.initConfig()
|
|
||||||
if g.Config.Process == nil {
|
|
||||||
g.Config.Process = &rspec.Process{}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (g *Generator) initConfigProcessConsoleSize() {
|
|
||||||
g.initConfigProcess()
|
|
||||||
if g.Config.Process.ConsoleSize == nil {
|
|
||||||
g.Config.Process.ConsoleSize = &rspec.Box{}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (g *Generator) initConfigProcessCapabilities() {
|
|
||||||
g.initConfigProcess()
|
|
||||||
if g.Config.Process.Capabilities == nil {
|
|
||||||
g.Config.Process.Capabilities = &rspec.LinuxCapabilities{}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (g *Generator) initConfigRoot() {
|
|
||||||
g.initConfig()
|
|
||||||
if g.Config.Root == nil {
|
|
||||||
g.Config.Root = &rspec.Root{}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (g *Generator) initConfigAnnotations() {
|
|
||||||
g.initConfig()
|
|
||||||
if g.Config.Annotations == nil {
|
|
||||||
g.Config.Annotations = make(map[string]string)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (g *Generator) initConfigHooks() {
|
|
||||||
g.initConfig()
|
|
||||||
if g.Config.Hooks == nil {
|
|
||||||
g.Config.Hooks = &rspec.Hooks{}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (g *Generator) initConfigLinux() {
|
|
||||||
g.initConfig()
|
|
||||||
if g.Config.Linux == nil {
|
|
||||||
g.Config.Linux = &rspec.Linux{}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (g *Generator) initConfigLinuxIntelRdt() {
|
|
||||||
g.initConfigLinux()
|
|
||||||
if g.Config.Linux.IntelRdt == nil {
|
|
||||||
g.Config.Linux.IntelRdt = &rspec.LinuxIntelRdt{}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (g *Generator) initConfigLinuxSysctl() {
|
|
||||||
g.initConfigLinux()
|
|
||||||
if g.Config.Linux.Sysctl == nil {
|
|
||||||
g.Config.Linux.Sysctl = make(map[string]string)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (g *Generator) initConfigLinuxSeccomp() {
|
|
||||||
g.initConfigLinux()
|
|
||||||
if g.Config.Linux.Seccomp == nil {
|
|
||||||
g.Config.Linux.Seccomp = &rspec.LinuxSeccomp{}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (g *Generator) initConfigLinuxResources() {
|
|
||||||
g.initConfigLinux()
|
|
||||||
if g.Config.Linux.Resources == nil {
|
|
||||||
g.Config.Linux.Resources = &rspec.LinuxResources{}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (g *Generator) initConfigLinuxResourcesBlockIO() {
|
|
||||||
g.initConfigLinuxResources()
|
|
||||||
if g.Config.Linux.Resources.BlockIO == nil {
|
|
||||||
g.Config.Linux.Resources.BlockIO = &rspec.LinuxBlockIO{}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// InitConfigLinuxResourcesCPU initializes CPU of Linux resources
|
|
||||||
func (g *Generator) InitConfigLinuxResourcesCPU() {
|
|
||||||
g.initConfigLinuxResources()
|
|
||||||
if g.Config.Linux.Resources.CPU == nil {
|
|
||||||
g.Config.Linux.Resources.CPU = &rspec.LinuxCPU{}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (g *Generator) initConfigLinuxResourcesMemory() {
|
|
||||||
g.initConfigLinuxResources()
|
|
||||||
if g.Config.Linux.Resources.Memory == nil {
|
|
||||||
g.Config.Linux.Resources.Memory = &rspec.LinuxMemory{}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (g *Generator) initConfigLinuxResourcesNetwork() {
|
|
||||||
g.initConfigLinuxResources()
|
|
||||||
if g.Config.Linux.Resources.Network == nil {
|
|
||||||
g.Config.Linux.Resources.Network = &rspec.LinuxNetwork{}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (g *Generator) initConfigLinuxResourcesPids() {
|
|
||||||
g.initConfigLinuxResources()
|
|
||||||
if g.Config.Linux.Resources.Pids == nil {
|
|
||||||
g.Config.Linux.Resources.Pids = &rspec.LinuxPids{}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (g *Generator) initConfigSolaris() {
|
|
||||||
g.initConfig()
|
|
||||||
if g.Config.Solaris == nil {
|
|
||||||
g.Config.Solaris = &rspec.Solaris{}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (g *Generator) initConfigSolarisCappedCPU() {
|
|
||||||
g.initConfigSolaris()
|
|
||||||
if g.Config.Solaris.CappedCPU == nil {
|
|
||||||
g.Config.Solaris.CappedCPU = &rspec.SolarisCappedCPU{}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (g *Generator) initConfigSolarisCappedMemory() {
|
|
||||||
g.initConfigSolaris()
|
|
||||||
if g.Config.Solaris.CappedMemory == nil {
|
|
||||||
g.Config.Solaris.CappedMemory = &rspec.SolarisCappedMemory{}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (g *Generator) initConfigWindows() {
|
|
||||||
g.initConfig()
|
|
||||||
if g.Config.Windows == nil {
|
|
||||||
g.Config.Windows = &rspec.Windows{}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (g *Generator) initConfigWindowsHyperV() {
|
|
||||||
g.initConfigWindows()
|
|
||||||
if g.Config.Windows.HyperV == nil {
|
|
||||||
g.Config.Windows.HyperV = &rspec.WindowsHyperV{}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (g *Generator) initConfigWindowsResources() {
|
|
||||||
g.initConfigWindows()
|
|
||||||
if g.Config.Windows.Resources == nil {
|
|
||||||
g.Config.Windows.Resources = &rspec.WindowsResources{}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (g *Generator) initConfigWindowsResourcesMemory() {
|
|
||||||
g.initConfigWindowsResources()
|
|
||||||
if g.Config.Windows.Resources.Memory == nil {
|
|
||||||
g.Config.Windows.Resources.Memory = &rspec.WindowsMemoryResources{}
|
|
||||||
}
|
|
||||||
}
|
|
1568
vendor/github.com/opencontainers/runtime-tools/generate/generate.go
generated
vendored
1568
vendor/github.com/opencontainers/runtime-tools/generate/generate.go
generated
vendored
File diff suppressed because it is too large
Load Diff
12
vendor/github.com/opencontainers/runtime-tools/generate/seccomp/consts.go
generated
vendored
12
vendor/github.com/opencontainers/runtime-tools/generate/seccomp/consts.go
generated
vendored
@ -1,12 +0,0 @@
|
|||||||
package seccomp
|
|
||||||
|
|
||||||
const (
|
|
||||||
seccompOverwrite = "overwrite"
|
|
||||||
seccompAppend = "append"
|
|
||||||
nothing = "nothing"
|
|
||||||
kill = "kill"
|
|
||||||
trap = "trap"
|
|
||||||
trace = "trace"
|
|
||||||
allow = "allow"
|
|
||||||
errno = "errno"
|
|
||||||
)
|
|
135
vendor/github.com/opencontainers/runtime-tools/generate/seccomp/parse_action.go
generated
vendored
135
vendor/github.com/opencontainers/runtime-tools/generate/seccomp/parse_action.go
generated
vendored
@ -1,135 +0,0 @@
|
|||||||
package seccomp
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
rspec "github.com/opencontainers/runtime-spec/specs-go"
|
|
||||||
)
|
|
||||||
|
|
||||||
// SyscallOpts contain options for parsing syscall rules
|
|
||||||
type SyscallOpts struct {
|
|
||||||
Action string
|
|
||||||
Syscall string
|
|
||||||
Index string
|
|
||||||
Value string
|
|
||||||
ValueTwo string
|
|
||||||
Operator string
|
|
||||||
}
|
|
||||||
|
|
||||||
// ParseSyscallFlag takes a SyscallOpts struct and the seccomp configuration
|
|
||||||
// and sets the new syscall rule accordingly
|
|
||||||
func ParseSyscallFlag(args SyscallOpts, config *rspec.LinuxSeccomp) error {
|
|
||||||
var arguments []string
|
|
||||||
if args.Index != "" && args.Value != "" && args.ValueTwo != "" && args.Operator != "" {
|
|
||||||
arguments = []string{args.Action, args.Syscall, args.Index, args.Value,
|
|
||||||
args.ValueTwo, args.Operator}
|
|
||||||
} else {
|
|
||||||
arguments = []string{args.Action, args.Syscall}
|
|
||||||
}
|
|
||||||
|
|
||||||
action, _ := parseAction(arguments[0])
|
|
||||||
if action == config.DefaultAction && args.argsAreEmpty() {
|
|
||||||
// default already set, no need to make changes
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
var newSyscall rspec.LinuxSyscall
|
|
||||||
numOfArgs := len(arguments)
|
|
||||||
if numOfArgs == 6 || numOfArgs == 2 {
|
|
||||||
argStruct, err := parseArguments(arguments[1:])
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
newSyscall = newSyscallStruct(arguments[1], action, argStruct)
|
|
||||||
} else {
|
|
||||||
return fmt.Errorf("incorrect number of arguments to ParseSyscall: %d", numOfArgs)
|
|
||||||
}
|
|
||||||
|
|
||||||
descison, err := decideCourseOfAction(&newSyscall, config.Syscalls)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
delimDescison := strings.Split(descison, ":")
|
|
||||||
|
|
||||||
if delimDescison[0] == seccompAppend {
|
|
||||||
config.Syscalls = append(config.Syscalls, newSyscall)
|
|
||||||
}
|
|
||||||
|
|
||||||
if delimDescison[0] == seccompOverwrite {
|
|
||||||
indexForOverwrite, err := strconv.ParseInt(delimDescison[1], 10, 32)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
config.Syscalls[indexForOverwrite] = newSyscall
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
var actions = map[string]rspec.LinuxSeccompAction{
|
|
||||||
"allow": rspec.ActAllow,
|
|
||||||
"errno": rspec.ActErrno,
|
|
||||||
"kill": rspec.ActKill,
|
|
||||||
"trace": rspec.ActTrace,
|
|
||||||
"trap": rspec.ActTrap,
|
|
||||||
}
|
|
||||||
|
|
||||||
// Take passed action, return the SCMP_ACT_<ACTION> version of it
|
|
||||||
func parseAction(action string) (rspec.LinuxSeccompAction, error) {
|
|
||||||
a, ok := actions[action]
|
|
||||||
if !ok {
|
|
||||||
return "", fmt.Errorf("unrecognized action: %s", action)
|
|
||||||
}
|
|
||||||
return a, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ParseDefaultAction sets the default action of the seccomp configuration
|
|
||||||
// and then removes any rules that were already specified with this action
|
|
||||||
func ParseDefaultAction(action string, config *rspec.LinuxSeccomp) error {
|
|
||||||
if action == "" {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
defaultAction, err := parseAction(action)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
config.DefaultAction = defaultAction
|
|
||||||
err = RemoveAllMatchingRules(config, defaultAction)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ParseDefaultActionForce simply sets the default action of the seccomp configuration
|
|
||||||
func ParseDefaultActionForce(action string, config *rspec.LinuxSeccomp) error {
|
|
||||||
if action == "" {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
defaultAction, err := parseAction(action)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
config.DefaultAction = defaultAction
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func newSyscallStruct(name string, action rspec.LinuxSeccompAction, args []rspec.LinuxSeccompArg) rspec.LinuxSyscall {
|
|
||||||
syscallStruct := rspec.LinuxSyscall{
|
|
||||||
Names: []string{name},
|
|
||||||
Action: action,
|
|
||||||
Args: args,
|
|
||||||
}
|
|
||||||
return syscallStruct
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s SyscallOpts) argsAreEmpty() bool {
|
|
||||||
return (s.Index == "" &&
|
|
||||||
s.Value == "" &&
|
|
||||||
s.ValueTwo == "" &&
|
|
||||||
s.Operator == "")
|
|
||||||
}
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user