update vendor
Signed-off-by: Jess Frazelle <acidburn@microsoft.com>
This commit is contained in:
parent
19a32db84d
commit
94d1cfbfbf
10501 changed files with 2307943 additions and 29279 deletions
61
vendor/github.com/docker/cli/internal/pkg/containerized/hostpaths.go
generated
vendored
Normal file
61
vendor/github.com/docker/cli/internal/pkg/containerized/hostpaths.go
generated
vendored
Normal file
|
@ -0,0 +1,61 @@
|
|||
package containerized
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/containerd/containerd/containers"
|
||||
"github.com/containerd/containerd/oci"
|
||||
specs "github.com/opencontainers/runtime-spec/specs-go"
|
||||
)
|
||||
|
||||
// WithAllCapabilities enables all capabilities required to run privileged containers
|
||||
func WithAllCapabilities(_ context.Context, _ oci.Client, c *containers.Container, s *specs.Spec) error {
|
||||
caps := []string{
|
||||
"CAP_CHOWN",
|
||||
"CAP_DAC_OVERRIDE",
|
||||
"CAP_DAC_READ_SEARCH",
|
||||
"CAP_FOWNER",
|
||||
"CAP_FSETID",
|
||||
"CAP_KILL",
|
||||
"CAP_SETGID",
|
||||
"CAP_SETUID",
|
||||
"CAP_SETPCAP",
|
||||
"CAP_LINUX_IMMUTABLE",
|
||||
"CAP_NET_BIND_SERVICE",
|
||||
"CAP_NET_BROADCAST",
|
||||
"CAP_NET_ADMIN",
|
||||
"CAP_NET_RAW",
|
||||
"CAP_IPC_LOCK",
|
||||
"CAP_IPC_OWNER",
|
||||
"CAP_SYS_MODULE",
|
||||
"CAP_SYS_RAWIO",
|
||||
"CAP_SYS_CHROOT",
|
||||
"CAP_SYS_PTRACE",
|
||||
"CAP_SYS_PACCT",
|
||||
"CAP_SYS_ADMIN",
|
||||
"CAP_SYS_BOOT",
|
||||
"CAP_SYS_NICE",
|
||||
"CAP_SYS_RESOURCE",
|
||||
"CAP_SYS_TIME",
|
||||
"CAP_SYS_TTY_CONFIG",
|
||||
"CAP_MKNOD",
|
||||
"CAP_LEASE",
|
||||
"CAP_AUDIT_WRITE",
|
||||
"CAP_AUDIT_CONTROL",
|
||||
"CAP_SETFCAP",
|
||||
"CAP_MAC_OVERRIDE",
|
||||
"CAP_MAC_ADMIN",
|
||||
"CAP_SYSLOG",
|
||||
"CAP_WAKE_ALARM",
|
||||
"CAP_BLOCK_SUSPEND",
|
||||
"CAP_AUDIT_READ",
|
||||
}
|
||||
if s.Process.Capabilities == nil {
|
||||
s.Process.Capabilities = &specs.LinuxCapabilities{}
|
||||
}
|
||||
s.Process.Capabilities.Bounding = caps
|
||||
s.Process.Capabilities.Effective = caps
|
||||
s.Process.Capabilities.Inheritable = caps
|
||||
s.Process.Capabilities.Permitted = caps
|
||||
return nil
|
||||
}
|
21
vendor/github.com/docker/cli/internal/pkg/containerized/hostpaths_test.go
generated
vendored
Normal file
21
vendor/github.com/docker/cli/internal/pkg/containerized/hostpaths_test.go
generated
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
package containerized
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/containerd/containerd/containers"
|
||||
specs "github.com/opencontainers/runtime-spec/specs-go"
|
||||
"gotest.tools/assert"
|
||||
)
|
||||
|
||||
func TestWithAllCapabilities(t *testing.T) {
|
||||
c := &containers.Container{}
|
||||
s := &specs.Spec{
|
||||
Process: &specs.Process{},
|
||||
}
|
||||
ctx := context.Background()
|
||||
err := WithAllCapabilities(ctx, nil, c, s)
|
||||
assert.NilError(t, err)
|
||||
assert.Assert(t, len(s.Process.Capabilities.Bounding) > 0)
|
||||
}
|
74
vendor/github.com/docker/cli/internal/pkg/containerized/pauseandrun.go
generated
vendored
Normal file
74
vendor/github.com/docker/cli/internal/pkg/containerized/pauseandrun.go
generated
vendored
Normal file
|
@ -0,0 +1,74 @@
|
|||
package containerized
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/containerd/containerd"
|
||||
"github.com/containerd/containerd/errdefs"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
// AtomicImageUpdate will perform an update of the given container with the new image
|
||||
// and verify success via the provided healthcheckFn. If the healthcheck fails, the
|
||||
// container will be reverted to the prior image
|
||||
func AtomicImageUpdate(ctx context.Context, container containerd.Container, image containerd.Image, healthcheckFn func() error) error {
|
||||
updateCompleted := false
|
||||
err := pauseAndRun(ctx, container, func() error {
|
||||
if err := container.Update(ctx, WithUpgrade(image)); err != nil {
|
||||
return errors.Wrap(err, "failed to update to new image")
|
||||
}
|
||||
updateCompleted = true
|
||||
task, err := container.Task(ctx, nil)
|
||||
if err != nil {
|
||||
if errdefs.IsNotFound(err) {
|
||||
return nil
|
||||
}
|
||||
return errors.Wrap(err, "failed to lookup task")
|
||||
}
|
||||
return task.Kill(ctx, sigTERM)
|
||||
})
|
||||
if err != nil {
|
||||
if updateCompleted {
|
||||
logrus.WithError(err).Error("failed to update, rolling back")
|
||||
return rollBack(ctx, container)
|
||||
}
|
||||
return err
|
||||
}
|
||||
if err := healthcheckFn(); err != nil {
|
||||
logrus.WithError(err).Error("failed health check, rolling back")
|
||||
return rollBack(ctx, container)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func rollBack(ctx context.Context, container containerd.Container) error {
|
||||
return pauseAndRun(ctx, container, func() error {
|
||||
if err := container.Update(ctx, WithRollback); err != nil {
|
||||
return err
|
||||
}
|
||||
task, err := container.Task(ctx, nil)
|
||||
if err != nil {
|
||||
if errdefs.IsNotFound(err) {
|
||||
return nil
|
||||
}
|
||||
return errors.Wrap(err, "failed to lookup task")
|
||||
}
|
||||
return task.Kill(ctx, sigTERM)
|
||||
})
|
||||
}
|
||||
|
||||
func pauseAndRun(ctx context.Context, container containerd.Container, fn func() error) error {
|
||||
task, err := container.Task(ctx, nil)
|
||||
if err != nil {
|
||||
if errdefs.IsNotFound(err) {
|
||||
return fn()
|
||||
}
|
||||
return errors.Wrap(err, "failed to lookup task")
|
||||
}
|
||||
if err := task.Pause(ctx); err != nil {
|
||||
return errors.Wrap(err, "failed to pause task")
|
||||
}
|
||||
defer task.Resume(ctx)
|
||||
return fn()
|
||||
}
|
66
vendor/github.com/docker/cli/internal/pkg/containerized/proxy.go
generated
vendored
Normal file
66
vendor/github.com/docker/cli/internal/pkg/containerized/proxy.go
generated
vendored
Normal file
|
@ -0,0 +1,66 @@
|
|||
package containerized
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
var (
|
||||
proxydir = "/etc/containerd-proxy"
|
||||
)
|
||||
|
||||
type proxyConfig struct {
|
||||
ID string `json:"-"`
|
||||
Namespace string `json:"namespace"`
|
||||
Image string `json:"image"`
|
||||
ImagePath string `json:"imagePath"`
|
||||
Args []string `json:"args"`
|
||||
Scope string `json:"scope"`
|
||||
}
|
||||
|
||||
func updateConfig(name, newImage string) error {
|
||||
cfg, err := loadConfig(name)
|
||||
if err != nil && os.IsNotExist(err) {
|
||||
return nil
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cfg.Image = newImage
|
||||
cfg.ImagePath = ""
|
||||
return storeConfig(name, cfg)
|
||||
}
|
||||
|
||||
func loadConfig(name string) (*proxyConfig, error) {
|
||||
configFile := filepath.Join(proxydir, name+".json")
|
||||
data, err := ioutil.ReadFile(configFile)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var cfg proxyConfig
|
||||
err = json.Unmarshal(data, &cfg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &cfg, nil
|
||||
}
|
||||
|
||||
// storeConfig will write out the config only if it already exists
|
||||
func storeConfig(name string, cfg *proxyConfig) error {
|
||||
configFile := filepath.Join(proxydir, name+".json")
|
||||
fd, err := os.OpenFile(configFile, os.O_RDWR, 0644)
|
||||
if err != nil && os.IsNotExist(err) {
|
||||
return nil
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = fd.Truncate(0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
enc := json.NewEncoder(fd)
|
||||
return enc.Encode(cfg)
|
||||
}
|
68
vendor/github.com/docker/cli/internal/pkg/containerized/proxy_test.go
generated
vendored
Normal file
68
vendor/github.com/docker/cli/internal/pkg/containerized/proxy_test.go
generated
vendored
Normal file
|
@ -0,0 +1,68 @@
|
|||
package containerized
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"gotest.tools/assert"
|
||||
)
|
||||
|
||||
func TestUpdateConfigNotExist(t *testing.T) {
|
||||
tmpdir, err := ioutil.TempDir("", "cfg-update")
|
||||
assert.NilError(t, err)
|
||||
defer os.RemoveAll(tmpdir)
|
||||
origProxyDir := proxydir
|
||||
defer func() {
|
||||
proxydir = origProxyDir
|
||||
}()
|
||||
proxydir = tmpdir
|
||||
name := "myname"
|
||||
newImage := "newimage:foo"
|
||||
err = updateConfig(name, newImage)
|
||||
assert.NilError(t, err)
|
||||
}
|
||||
|
||||
func TestUpdateConfigBadJson(t *testing.T) {
|
||||
tmpdir, err := ioutil.TempDir("", "cfg-update")
|
||||
assert.NilError(t, err)
|
||||
defer os.RemoveAll(tmpdir)
|
||||
origProxyDir := proxydir
|
||||
defer func() {
|
||||
proxydir = origProxyDir
|
||||
}()
|
||||
proxydir = tmpdir
|
||||
filename := filepath.Join(tmpdir, "dockerd.json")
|
||||
err = ioutil.WriteFile(filename, []byte("not json"), 0644)
|
||||
assert.NilError(t, err)
|
||||
name := "dockerd"
|
||||
newImage := "newimage:foo"
|
||||
err = updateConfig(name, newImage)
|
||||
assert.ErrorContains(t, err, "invalid character")
|
||||
}
|
||||
|
||||
func TestUpdateConfigHappyPath(t *testing.T) {
|
||||
tmpdir, err := ioutil.TempDir("", "cfg-update")
|
||||
assert.NilError(t, err)
|
||||
defer os.RemoveAll(tmpdir)
|
||||
origProxyDir := proxydir
|
||||
defer func() {
|
||||
proxydir = origProxyDir
|
||||
}()
|
||||
proxydir = tmpdir
|
||||
filename := filepath.Join(tmpdir, "dockerd.json")
|
||||
err = ioutil.WriteFile(filename, []byte("{}"), 0644)
|
||||
assert.NilError(t, err)
|
||||
name := "dockerd"
|
||||
newImage := "newimage:foo"
|
||||
err = updateConfig(name, newImage)
|
||||
assert.NilError(t, err)
|
||||
data, err := ioutil.ReadFile(filename)
|
||||
assert.NilError(t, err)
|
||||
var cfg map[string]string
|
||||
err = json.Unmarshal(data, &cfg)
|
||||
assert.NilError(t, err)
|
||||
assert.Assert(t, cfg["image"] == newImage)
|
||||
}
|
12
vendor/github.com/docker/cli/internal/pkg/containerized/signal_unix.go
generated
vendored
Normal file
12
vendor/github.com/docker/cli/internal/pkg/containerized/signal_unix.go
generated
vendored
Normal file
|
@ -0,0 +1,12 @@
|
|||
// +build !windows
|
||||
|
||||
package containerized
|
||||
|
||||
import (
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
var (
|
||||
// sigTERM maps to unix.SIGTERM
|
||||
sigTERM = unix.SIGTERM
|
||||
)
|
12
vendor/github.com/docker/cli/internal/pkg/containerized/signal_windows.go
generated
vendored
Normal file
12
vendor/github.com/docker/cli/internal/pkg/containerized/signal_windows.go
generated
vendored
Normal file
|
@ -0,0 +1,12 @@
|
|||
// +build windows
|
||||
|
||||
package containerized
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
)
|
||||
|
||||
var (
|
||||
// sigTERM all signals are ignored by containerd kill windows
|
||||
sigTERM = syscall.Signal(0)
|
||||
)
|
166
vendor/github.com/docker/cli/internal/pkg/containerized/snapshot.go
generated
vendored
Normal file
166
vendor/github.com/docker/cli/internal/pkg/containerized/snapshot.go
generated
vendored
Normal file
|
@ -0,0 +1,166 @@
|
|||
package containerized
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/containerd/containerd"
|
||||
"github.com/containerd/containerd/containers"
|
||||
"github.com/containerd/containerd/diff/apply"
|
||||
"github.com/containerd/containerd/mount"
|
||||
"github.com/containerd/containerd/rootfs"
|
||||
"github.com/containerd/containerd/snapshots"
|
||||
"github.com/opencontainers/image-spec/identity"
|
||||
)
|
||||
|
||||
const (
|
||||
gcRoot = "containerd.io/gc.root"
|
||||
timestampFormat = "01-02-2006-15:04:05"
|
||||
previousRevision = "docker.com/revision.previous"
|
||||
imageLabel = "docker.com/revision.image"
|
||||
)
|
||||
|
||||
// ErrNoPreviousRevision returned if the container has to previous revision
|
||||
var ErrNoPreviousRevision = errors.New("no previous revision")
|
||||
|
||||
// WithNewSnapshot creates a new snapshot managed by containerized
|
||||
func WithNewSnapshot(i containerd.Image) containerd.NewContainerOpts {
|
||||
return func(ctx context.Context, client *containerd.Client, c *containers.Container) error {
|
||||
if c.Snapshotter == "" {
|
||||
c.Snapshotter = containerd.DefaultSnapshotter
|
||||
}
|
||||
r, err := create(ctx, client, i, c.ID, "")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c.SnapshotKey = r.Key
|
||||
c.Image = i.Name()
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithUpgrade upgrades an existing container's image to a new one
|
||||
func WithUpgrade(i containerd.Image) containerd.UpdateContainerOpts {
|
||||
return func(ctx context.Context, client *containerd.Client, c *containers.Container) error {
|
||||
revision, err := save(ctx, client, i, c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c.Image = i.Name()
|
||||
err = updateConfig(c.ID, c.Image)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c.SnapshotKey = revision.Key
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithRollback rolls back to the previous container's revision
|
||||
func WithRollback(ctx context.Context, client *containerd.Client, c *containers.Container) error {
|
||||
prev, err := previous(ctx, client, c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ss := client.SnapshotService(c.Snapshotter)
|
||||
sInfo, err := ss.Stat(ctx, prev.Key)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
snapshotImage, ok := sInfo.Labels[imageLabel]
|
||||
if !ok {
|
||||
return fmt.Errorf("snapshot %s does not have a service image label", prev.Key)
|
||||
}
|
||||
if snapshotImage == "" {
|
||||
return fmt.Errorf("snapshot %s has an empty service image label", prev.Key)
|
||||
}
|
||||
c.Image = snapshotImage
|
||||
err = updateConfig(c.ID, c.Image)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c.SnapshotKey = prev.Key
|
||||
return nil
|
||||
}
|
||||
|
||||
func newRevision(id string) *revision {
|
||||
now := time.Now()
|
||||
return &revision{
|
||||
Timestamp: now,
|
||||
Key: fmt.Sprintf("boss.io.%s.%s", id, now.Format(timestampFormat)),
|
||||
}
|
||||
}
|
||||
|
||||
type revision struct {
|
||||
Timestamp time.Time
|
||||
Key string
|
||||
mounts []mount.Mount
|
||||
}
|
||||
|
||||
// nolint: interfacer
|
||||
func create(ctx context.Context, client *containerd.Client, i containerd.Image, id string, previous string) (*revision, error) {
|
||||
diffIDs, err := i.RootFS(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var (
|
||||
parent = identity.ChainID(diffIDs).String()
|
||||
r = newRevision(id)
|
||||
)
|
||||
labels := map[string]string{
|
||||
gcRoot: r.Timestamp.Format(time.RFC3339),
|
||||
imageLabel: i.Name(),
|
||||
}
|
||||
if previous != "" {
|
||||
labels[previousRevision] = previous
|
||||
}
|
||||
mounts, err := client.SnapshotService(containerd.DefaultSnapshotter).Prepare(ctx, r.Key, parent, snapshots.WithLabels(labels))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
r.mounts = mounts
|
||||
return r, nil
|
||||
}
|
||||
|
||||
func save(ctx context.Context, client *containerd.Client, updatedImage containerd.Image, c *containers.Container) (*revision, error) {
|
||||
snapshot, err := create(ctx, client, updatedImage, c.ID, c.SnapshotKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
service := client.SnapshotService(c.Snapshotter)
|
||||
// create a diff from the existing snapshot
|
||||
diff, err := rootfs.CreateDiff(ctx, c.SnapshotKey, service, client.DiffService())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
applier := apply.NewFileSystemApplier(client.ContentStore())
|
||||
if _, err := applier.Apply(ctx, diff, snapshot.mounts); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return snapshot, nil
|
||||
}
|
||||
|
||||
// nolint: interfacer
|
||||
func previous(ctx context.Context, client *containerd.Client, c *containers.Container) (*revision, error) {
|
||||
service := client.SnapshotService(c.Snapshotter)
|
||||
sInfo, err := service.Stat(ctx, c.SnapshotKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
key := sInfo.Labels[previousRevision]
|
||||
if key == "" {
|
||||
return nil, ErrNoPreviousRevision
|
||||
}
|
||||
parts := strings.Split(key, ".")
|
||||
timestamp, err := time.Parse(timestampFormat, parts[len(parts)-1])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &revision{
|
||||
Timestamp: timestamp,
|
||||
Key: key,
|
||||
}, nil
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue