diff --git a/components/engine/libcontainerd/client_daemon.go b/components/engine/libcontainerd/client_daemon.go index 050a80d035..72f9692260 100644 --- a/components/engine/libcontainerd/client_daemon.go +++ b/components/engine/libcontainerd/client_daemon.go @@ -114,6 +114,13 @@ type client struct { containers map[string]*container } +func (c *client) reconnect() error { + c.Lock() + err := c.remote.Reconnect() + c.Unlock() + return err +} + func (c *client) setRemote(remote *containerd.Client) { c.Lock() c.remote = remote diff --git a/components/engine/libcontainerd/remote_daemon.go b/components/engine/libcontainerd/remote_daemon.go index cc98456ba5..d5ff83be88 100644 --- a/components/engine/libcontainerd/remote_daemon.go +++ b/components/engine/libcontainerd/remote_daemon.go @@ -311,20 +311,17 @@ func (r *remote) monitorConnection(monitor *containerd.Client) { <-r.daemonWaitCh } - monitor.Close() os.Remove(r.GRPC.Address) if err := r.startContainerd(); err != nil { r.logger.WithError(err).Error("failed restarting containerd") continue } - newMonitor, err := containerd.New(r.GRPC.Address) - if err != nil { + if err := monitor.Reconnect(); err != nil { r.logger.WithError(err).Error("failed connect to containerd") continue } - monitor = newMonitor var wg sync.WaitGroup for _, c := range r.clients { @@ -333,18 +330,12 @@ func (r *remote) monitorConnection(monitor *containerd.Client) { go func(c *client) { defer wg.Done() c.logger.WithField("namespace", c.namespace).Debug("creating new containerd remote client") - c.remote.Close() - - remote, err := containerd.New(r.GRPC.Address, containerd.WithDefaultNamespace(c.namespace)) - if err != nil { + if err := c.reconnect(); err != nil { r.logger.WithError(err).Error("failed to connect to containerd") // TODO: Better way to handle this? // This *shouldn't* happen, but this could wind up where the daemon // is not able to communicate with an eventually up containerd - return } - - c.setRemote(remote) }(c) wg.Wait() diff --git a/components/engine/libcontainerd/remote_daemon_options_linux.go b/components/engine/libcontainerd/remote_daemon_options_linux.go index 24ef5a5a4b..a820fb3894 100644 --- a/components/engine/libcontainerd/remote_daemon_options_linux.go +++ b/components/engine/libcontainerd/remote_daemon_options_linux.go @@ -16,19 +16,3 @@ func (o oomScore) Apply(r Remote) error { } return fmt.Errorf("WithOOMScore option not supported for this remote") } - -// WithSubreaper sets whether containerd should register itself as a -// subreaper -func WithSubreaper(reap bool) RemoteOption { - return subreaper(reap) -} - -type subreaper bool - -func (s subreaper) Apply(r Remote) error { - if remote, ok := r.(*remote); ok { - remote.NoSubreaper = !bool(s) - return nil - } - return fmt.Errorf("WithSubreaper option not supported for this remote") -} diff --git a/components/engine/vendor.conf b/components/engine/vendor.conf index b83c05adf3..91cde6db28 100644 --- a/components/engine/vendor.conf +++ b/components/engine/vendor.conf @@ -108,7 +108,7 @@ github.com/googleapis/gax-go da06d194a00e19ce00d9011a13931c3f6f6887c7 google.golang.org/genproto d80a6e20e776b0b17a324d0ba1ab50a39c8e8944 # containerd -github.com/containerd/containerd 3fa104f843ec92328912e042b767d26825f202aa +github.com/containerd/containerd 4ac4fd0b6a268fe6f38b2b2e32e40daa7e424fac github.com/containerd/fifo fbfb6a11ec671efbe94ad1c12c2e98773f19e1e6 github.com/containerd/continuity d8fb8589b0e8e85b8c8bbaa8840226d0dfeb7371 github.com/containerd/cgroups fe281dd265766145e943a034aa41086474ea6130 diff --git a/components/engine/vendor/github.com/containerd/containerd/LICENSE.code b/components/engine/vendor/github.com/containerd/containerd/LICENSE similarity index 100% rename from components/engine/vendor/github.com/containerd/containerd/LICENSE.code rename to components/engine/vendor/github.com/containerd/containerd/LICENSE diff --git a/components/engine/vendor/github.com/containerd/containerd/README.md b/components/engine/vendor/github.com/containerd/containerd/README.md index 84d1eec8ae..d76ce1b2c1 100644 --- a/components/engine/vendor/github.com/containerd/containerd/README.md +++ b/components/engine/vendor/github.com/containerd/containerd/README.md @@ -4,6 +4,7 @@ [![Build Status](https://travis-ci.org/containerd/containerd.svg?branch=master)](https://travis-ci.org/containerd/containerd) [![FOSSA Status](https://app.fossa.io/api/projects/git%2Bhttps%3A%2F%2Fgithub.com%2Fcontainerd%2Fcontainerd.svg?type=shield)](https://app.fossa.io/projects/git%2Bhttps%3A%2F%2Fgithub.com%2Fcontainerd%2Fcontainerd?ref=badge_shield) [![Go Report Card](https://goreportcard.com/badge/github.com/containerd/containerd)](https://goreportcard.com/report/github.com/containerd/containerd) +[![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/1271/badge)](https://bestpractices.coreinfrastructure.org/projects/1271) containerd is an industry-standard container runtime with an emphasis on simplicity, robustness and portability. It is available as a daemon for Linux and Windows, which can manage the complete container lifecycle of its host system: image transfer and storage, container execution and supervision, low-level storage and network attachments, etc. @@ -13,7 +14,7 @@ containerd is designed to be embedded into a larger system, rather than being us ## Getting Started -See our documentation on [containerd.io](containerd.io): +See our documentation on [containerd.io](https://containerd.io): * [for ops and admins](docs/ops.md) * [namespaces](docs/namespaces.md) * [client options](docs/client-opts.md) diff --git a/components/engine/vendor/github.com/containerd/containerd/api/events/container.pb.go b/components/engine/vendor/github.com/containerd/containerd/api/events/container.pb.go index b05a402bb0..5b715fc1ef 100644 --- a/components/engine/vendor/github.com/containerd/containerd/api/events/container.pb.go +++ b/components/engine/vendor/github.com/containerd/containerd/api/events/container.pb.go @@ -158,9 +158,7 @@ func (m *ContainerCreate_Runtime) Field(fieldpath []string) (string, bool) { return "", false } - adaptor, ok := decoded.(interface { - Field([]string) (string, bool) - }) + adaptor, ok := decoded.(interface{ Field([]string) (string, bool) }) if !ok { return "", false } diff --git a/components/engine/vendor/github.com/containerd/containerd/api/events/doc.go b/components/engine/vendor/github.com/containerd/containerd/api/events/doc.go index ac1e83fb75..354bef79fd 100644 --- a/components/engine/vendor/github.com/containerd/containerd/api/events/doc.go +++ b/components/engine/vendor/github.com/containerd/containerd/api/events/doc.go @@ -1,3 +1,19 @@ +/* + 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 events has protobuf types for various events that are used in // containerd. package events diff --git a/components/engine/vendor/github.com/containerd/containerd/api/services/events/v1/doc.go b/components/engine/vendor/github.com/containerd/containerd/api/services/events/v1/doc.go index 070604bb8f..b7f86da869 100644 --- a/components/engine/vendor/github.com/containerd/containerd/api/services/events/v1/doc.go +++ b/components/engine/vendor/github.com/containerd/containerd/api/services/events/v1/doc.go @@ -1,2 +1,18 @@ +/* + 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 events defines the event pushing and subscription service. package events diff --git a/components/engine/vendor/github.com/containerd/containerd/api/services/events/v1/events.pb.go b/components/engine/vendor/github.com/containerd/containerd/api/services/events/v1/events.pb.go index e2ad455a43..52cca0acd7 100644 --- a/components/engine/vendor/github.com/containerd/containerd/api/services/events/v1/events.pb.go +++ b/components/engine/vendor/github.com/containerd/containerd/api/services/events/v1/events.pb.go @@ -115,9 +115,7 @@ func (m *Envelope) Field(fieldpath []string) (string, bool) { return "", false } - adaptor, ok := decoded.(interface { - Field([]string) (string, bool) - }) + adaptor, ok := decoded.(interface{ Field([]string) (string, bool) }) if !ok { return "", false } diff --git a/components/engine/vendor/github.com/containerd/containerd/api/services/images/v1/docs.go b/components/engine/vendor/github.com/containerd/containerd/api/services/images/v1/docs.go index a8d61a31e4..4170f38aff 100644 --- a/components/engine/vendor/github.com/containerd/containerd/api/services/images/v1/docs.go +++ b/components/engine/vendor/github.com/containerd/containerd/api/services/images/v1/docs.go @@ -1 +1,17 @@ +/* + 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 images diff --git a/components/engine/vendor/github.com/containerd/containerd/api/services/introspection/v1/doc.go b/components/engine/vendor/github.com/containerd/containerd/api/services/introspection/v1/doc.go index 3b9d7947c9..f6f65eadfd 100644 --- a/components/engine/vendor/github.com/containerd/containerd/api/services/introspection/v1/doc.go +++ b/components/engine/vendor/github.com/containerd/containerd/api/services/introspection/v1/doc.go @@ -1 +1,17 @@ +/* + 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 introspection diff --git a/components/engine/vendor/github.com/containerd/containerd/api/services/leases/v1/doc.go b/components/engine/vendor/github.com/containerd/containerd/api/services/leases/v1/doc.go index 3685b64558..db2422a8bb 100644 --- a/components/engine/vendor/github.com/containerd/containerd/api/services/leases/v1/doc.go +++ b/components/engine/vendor/github.com/containerd/containerd/api/services/leases/v1/doc.go @@ -1 +1,17 @@ +/* + 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 leases diff --git a/components/engine/vendor/github.com/containerd/containerd/api/types/doc.go b/components/engine/vendor/github.com/containerd/containerd/api/types/doc.go index ab1254f4c2..475b465ed4 100644 --- a/components/engine/vendor/github.com/containerd/containerd/api/types/doc.go +++ b/components/engine/vendor/github.com/containerd/containerd/api/types/doc.go @@ -1 +1,17 @@ +/* + 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 types diff --git a/components/engine/vendor/github.com/containerd/containerd/archive/strconv.go b/components/engine/vendor/github.com/containerd/containerd/archive/strconv.go new file mode 100644 index 0000000000..d262e90598 --- /dev/null +++ b/components/engine/vendor/github.com/containerd/containerd/archive/strconv.go @@ -0,0 +1,68 @@ +// +build windows + +/* + 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 archive + +import ( + "strconv" + "strings" + "time" + + "github.com/dmcgowan/go-tar" +) + +// Forked from https://github.com/golang/go/blob/master/src/archive/tar/strconv.go +// as archive/tar doesn't support CreationTime, but does handle PAX time parsing, +// and there's no need to re-invent the wheel. + +// parsePAXTime takes a string of the form %d.%d as described in the PAX +// specification. Note that this implementation allows for negative timestamps, +// which is allowed for by the PAX specification, but not always portable. +func parsePAXTime(s string) (time.Time, error) { + const maxNanoSecondDigits = 9 + + // Split string into seconds and sub-seconds parts. + ss, sn := s, "" + if pos := strings.IndexByte(s, '.'); pos >= 0 { + ss, sn = s[:pos], s[pos+1:] + } + + // Parse the seconds. + secs, err := strconv.ParseInt(ss, 10, 64) + if err != nil { + return time.Time{}, tar.ErrHeader + } + if len(sn) == 0 { + return time.Unix(secs, 0), nil // No sub-second values + } + + // Parse the nanoseconds. + if strings.Trim(sn, "0123456789") != "" { + return time.Time{}, tar.ErrHeader + } + if len(sn) < maxNanoSecondDigits { + sn += strings.Repeat("0", maxNanoSecondDigits-len(sn)) // Right pad + } else { + sn = sn[:maxNanoSecondDigits] // Right truncate + } + nsecs, _ := strconv.ParseInt(sn, 10, 64) // Must succeed + if len(ss) > 0 && ss[0] == '-' { + return time.Unix(secs, -nsecs), nil // Negative correction + } + return time.Unix(secs, nsecs), nil +} diff --git a/components/engine/vendor/github.com/containerd/containerd/archive/tar.go b/components/engine/vendor/github.com/containerd/containerd/archive/tar.go index a649c5b458..7e9182c8f5 100644 --- a/components/engine/vendor/github.com/containerd/containerd/archive/tar.go +++ b/components/engine/vendor/github.com/containerd/containerd/archive/tar.go @@ -1,3 +1,19 @@ +/* + 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 archive import ( @@ -13,19 +29,21 @@ import ( "syscall" "time" - "github.com/containerd/containerd/fs" "github.com/containerd/containerd/log" + "github.com/containerd/continuity/fs" "github.com/dmcgowan/go-tar" "github.com/pkg/errors" ) -var bufferPool = &sync.Pool{ +var bufPool = &sync.Pool{ New: func() interface{} { buffer := make([]byte, 32*1024) return &buffer }, } +var errInvalidArchive = errors.New("invalid archive") + // Diff returns a tar stream of the computed filesystem // difference between the provided directories. // @@ -87,12 +105,23 @@ const ( // Apply applies a tar stream of an OCI style diff tar. // See https://github.com/opencontainers/image-spec/blob/master/layer.md#applying-changesets -func Apply(ctx context.Context, root string, r io.Reader) (int64, error) { +func Apply(ctx context.Context, root string, r io.Reader, opts ...ApplyOpt) (int64, error) { root = filepath.Clean(root) + var options ApplyOptions + for _, opt := range opts { + if err := opt(&options); err != nil { + return 0, errors.Wrap(err, "failed to apply option") + } + } + + return apply(ctx, root, tar.NewReader(r), options) +} + +// applyNaive applies a tar stream of an OCI style diff tar. +// See https://github.com/opencontainers/image-spec/blob/master/layer.md#applying-changesets +func applyNaive(ctx context.Context, root string, tr *tar.Reader, options ApplyOptions) (size int64, err error) { var ( - tr = tar.NewReader(r) - size int64 dirs []*tar.Header // Used for handling opaque directory markers which @@ -220,6 +249,15 @@ func Apply(ctx context.Context, root string, r io.Reader) (int64, error) { originalBase := base[len(whiteoutPrefix):] originalPath := filepath.Join(dir, originalBase) + + // Ensure originalPath is under dir + if dir[len(dir)-1] != filepath.Separator { + dir += string(filepath.Separator) + } + if !strings.HasPrefix(originalPath, dir) { + return 0, errors.Wrapf(errInvalidArchive, "invalid whiteout name: %v", base) + } + if err := os.RemoveAll(originalPath); err != nil { return 0, err } @@ -285,163 +323,6 @@ func Apply(ctx context.Context, root string, r io.Reader) (int64, error) { return size, nil } -type changeWriter struct { - tw *tar.Writer - source string - whiteoutT time.Time - inodeSrc map[uint64]string - inodeRefs map[uint64][]string -} - -func newChangeWriter(w io.Writer, source string) *changeWriter { - return &changeWriter{ - tw: tar.NewWriter(w), - source: source, - whiteoutT: time.Now(), - inodeSrc: map[uint64]string{}, - inodeRefs: map[uint64][]string{}, - } -} - -func (cw *changeWriter) HandleChange(k fs.ChangeKind, p string, f os.FileInfo, err error) error { - if err != nil { - return err - } - if k == fs.ChangeKindDelete { - whiteOutDir := filepath.Dir(p) - whiteOutBase := filepath.Base(p) - whiteOut := filepath.Join(whiteOutDir, whiteoutPrefix+whiteOutBase) - hdr := &tar.Header{ - Name: whiteOut[1:], - Size: 0, - ModTime: cw.whiteoutT, - AccessTime: cw.whiteoutT, - ChangeTime: cw.whiteoutT, - } - if err := cw.tw.WriteHeader(hdr); err != nil { - return errors.Wrap(err, "failed to write whiteout header") - } - } else { - var ( - link string - err error - source = filepath.Join(cw.source, p) - ) - - if f.Mode()&os.ModeSymlink != 0 { - if link, err = os.Readlink(source); err != nil { - return err - } - } - - hdr, err := tar.FileInfoHeader(f, link) - if err != nil { - return err - } - - hdr.Mode = int64(chmodTarEntry(os.FileMode(hdr.Mode))) - - name := p - if strings.HasPrefix(name, string(filepath.Separator)) { - name, err = filepath.Rel(string(filepath.Separator), name) - if err != nil { - return errors.Wrap(err, "failed to make path relative") - } - } - name, err = tarName(name) - if err != nil { - return errors.Wrap(err, "cannot canonicalize path") - } - // suffix with '/' for directories - if f.IsDir() && !strings.HasSuffix(name, "/") { - name += "/" - } - hdr.Name = name - - if err := setHeaderForSpecialDevice(hdr, name, f); err != nil { - return errors.Wrap(err, "failed to set device headers") - } - - // additionalLinks stores file names which must be linked to - // this file when this file is added - var additionalLinks []string - inode, isHardlink := fs.GetLinkInfo(f) - if isHardlink { - // If the inode has a source, always link to it - if source, ok := cw.inodeSrc[inode]; ok { - hdr.Typeflag = tar.TypeLink - hdr.Linkname = source - hdr.Size = 0 - } else { - if k == fs.ChangeKindUnmodified { - cw.inodeRefs[inode] = append(cw.inodeRefs[inode], name) - return nil - } - cw.inodeSrc[inode] = name - additionalLinks = cw.inodeRefs[inode] - delete(cw.inodeRefs, inode) - } - } else if k == fs.ChangeKindUnmodified && !f.IsDir() { - // Nothing to write to diff - // Unmodified directories should still be written to keep - // directory permissions correct on direct unpack - return nil - } - - if capability, err := getxattr(source, "security.capability"); err != nil { - return errors.Wrap(err, "failed to get capabilities xattr") - } else if capability != nil { - if hdr.PAXRecords == nil { - hdr.PAXRecords = map[string]string{} - } - hdr.PAXRecords[paxSchilyXattr+"security.capability"] = string(capability) - } - - if err := cw.tw.WriteHeader(hdr); err != nil { - return errors.Wrap(err, "failed to write file header") - } - - if hdr.Typeflag == tar.TypeReg && hdr.Size > 0 { - file, err := open(source) - if err != nil { - return errors.Wrapf(err, "failed to open path: %v", source) - } - defer file.Close() - - buf := bufferPool.Get().(*[]byte) - n, err := io.CopyBuffer(cw.tw, file, *buf) - bufferPool.Put(buf) - if err != nil { - return errors.Wrap(err, "failed to copy") - } - if n != hdr.Size { - return errors.New("short write copying file") - } - } - - if additionalLinks != nil { - source = hdr.Name - for _, extra := range additionalLinks { - hdr.Name = extra - hdr.Typeflag = tar.TypeLink - hdr.Linkname = source - hdr.Size = 0 - if err := cw.tw.WriteHeader(hdr); err != nil { - return errors.Wrap(err, "failed to write file header") - } - } - } - } - return nil -} - -func (cw *changeWriter) Close() error { - if err := cw.tw.Close(); err != nil { - return errors.Wrap(err, "failed to close tar writer") - } - return nil -} - func createTarFile(ctx context.Context, path, extractDir string, hdr *tar.Header, reader io.Reader) error { // hdr.Mode is in linux format, which we can use for syscalls, // but for os.Foo() calls we need the mode converted to os.FileMode, @@ -535,9 +416,201 @@ func createTarFile(ctx context.Context, path, extractDir string, hdr *tar.Header return chtimes(path, boundTime(latestTime(hdr.AccessTime, hdr.ModTime)), boundTime(hdr.ModTime)) } +type changeWriter struct { + tw *tar.Writer + source string + whiteoutT time.Time + inodeSrc map[uint64]string + inodeRefs map[uint64][]string + addedDirs map[string]struct{} +} + +func newChangeWriter(w io.Writer, source string) *changeWriter { + return &changeWriter{ + tw: tar.NewWriter(w), + source: source, + whiteoutT: time.Now(), + inodeSrc: map[uint64]string{}, + inodeRefs: map[uint64][]string{}, + addedDirs: map[string]struct{}{}, + } +} + +func (cw *changeWriter) HandleChange(k fs.ChangeKind, p string, f os.FileInfo, err error) error { + if err != nil { + return err + } + if k == fs.ChangeKindDelete { + whiteOutDir := filepath.Dir(p) + whiteOutBase := filepath.Base(p) + whiteOut := filepath.Join(whiteOutDir, whiteoutPrefix+whiteOutBase) + hdr := &tar.Header{ + Typeflag: tar.TypeReg, + Name: whiteOut[1:], + Size: 0, + ModTime: cw.whiteoutT, + AccessTime: cw.whiteoutT, + ChangeTime: cw.whiteoutT, + } + if err := cw.includeParents(hdr); err != nil { + return err + } + if err := cw.tw.WriteHeader(hdr); err != nil { + return errors.Wrap(err, "failed to write whiteout header") + } + } else { + var ( + link string + err error + source = filepath.Join(cw.source, p) + ) + + if f.Mode()&os.ModeSymlink != 0 { + if link, err = os.Readlink(source); err != nil { + return err + } + } + + hdr, err := tar.FileInfoHeader(f, link) + if err != nil { + return err + } + + hdr.Mode = int64(chmodTarEntry(os.FileMode(hdr.Mode))) + + name := p + if strings.HasPrefix(name, string(filepath.Separator)) { + name, err = filepath.Rel(string(filepath.Separator), name) + if err != nil { + return errors.Wrap(err, "failed to make path relative") + } + } + name, err = tarName(name) + if err != nil { + return errors.Wrap(err, "cannot canonicalize path") + } + // suffix with '/' for directories + if f.IsDir() && !strings.HasSuffix(name, "/") { + name += "/" + } + hdr.Name = name + + if err := setHeaderForSpecialDevice(hdr, name, f); err != nil { + return errors.Wrap(err, "failed to set device headers") + } + + // additionalLinks stores file names which must be linked to + // this file when this file is added + var additionalLinks []string + inode, isHardlink := fs.GetLinkInfo(f) + if isHardlink { + // If the inode has a source, always link to it + if source, ok := cw.inodeSrc[inode]; ok { + hdr.Typeflag = tar.TypeLink + hdr.Linkname = source + hdr.Size = 0 + } else { + if k == fs.ChangeKindUnmodified { + cw.inodeRefs[inode] = append(cw.inodeRefs[inode], name) + return nil + } + cw.inodeSrc[inode] = name + additionalLinks = cw.inodeRefs[inode] + delete(cw.inodeRefs, inode) + } + } else if k == fs.ChangeKindUnmodified { + // Nothing to write to diff + return nil + } + + if capability, err := getxattr(source, "security.capability"); err != nil { + return errors.Wrap(err, "failed to get capabilities xattr") + } else if capability != nil { + if hdr.PAXRecords == nil { + hdr.PAXRecords = map[string]string{} + } + hdr.PAXRecords[paxSchilyXattr+"security.capability"] = string(capability) + } + + if err := cw.includeParents(hdr); err != nil { + return err + } + if err := cw.tw.WriteHeader(hdr); err != nil { + return errors.Wrap(err, "failed to write file header") + } + + if hdr.Typeflag == tar.TypeReg && hdr.Size > 0 { + file, err := open(source) + if err != nil { + return errors.Wrapf(err, "failed to open path: %v", source) + } + defer file.Close() + + n, err := copyBuffered(context.TODO(), cw.tw, file) + if err != nil { + return errors.Wrap(err, "failed to copy") + } + if n != hdr.Size { + return errors.New("short write copying file") + } + } + + if additionalLinks != nil { + source = hdr.Name + for _, extra := range additionalLinks { + hdr.Name = extra + hdr.Typeflag = tar.TypeLink + hdr.Linkname = source + hdr.Size = 0 + + if err := cw.includeParents(hdr); err != nil { + return err + } + if err := cw.tw.WriteHeader(hdr); err != nil { + return errors.Wrap(err, "failed to write file header") + } + } + } + } + return nil +} + +func (cw *changeWriter) Close() error { + if err := cw.tw.Close(); err != nil { + return errors.Wrap(err, "failed to close tar writer") + } + return nil +} + +func (cw *changeWriter) includeParents(hdr *tar.Header) error { + name := strings.TrimRight(hdr.Name, "/") + fname := filepath.Join(cw.source, name) + parent := filepath.Dir(name) + pname := filepath.Join(cw.source, parent) + + // Do not include root directory as parent + if fname != cw.source && pname != cw.source { + _, ok := cw.addedDirs[parent] + if !ok { + cw.addedDirs[parent] = struct{}{} + fi, err := os.Stat(pname) + if err != nil { + return err + } + if err := cw.HandleChange(fs.ChangeKindModify, parent, fi, nil); err != nil { + return err + } + } + } + if hdr.Typeflag == tar.TypeDir { + cw.addedDirs[name] = struct{}{} + } + return nil +} + func copyBuffered(ctx context.Context, dst io.Writer, src io.Reader) (written int64, err error) { - buf := bufferPool.Get().(*[]byte) - defer bufferPool.Put(buf) + buf := bufPool.Get().(*[]byte) + defer bufPool.Put(buf) for { select { diff --git a/components/engine/vendor/github.com/containerd/containerd/archive/tar_opts.go b/components/engine/vendor/github.com/containerd/containerd/archive/tar_opts.go new file mode 100644 index 0000000000..b0f86abdff --- /dev/null +++ b/components/engine/vendor/github.com/containerd/containerd/archive/tar_opts.go @@ -0,0 +1,20 @@ +/* + 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 archive + +// ApplyOpt allows setting mutable archive apply properties on creation +type ApplyOpt func(options *ApplyOptions) error diff --git a/components/engine/vendor/github.com/containerd/containerd/archive/tar_opts_unix.go b/components/engine/vendor/github.com/containerd/containerd/archive/tar_opts_unix.go new file mode 100644 index 0000000000..e19afddd25 --- /dev/null +++ b/components/engine/vendor/github.com/containerd/containerd/archive/tar_opts_unix.go @@ -0,0 +1,23 @@ +// +build !windows + +/* + 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 archive + +// ApplyOptions provides additional options for an Apply operation +type ApplyOptions struct { +} diff --git a/components/engine/vendor/github.com/containerd/containerd/archive/tar_opts_windows.go b/components/engine/vendor/github.com/containerd/containerd/archive/tar_opts_windows.go new file mode 100644 index 0000000000..0991ab0945 --- /dev/null +++ b/components/engine/vendor/github.com/containerd/containerd/archive/tar_opts_windows.go @@ -0,0 +1,44 @@ +// +build windows + +/* + 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 archive + +// ApplyOptions provides additional options for an Apply operation +type ApplyOptions struct { + ParentLayerPaths []string // Parent layer paths used for Windows layer apply + IsWindowsContainerLayer bool // True if the tar stream to be applied is a Windows Container Layer +} + +// WithParentLayers adds parent layers to the apply process this is required +// for all Windows layers except the base layer. +func WithParentLayers(parentPaths []string) ApplyOpt { + return func(options *ApplyOptions) error { + options.ParentLayerPaths = parentPaths + return nil + } +} + +// AsWindowsContainerLayer indicates that the tar stream to apply is that of +// a Windows Container Layer. The caller must be holding SeBackupPrivilege and +// SeRestorePrivilege. +func AsWindowsContainerLayer() ApplyOpt { + return func(options *ApplyOptions) error { + options.IsWindowsContainerLayer = true + return nil + } +} diff --git a/components/engine/vendor/github.com/containerd/containerd/archive/tar_unix.go b/components/engine/vendor/github.com/containerd/containerd/archive/tar_unix.go index 44b1069432..f577996ee0 100644 --- a/components/engine/vendor/github.com/containerd/containerd/archive/tar_unix.go +++ b/components/engine/vendor/github.com/containerd/containerd/archive/tar_unix.go @@ -1,8 +1,25 @@ // +build !windows +/* + 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 archive import ( + "context" "os" "sync" "syscall" @@ -28,11 +45,14 @@ func setHeaderForSpecialDevice(hdr *tar.Header, name string, fi os.FileInfo) err return errors.New("unsupported stat type") } + // Rdev is int32 on darwin/bsd, int64 on linux/solaris + rdev := uint64(s.Rdev) // nolint: unconvert + // Currently go does not fill in the major/minors if s.Mode&syscall.S_IFBLK != 0 || s.Mode&syscall.S_IFCHR != 0 { - hdr.Devmajor = int64(unix.Major(uint64(s.Rdev))) - hdr.Devminor = int64(unix.Minor(uint64(s.Rdev))) + hdr.Devmajor = int64(unix.Major(rdev)) + hdr.Devminor = int64(unix.Minor(rdev)) } return nil @@ -128,3 +148,9 @@ func getxattr(path, attr string) ([]byte, error) { func setxattr(path, key, value string) error { return sysx.LSetxattr(path, key, []byte(value), 0) } + +// apply applies a tar stream of an OCI style diff tar. +// See https://github.com/opencontainers/image-spec/blob/master/layer.md#applying-changesets +func apply(ctx context.Context, root string, tr *tar.Reader, options ApplyOptions) (size int64, err error) { + return applyNaive(ctx, root, tr, options) +} diff --git a/components/engine/vendor/github.com/containerd/containerd/archive/tar_windows.go b/components/engine/vendor/github.com/containerd/containerd/archive/tar_windows.go index cb3b6c59a9..7172e735c0 100644 --- a/components/engine/vendor/github.com/containerd/containerd/archive/tar_windows.go +++ b/components/engine/vendor/github.com/containerd/containerd/archive/tar_windows.go @@ -1,15 +1,71 @@ +// +build windows + +/* + 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 archive import ( + "bufio" + "context" + "encoding/base64" "errors" "fmt" + "io" "os" + "path" + "path/filepath" + "strconv" "strings" + "syscall" + "github.com/Microsoft/go-winio" + "github.com/Microsoft/hcsshim" + "github.com/containerd/containerd/log" "github.com/containerd/containerd/sys" "github.com/dmcgowan/go-tar" ) +const ( + // MSWINDOWS pax vendor extensions + hdrMSWindowsPrefix = "MSWINDOWS." + + hdrFileAttributes = hdrMSWindowsPrefix + "fileattr" + hdrSecurityDescriptor = hdrMSWindowsPrefix + "sd" + hdrRawSecurityDescriptor = hdrMSWindowsPrefix + "rawsd" + hdrMountPoint = hdrMSWindowsPrefix + "mountpoint" + hdrEaPrefix = hdrMSWindowsPrefix + "xattr." + + // LIBARCHIVE pax vendor extensions + hdrLibArchivePrefix = "LIBARCHIVE." + + hdrCreateTime = hdrLibArchivePrefix + "creationtime" +) + +var ( + // mutatedFiles is a list of files that are mutated by the import process + // and must be backed up and restored. + mutatedFiles = map[string]string{ + "UtilityVM/Files/EFI/Microsoft/Boot/BCD": "bcd.bak", + "UtilityVM/Files/EFI/Microsoft/Boot/BCD.LOG": "bcd.log.bak", + "UtilityVM/Files/EFI/Microsoft/Boot/BCD.LOG1": "bcd.log1.bak", + "UtilityVM/Files/EFI/Microsoft/Boot/BCD.LOG2": "bcd.log2.bak", + } +) + // tarName returns platform-specific filepath // to canonical posix-style path for tar archival. p is relative // path. @@ -101,3 +157,290 @@ func setxattr(path, key, value string) error { // since xattrs should not exist in windows diff archives return errors.New("xattrs not supported on Windows") } + +// apply applies a tar stream of an OCI style diff tar of a Windows layer. +// See https://github.com/opencontainers/image-spec/blob/master/layer.md#applying-changesets +func apply(ctx context.Context, root string, tr *tar.Reader, options ApplyOptions) (size int64, err error) { + if options.IsWindowsContainerLayer { + return applyWindowsLayer(ctx, root, tr, options) + } + return applyNaive(ctx, root, tr, options) +} + +// applyWindowsLayer applies a tar stream of an OCI style diff tar of a Windows layer. +// See https://github.com/opencontainers/image-spec/blob/master/layer.md#applying-changesets +func applyWindowsLayer(ctx context.Context, root string, tr *tar.Reader, options ApplyOptions) (size int64, err error) { + home, id := filepath.Split(root) + info := hcsshim.DriverInfo{ + HomeDir: home, + } + + w, err := hcsshim.NewLayerWriter(info, id, options.ParentLayerPaths) + if err != nil { + return 0, err + } + defer func() { + if err := w.Close(); err != nil { + log.G(ctx).Errorf("failed to close layer writer: %v", err) + } + }() + + buf := bufio.NewWriter(nil) + hdr, nextErr := tr.Next() + // Iterate through the files in the archive. + for { + select { + case <-ctx.Done(): + return 0, ctx.Err() + default: + } + + if nextErr == io.EOF { + // end of tar archive + break + } + if nextErr != nil { + return 0, nextErr + } + + // Note: path is used instead of filepath to prevent OS specific handling + // of the tar path + base := path.Base(hdr.Name) + if strings.HasPrefix(base, whiteoutPrefix) { + dir := path.Dir(hdr.Name) + originalBase := base[len(whiteoutPrefix):] + originalPath := path.Join(dir, originalBase) + if err := w.Remove(filepath.FromSlash(originalPath)); err != nil { + return 0, err + } + hdr, nextErr = tr.Next() + } else if hdr.Typeflag == tar.TypeLink { + err := w.AddLink(filepath.FromSlash(hdr.Name), filepath.FromSlash(hdr.Linkname)) + if err != nil { + return 0, err + } + hdr, nextErr = tr.Next() + } else { + name, fileSize, fileInfo, err := fileInfoFromHeader(hdr) + if err != nil { + return 0, err + } + if err := w.Add(filepath.FromSlash(name), fileInfo); err != nil { + return 0, err + } + size += fileSize + hdr, nextErr = tarToBackupStreamWithMutatedFiles(buf, w, tr, hdr, root) + } + } + + return +} + +// fileInfoFromHeader retrieves basic Win32 file information from a tar header, using the additional metadata written by +// WriteTarFileFromBackupStream. +func fileInfoFromHeader(hdr *tar.Header) (name string, size int64, fileInfo *winio.FileBasicInfo, err error) { + name = hdr.Name + if hdr.Typeflag == tar.TypeReg || hdr.Typeflag == tar.TypeRegA { + size = hdr.Size + } + fileInfo = &winio.FileBasicInfo{ + LastAccessTime: syscall.NsecToFiletime(hdr.AccessTime.UnixNano()), + LastWriteTime: syscall.NsecToFiletime(hdr.ModTime.UnixNano()), + ChangeTime: syscall.NsecToFiletime(hdr.ChangeTime.UnixNano()), + + // Default CreationTime to ModTime, updated below if MSWINDOWS.createtime exists + CreationTime: syscall.NsecToFiletime(hdr.ModTime.UnixNano()), + } + if attrStr, ok := hdr.PAXRecords[hdrFileAttributes]; ok { + attr, err := strconv.ParseUint(attrStr, 10, 32) + if err != nil { + return "", 0, nil, err + } + fileInfo.FileAttributes = uintptr(attr) + } else { + if hdr.Typeflag == tar.TypeDir { + fileInfo.FileAttributes |= syscall.FILE_ATTRIBUTE_DIRECTORY + } + } + if createStr, ok := hdr.PAXRecords[hdrCreateTime]; ok { + createTime, err := parsePAXTime(createStr) + if err != nil { + return "", 0, nil, err + } + fileInfo.CreationTime = syscall.NsecToFiletime(createTime.UnixNano()) + } + return +} + +// tarToBackupStreamWithMutatedFiles reads data from a tar stream and +// writes it to a backup stream, and also saves any files that will be mutated +// by the import layer process to a backup location. +func tarToBackupStreamWithMutatedFiles(buf *bufio.Writer, w io.Writer, t *tar.Reader, hdr *tar.Header, root string) (nextHdr *tar.Header, err error) { + var ( + bcdBackup *os.File + bcdBackupWriter *winio.BackupFileWriter + ) + if backupPath, ok := mutatedFiles[hdr.Name]; ok { + bcdBackup, err = os.Create(filepath.Join(root, backupPath)) + if err != nil { + return nil, err + } + defer func() { + cerr := bcdBackup.Close() + if err == nil { + err = cerr + } + }() + + bcdBackupWriter = winio.NewBackupFileWriter(bcdBackup, false) + defer func() { + cerr := bcdBackupWriter.Close() + if err == nil { + err = cerr + } + }() + + buf.Reset(io.MultiWriter(w, bcdBackupWriter)) + } else { + buf.Reset(w) + } + + defer func() { + ferr := buf.Flush() + if err == nil { + err = ferr + } + }() + + return writeBackupStreamFromTarFile(buf, t, hdr) +} + +// writeBackupStreamFromTarFile writes a Win32 backup stream from the current tar file. Since this function may process multiple +// tar file entries in order to collect all the alternate data streams for the file, it returns the next +// tar file that was not processed, or io.EOF is there are no more. +func writeBackupStreamFromTarFile(w io.Writer, t *tar.Reader, hdr *tar.Header) (*tar.Header, error) { + bw := winio.NewBackupStreamWriter(w) + var sd []byte + var err error + // Maintaining old SDDL-based behavior for backward compatibility. All new tar headers written + // by this library will have raw binary for the security descriptor. + if sddl, ok := hdr.PAXRecords[hdrSecurityDescriptor]; ok { + sd, err = winio.SddlToSecurityDescriptor(sddl) + if err != nil { + return nil, err + } + } + if sdraw, ok := hdr.PAXRecords[hdrRawSecurityDescriptor]; ok { + sd, err = base64.StdEncoding.DecodeString(sdraw) + if err != nil { + return nil, err + } + } + if len(sd) != 0 { + bhdr := winio.BackupHeader{ + Id: winio.BackupSecurity, + Size: int64(len(sd)), + } + err := bw.WriteHeader(&bhdr) + if err != nil { + return nil, err + } + _, err = bw.Write(sd) + if err != nil { + return nil, err + } + } + var eas []winio.ExtendedAttribute + for k, v := range hdr.PAXRecords { + if !strings.HasPrefix(k, hdrEaPrefix) { + continue + } + data, err := base64.StdEncoding.DecodeString(v) + if err != nil { + return nil, err + } + eas = append(eas, winio.ExtendedAttribute{ + Name: k[len(hdrEaPrefix):], + Value: data, + }) + } + if len(eas) != 0 { + eadata, err := winio.EncodeExtendedAttributes(eas) + if err != nil { + return nil, err + } + bhdr := winio.BackupHeader{ + Id: winio.BackupEaData, + Size: int64(len(eadata)), + } + err = bw.WriteHeader(&bhdr) + if err != nil { + return nil, err + } + _, err = bw.Write(eadata) + if err != nil { + return nil, err + } + } + if hdr.Typeflag == tar.TypeSymlink { + _, isMountPoint := hdr.PAXRecords[hdrMountPoint] + rp := winio.ReparsePoint{ + Target: filepath.FromSlash(hdr.Linkname), + IsMountPoint: isMountPoint, + } + reparse := winio.EncodeReparsePoint(&rp) + bhdr := winio.BackupHeader{ + Id: winio.BackupReparseData, + Size: int64(len(reparse)), + } + err := bw.WriteHeader(&bhdr) + if err != nil { + return nil, err + } + _, err = bw.Write(reparse) + if err != nil { + return nil, err + } + } + + buf := bufPool.Get().(*[]byte) + defer bufPool.Put(buf) + + if hdr.Typeflag == tar.TypeReg || hdr.Typeflag == tar.TypeRegA { + bhdr := winio.BackupHeader{ + Id: winio.BackupData, + Size: hdr.Size, + } + err := bw.WriteHeader(&bhdr) + if err != nil { + return nil, err + } + _, err = io.CopyBuffer(bw, t, *buf) + if err != nil { + return nil, err + } + } + // Copy all the alternate data streams and return the next non-ADS header. + for { + ahdr, err := t.Next() + if err != nil { + return nil, err + } + if ahdr.Typeflag != tar.TypeReg || !strings.HasPrefix(ahdr.Name, hdr.Name+":") { + return ahdr, nil + } + bhdr := winio.BackupHeader{ + Id: winio.BackupAlternateData, + Size: ahdr.Size, + Name: ahdr.Name[len(hdr.Name):] + ":$DATA", + } + err = bw.WriteHeader(&bhdr) + if err != nil { + return nil, err + } + _, err = io.CopyBuffer(bw, t, *buf) + if err != nil { + return nil, err + } + } +} diff --git a/components/engine/vendor/github.com/containerd/containerd/archive/time.go b/components/engine/vendor/github.com/containerd/containerd/archive/time.go index 4e9ae95084..16651a4d05 100644 --- a/components/engine/vendor/github.com/containerd/containerd/archive/time.go +++ b/components/engine/vendor/github.com/containerd/containerd/archive/time.go @@ -1,3 +1,19 @@ +/* + 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 archive import ( diff --git a/components/engine/vendor/github.com/containerd/containerd/archive/time_darwin.go b/components/engine/vendor/github.com/containerd/containerd/archive/time_darwin.go index 2ac517a91c..9c2b656b04 100644 --- a/components/engine/vendor/github.com/containerd/containerd/archive/time_darwin.go +++ b/components/engine/vendor/github.com/containerd/containerd/archive/time_darwin.go @@ -1,3 +1,19 @@ +/* + 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 archive import ( diff --git a/components/engine/vendor/github.com/containerd/containerd/archive/time_unix.go b/components/engine/vendor/github.com/containerd/containerd/archive/time_unix.go index 054f06eba5..4a69cb7d0e 100644 --- a/components/engine/vendor/github.com/containerd/containerd/archive/time_unix.go +++ b/components/engine/vendor/github.com/containerd/containerd/archive/time_unix.go @@ -1,5 +1,21 @@ // +build linux 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 archive import ( diff --git a/components/engine/vendor/github.com/containerd/containerd/archive/time_windows.go b/components/engine/vendor/github.com/containerd/containerd/archive/time_windows.go index 0b18c348d2..71f397821a 100644 --- a/components/engine/vendor/github.com/containerd/containerd/archive/time_windows.go +++ b/components/engine/vendor/github.com/containerd/containerd/archive/time_windows.go @@ -1,3 +1,19 @@ +/* + 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 archive import ( diff --git a/components/engine/vendor/github.com/containerd/containerd/cio/io.go b/components/engine/vendor/github.com/containerd/containerd/cio/io.go index 1b4a4dc251..a49c11735b 100644 --- a/components/engine/vendor/github.com/containerd/containerd/cio/io.go +++ b/components/engine/vendor/github.com/containerd/containerd/cio/io.go @@ -1,3 +1,19 @@ +/* + 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 cio import ( @@ -6,8 +22,17 @@ import ( "io" "os" "sync" + + "github.com/containerd/containerd/defaults" ) +var bufPool = sync.Pool{ + New: func() interface{} { + buffer := make([]byte, 32<<10) + return &buffer + }, +} + // Config holds the IO configurations. type Config struct { // Terminal is true if one has been allocated @@ -68,6 +93,7 @@ type Streams struct { Stdout io.Writer Stderr io.Writer Terminal bool + FIFODir string } // Opt customize options for creating a Creator or Attach @@ -92,16 +118,25 @@ func WithStreams(stdin io.Reader, stdout, stderr io.Writer) Opt { } } +// WithFIFODir sets the fifo directory. +// e.g. "/run/containerd/fifo", "/run/users/1001/containerd/fifo" +func WithFIFODir(dir string) Opt { + return func(opt *Streams) { + opt.FIFODir = dir + } +} + // NewCreator returns an IO creator from the options func NewCreator(opts ...Opt) Creator { streams := &Streams{} for _, opt := range opts { opt(streams) } + if streams.FIFODir == "" { + streams.FIFODir = defaults.DefaultFIFODir + } return func(id string) (IO, error) { - // TODO: accept root as a param - root := "/run/containerd/fifo" - fifos, err := NewFIFOSetInDir(root, id, streams.Terminal) + fifos, err := NewFIFOSetInDir(streams.FIFODir, id, streams.Terminal) if err != nil { return nil, err } diff --git a/components/engine/vendor/github.com/containerd/containerd/cio/io_unix.go b/components/engine/vendor/github.com/containerd/containerd/cio/io_unix.go index 005fb0ce98..3ab2a30b0c 100644 --- a/components/engine/vendor/github.com/containerd/containerd/cio/io_unix.go +++ b/components/engine/vendor/github.com/containerd/containerd/cio/io_unix.go @@ -1,5 +1,21 @@ // +build !windows +/* + 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 cio import ( @@ -47,7 +63,10 @@ func copyIO(fifos *FIFOSet, ioset *Streams) (*cio, error) { if fifos.Stdin != "" { go func() { - io.Copy(pipes.Stdin, ioset.Stdin) + p := bufPool.Get().(*[]byte) + defer bufPool.Put(p) + + io.CopyBuffer(pipes.Stdin, ioset.Stdin, *p) pipes.Stdin.Close() }() } @@ -55,7 +74,10 @@ func copyIO(fifos *FIFOSet, ioset *Streams) (*cio, error) { var wg = &sync.WaitGroup{} wg.Add(1) go func() { - io.Copy(ioset.Stdout, pipes.Stdout) + p := bufPool.Get().(*[]byte) + defer bufPool.Put(p) + + io.CopyBuffer(ioset.Stdout, pipes.Stdout, *p) pipes.Stdout.Close() wg.Done() }() @@ -63,7 +85,10 @@ func copyIO(fifos *FIFOSet, ioset *Streams) (*cio, error) { if !fifos.Terminal { wg.Add(1) go func() { - io.Copy(ioset.Stderr, pipes.Stderr) + p := bufPool.Get().(*[]byte) + defer bufPool.Put(p) + + io.CopyBuffer(ioset.Stderr, pipes.Stderr, *p) pipes.Stderr.Close() wg.Done() }() @@ -89,17 +114,24 @@ func openFifos(ctx context.Context, fifos *FIFOSet) (pipes, error) { if f.Stdin, err = fifo.OpenFifo(ctx, fifos.Stdin, syscall.O_WRONLY|syscall.O_CREAT|syscall.O_NONBLOCK, 0700); err != nil { return f, errors.Wrapf(err, "failed to open stdin fifo") } + defer func() { + if err != nil && f.Stdin != nil { + f.Stdin.Close() + } + }() } if fifos.Stdout != "" { if f.Stdout, err = fifo.OpenFifo(ctx, fifos.Stdout, syscall.O_RDONLY|syscall.O_CREAT|syscall.O_NONBLOCK, 0700); err != nil { - f.Stdin.Close() return f, errors.Wrapf(err, "failed to open stdout fifo") } + defer func() { + if err != nil && f.Stdout != nil { + f.Stdout.Close() + } + }() } if fifos.Stderr != "" { if f.Stderr, err = fifo.OpenFifo(ctx, fifos.Stderr, syscall.O_RDONLY|syscall.O_CREAT|syscall.O_NONBLOCK, 0700); err != nil { - f.Stdin.Close() - f.Stdout.Close() return f, errors.Wrapf(err, "failed to open stderr fifo") } } diff --git a/components/engine/vendor/github.com/containerd/containerd/cio/io_windows.go b/components/engine/vendor/github.com/containerd/containerd/cio/io_windows.go index 017c9a11f6..fa9532a3bd 100644 --- a/components/engine/vendor/github.com/containerd/containerd/cio/io_windows.go +++ b/components/engine/vendor/github.com/containerd/containerd/cio/io_windows.go @@ -1,3 +1,19 @@ +/* + 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 cio import ( @@ -47,7 +63,11 @@ func copyIO(fifos *FIFOSet, ioset *Streams) (*cio, error) { log.L.WithError(err).Errorf("failed to accept stdin connection on %s", fifos.Stdin) return } - io.Copy(c, ioset.Stdin) + + p := bufPool.Get().(*[]byte) + defer bufPool.Put(p) + + io.CopyBuffer(c, ioset.Stdin, *p) c.Close() l.Close() }() @@ -73,7 +93,11 @@ func copyIO(fifos *FIFOSet, ioset *Streams) (*cio, error) { log.L.WithError(err).Errorf("failed to accept stdout connection on %s", fifos.Stdout) return } - io.Copy(ioset.Stdout, c) + + p := bufPool.Get().(*[]byte) + defer bufPool.Put(p) + + io.CopyBuffer(ioset.Stdout, c, *p) c.Close() l.Close() }() @@ -99,7 +123,11 @@ func copyIO(fifos *FIFOSet, ioset *Streams) (*cio, error) { log.L.WithError(err).Errorf("failed to accept stderr connection on %s", fifos.Stderr) return } - io.Copy(ioset.Stderr, c) + + p := bufPool.Get().(*[]byte) + defer bufPool.Put(p) + + io.CopyBuffer(ioset.Stderr, c, *p) c.Close() l.Close() }() diff --git a/components/engine/vendor/github.com/containerd/containerd/client.go b/components/engine/vendor/github.com/containerd/containerd/client.go index 39547f589a..2ac256dd9d 100644 --- a/components/engine/vendor/github.com/containerd/containerd/client.go +++ b/components/engine/vendor/github.com/containerd/containerd/client.go @@ -1,3 +1,19 @@ +/* + 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 ( @@ -7,8 +23,6 @@ import ( "net/http" "runtime" "strconv" - "strings" - "sync" "time" containersapi "github.com/containerd/containerd/api/services/containers/v1" @@ -24,7 +38,6 @@ import ( "github.com/containerd/containerd/containers" "github.com/containerd/containerd/content" "github.com/containerd/containerd/dialer" - "github.com/containerd/containerd/diff" "github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/images" "github.com/containerd/containerd/namespaces" @@ -80,11 +93,22 @@ func New(address string, opts ...ClientOpt) (*Client, error) { grpc.WithStreamInterceptor(stream), ) } - conn, err := grpc.Dial(dialer.DialAddress(address), gopts...) - if err != nil { - return nil, errors.Wrapf(err, "failed to dial %q", address) + connector := func() (*grpc.ClientConn, error) { + conn, err := grpc.Dial(dialer.DialAddress(address), gopts...) + if err != nil { + return nil, errors.Wrapf(err, "failed to dial %q", address) + } + return conn, nil } - return NewWithConn(conn, opts...) + conn, err := connector() + if err != nil { + return nil, err + } + return &Client{ + conn: conn, + connector: connector, + runtime: fmt.Sprintf("%s.%s", plugin.RuntimePlugin, runtime.GOOS), + }, nil } // NewWithConn returns a new containerd client that is connected to the containerd @@ -99,8 +123,23 @@ func NewWithConn(conn *grpc.ClientConn, opts ...ClientOpt) (*Client, error) { // Client is the client to interact with containerd and its various services // using a uniform interface type Client struct { - conn *grpc.ClientConn - runtime string + conn *grpc.ClientConn + runtime string + connector func() (*grpc.ClientConn, error) +} + +// Reconnect re-establishes the GRPC connection to the containerd daemon +func (c *Client) Reconnect() error { + if c.connector == nil { + return errors.New("unable to reconnect to containerd, no connector available") + } + c.conn.Close() + conn, err := c.connector() + if err != nil { + return err + } + c.conn = conn + return nil } // IsServing returns true if the client can successfully connect to the @@ -222,11 +261,11 @@ func (c *Client) Pull(ctx context.Context, ref string, opts ...RemoteOpt) (Image name, desc, err := pullCtx.Resolver.Resolve(ctx, ref) if err != nil { - return nil, err + return nil, errors.Wrapf(err, "failed to resolve reference %q", ref) } fetcher, err := pullCtx.Resolver.Fetcher(ctx, name) if err != nil { - return nil, err + return nil, errors.Wrapf(err, "failed to get fetcher for %q", name) } var ( @@ -237,10 +276,17 @@ func (c *Client) Pull(ctx context.Context, ref string, opts ...RemoteOpt) (Image schema1Converter = schema1.NewConverter(store, fetcher) handler = images.Handlers(append(pullCtx.BaseHandlers, schema1Converter)...) } 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 the childen by the platform + childrenHandler = images.FilterPlatform(platforms.Default(), childrenHandler) + handler = images.Handlers(append(pullCtx.BaseHandlers, remotes.FetchHandler(store, fetcher), - images.ChildrenHandler(store, platforms.Default()))..., - ) + childrenHandler, + )...) } if err := images.Dispatch(ctx, handler, desc); err != nil { @@ -281,7 +327,7 @@ func (c *Client) Pull(ctx context.Context, ref string, opts ...RemoteOpt) (Image } if pullCtx.Unpack { if err := img.Unpack(ctx, pullCtx.Snapshotter); err != nil { - return nil, err + errors.Wrapf(err, "failed to unpack image on snapshotter %s", pullCtx.Snapshotter) } } return img, nil @@ -301,51 +347,7 @@ func (c *Client) Push(ctx context.Context, ref string, desc ocispec.Descriptor, return err } - var m sync.Mutex - manifestStack := []ocispec.Descriptor{} - - filterHandler := images.HandlerFunc(func(ctx context.Context, desc ocispec.Descriptor) ([]ocispec.Descriptor, error) { - switch desc.MediaType { - case images.MediaTypeDockerSchema2Manifest, ocispec.MediaTypeImageManifest, - images.MediaTypeDockerSchema2ManifestList, ocispec.MediaTypeImageIndex: - m.Lock() - manifestStack = append(manifestStack, desc) - m.Unlock() - return nil, images.ErrStopHandler - default: - return nil, nil - } - }) - - cs := c.ContentStore() - pushHandler := remotes.PushHandler(cs, pusher) - - handlers := append(pushCtx.BaseHandlers, - images.ChildrenHandler(cs, platforms.Default()), - filterHandler, - pushHandler, - ) - - if err := images.Dispatch(ctx, images.Handlers(handlers...), desc); err != nil { - return err - } - - // Iterate in reverse order as seen, parent always uploaded after child - for i := len(manifestStack) - 1; i >= 0; i-- { - _, err := pushHandler(ctx, manifestStack[i]) - if err != nil { - // TODO(estesp): until we have a more complete method for index push, we need to report - // missing dependencies in an index/manifest list by sensing the "400 Bad Request" - // as a marker for this problem - if (manifestStack[i].MediaType == ocispec.MediaTypeImageIndex || - manifestStack[i].MediaType == images.MediaTypeDockerSchema2ManifestList) && - errors.Cause(err) != nil && strings.Contains(errors.Cause(err).Error(), "400 Bad Request") { - return errors.Wrap(err, "manifest list/index references to blobs and/or manifests are missing in your target registry") - } - return err - } - } - return nil + return remotes.PushContent(ctx, pusher, desc, c.ContentStore(), pushCtx.BaseHandlers...) } // GetImage returns an existing image @@ -378,11 +380,11 @@ func (c *Client) ListImages(ctx context.Context, filters ...string) ([]Image, er // Subscribe to events that match one or more of the provided filters. // -// Callers should listen on both the envelope channel and errs channel. If the -// errs channel returns nil or an error, the subscriber should terminate. +// Callers should listen on both the envelope and errs channels. If the errs +// channel returns nil or an error, the subscriber should terminate. // -// To cancel shutdown reciept of events, cancel the provided context. The errs -// channel will be closed and return a nil error. +// The subscriber can stop receiving events by canceling the provided context. +// The errs channel will be closed and return a nil error. func (c *Client) Subscribe(ctx context.Context, filters ...string) (ch <-chan *eventsapi.Envelope, errs <-chan error) { var ( evq = make(chan *eventsapi.Envelope) @@ -458,7 +460,7 @@ func (c *Client) ImageService() images.Store { } // DiffService returns the underlying Differ -func (c *Client) DiffService() diff.Differ { +func (c *Client) DiffService() DiffService { return NewDiffServiceFromClient(diffapi.NewDiffClient(c.conn)) } diff --git a/components/engine/vendor/github.com/containerd/containerd/client_opts.go b/components/engine/vendor/github.com/containerd/containerd/client_opts.go index c1e93bae92..dfa02ee7be 100644 --- a/components/engine/vendor/github.com/containerd/containerd/client_opts.go +++ b/components/engine/vendor/github.com/containerd/containerd/client_opts.go @@ -1,3 +1,19 @@ +/* + 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 ( diff --git a/components/engine/vendor/github.com/containerd/containerd/container.go b/components/engine/vendor/github.com/containerd/containerd/container.go index ad60c69eac..895e793ae7 100644 --- a/components/engine/vendor/github.com/containerd/containerd/container.go +++ b/components/engine/vendor/github.com/containerd/containerd/container.go @@ -1,3 +1,19 @@ +/* + 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 ( diff --git a/components/engine/vendor/github.com/containerd/containerd/container_opts.go b/components/engine/vendor/github.com/containerd/containerd/container_opts.go index fb22a90963..4f586a4ecd 100644 --- a/components/engine/vendor/github.com/containerd/containerd/container_opts.go +++ b/components/engine/vendor/github.com/containerd/containerd/container_opts.go @@ -1,3 +1,19 @@ +/* + 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 ( diff --git a/components/engine/vendor/github.com/containerd/containerd/container_opts_unix.go b/components/engine/vendor/github.com/containerd/containerd/container_opts_unix.go index b678033b7e..8ae9551132 100644 --- a/components/engine/vendor/github.com/containerd/containerd/container_opts_unix.go +++ b/components/engine/vendor/github.com/containerd/containerd/container_opts_unix.go @@ -1,12 +1,27 @@ // +build !windows +/* + 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" "encoding/json" "fmt" - "io/ioutil" "os" "path/filepath" "syscall" @@ -16,6 +31,7 @@ import ( "github.com/containerd/containerd/content" "github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/images" + "github.com/containerd/containerd/linux/runctypes" "github.com/containerd/containerd/mount" "github.com/containerd/containerd/platforms" "github.com/gogo/protobuf/proto" @@ -115,7 +131,7 @@ func WithTaskCheckpoint(im Image) NewTaskOpts { } } -func decodeIndex(ctx context.Context, store content.Store, id digest.Digest) (*v1.Index, error) { +func decodeIndex(ctx context.Context, store content.Provider, id digest.Digest) (*v1.Index, error) { var index v1.Index p, err := content.ReadBlob(ctx, store, id) if err != nil { @@ -166,7 +182,7 @@ func withRemappedSnapshotBase(id string, i Image, uid, gid uint32, readonly bool if err != nil { return err } - if err := remapRootFS(mounts, uid, gid); err != nil { + if err := remapRootFS(ctx, mounts, uid, gid); err != nil { snapshotter.Remove(ctx, usernsID) return err } @@ -187,22 +203,10 @@ func withRemappedSnapshotBase(id string, i Image, uid, gid uint32, readonly bool } } -func remapRootFS(mounts []mount.Mount, uid, gid uint32) error { - root, err := ioutil.TempDir("", "ctd-remap") - if err != nil { - return err - } - defer os.Remove(root) - for _, m := range mounts { - if err := m.Mount(root); err != nil { - return err - } - } - err = filepath.Walk(root, incrementFS(root, uid, gid)) - if uerr := mount.Unmount(root, 0); err == nil { - err = uerr - } - return err +func remapRootFS(ctx context.Context, mounts []mount.Mount, uid, gid uint32) error { + return mount.WithTempMount(ctx, mounts, func(root string) error { + return filepath.Walk(root, incrementFS(root, uid, gid)) + }) } func incrementFS(root string, uidInc, gidInc uint32) filepath.WalkFunc { @@ -218,3 +222,19 @@ func incrementFS(root string, uidInc, gidInc uint32) filepath.WalkFunc { return os.Lchown(path, u, g) } } + +// WithNoPivotRoot instructs the runtime not to you pivot_root +func WithNoPivotRoot(_ context.Context, _ *Client, info *TaskInfo) error { + if info.Options == nil { + info.Options = &runctypes.CreateOptions{ + NoPivotRoot: true, + } + return nil + } + copts, ok := info.Options.(*runctypes.CreateOptions) + if !ok { + return errors.New("invalid options type, expected runctypes.CreateOptions") + } + copts.NoPivotRoot = true + return nil +} diff --git a/components/engine/vendor/github.com/containerd/containerd/containers/containers.go b/components/engine/vendor/github.com/containerd/containerd/containers/containers.go index df4ad83c9e..c624164e80 100644 --- a/components/engine/vendor/github.com/containerd/containerd/containers/containers.go +++ b/components/engine/vendor/github.com/containerd/containerd/containers/containers.go @@ -1,3 +1,19 @@ +/* + 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 containers import ( diff --git a/components/engine/vendor/github.com/containerd/containerd/containerstore.go b/components/engine/vendor/github.com/containerd/containerd/containerstore.go index 4db2350b08..ee3d8c7278 100644 --- a/components/engine/vendor/github.com/containerd/containerd/containerstore.go +++ b/components/engine/vendor/github.com/containerd/containerd/containerstore.go @@ -1,3 +1,19 @@ +/* + 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 ( diff --git a/components/engine/vendor/github.com/containerd/containerd/content/content.go b/components/engine/vendor/github.com/containerd/containerd/content/content.go index 05fd4aebe1..de9dd48f55 100644 --- a/components/engine/vendor/github.com/containerd/containerd/content/content.go +++ b/components/engine/vendor/github.com/containerd/containerd/content/content.go @@ -1,3 +1,19 @@ +/* + 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 content import ( diff --git a/components/engine/vendor/github.com/containerd/containerd/content/helpers.go b/components/engine/vendor/github.com/containerd/containerd/content/helpers.go index 83c31d917e..ac0b5a3dbe 100644 --- a/components/engine/vendor/github.com/containerd/containerd/content/helpers.go +++ b/components/engine/vendor/github.com/containerd/containerd/content/helpers.go @@ -1,8 +1,25 @@ +/* + 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 content import ( "context" "io" + "io/ioutil" "sync" "github.com/containerd/containerd/errdefs" @@ -76,14 +93,7 @@ func Copy(ctx context.Context, cw Writer, r io.Reader, size int64, expected dige if ws.Offset > 0 { r, err = seekReader(r, ws.Offset, size) if err != nil { - if !isUnseekable(err) { - return errors.Wrapf(err, "unable to resume write to %v", ws.Ref) - } - - // reader is unseekable, try to move the writer back to the start. - if err := cw.Truncate(0); err != nil { - return errors.Wrapf(err, "content writer truncate failed") - } + return errors.Wrapf(err, "unable to resume write to %v", ws.Ref) } } @@ -103,14 +113,9 @@ func Copy(ctx context.Context, cw Writer, r io.Reader, size int64, expected dige return nil } -var errUnseekable = errors.New("seek not supported") - -func isUnseekable(err error) bool { - return errors.Cause(err) == errUnseekable -} - // seekReader attempts to seek the reader to the given offset, either by -// resolving `io.Seeker` or by detecting `io.ReaderAt`. +// resolving `io.Seeker`, by detecting `io.ReaderAt`, or discarding +// up to the given offset. func seekReader(r io.Reader, offset, size int64) (io.Reader, error) { // attempt to resolve r as a seeker and setup the offset. seeker, ok := r.(io.Seeker) @@ -134,5 +139,17 @@ func seekReader(r io.Reader, offset, size int64) (io.Reader, error) { return sr, nil } - return r, errors.Wrapf(errUnseekable, "seek to offset %v failed", offset) + // well then, let's just discard up to the offset + buf := bufPool.Get().(*[]byte) + defer bufPool.Put(buf) + + n, err := io.CopyBuffer(ioutil.Discard, io.LimitReader(r, offset), *buf) + if err != nil { + return nil, errors.Wrap(err, "failed to discard to offset") + } + if n != offset { + return nil, errors.Errorf("unable to discard to offset") + } + + return r, nil } diff --git a/components/engine/vendor/github.com/containerd/containerd/content/local/locks.go b/components/engine/vendor/github.com/containerd/containerd/content/local/locks.go index 9a6c62fd85..411c29a9d9 100644 --- a/components/engine/vendor/github.com/containerd/containerd/content/local/locks.go +++ b/components/engine/vendor/github.com/containerd/containerd/content/local/locks.go @@ -1,3 +1,19 @@ +/* + 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 local import ( diff --git a/components/engine/vendor/github.com/containerd/containerd/content/local/readerat.go b/components/engine/vendor/github.com/containerd/containerd/content/local/readerat.go index ae1af5d8d4..42b99dc42b 100644 --- a/components/engine/vendor/github.com/containerd/containerd/content/local/readerat.go +++ b/components/engine/vendor/github.com/containerd/containerd/content/local/readerat.go @@ -1,3 +1,19 @@ +/* + 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 local import ( diff --git a/components/engine/vendor/github.com/containerd/containerd/content/local/store.go b/components/engine/vendor/github.com/containerd/containerd/content/local/store.go index 9ff95de457..69437dfd19 100644 --- a/components/engine/vendor/github.com/containerd/containerd/content/local/store.go +++ b/components/engine/vendor/github.com/containerd/containerd/content/local/store.go @@ -1,3 +1,19 @@ +/* + 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 local import ( diff --git a/components/engine/vendor/github.com/containerd/containerd/content/local/store_unix.go b/components/engine/vendor/github.com/containerd/containerd/content/local/store_unix.go index c0587e1b23..f5f34fd0cd 100644 --- a/components/engine/vendor/github.com/containerd/containerd/content/local/store_unix.go +++ b/components/engine/vendor/github.com/containerd/containerd/content/local/store_unix.go @@ -1,5 +1,21 @@ // +build linux solaris darwin freebsd +/* + 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 local import ( @@ -12,8 +28,7 @@ import ( func getATime(fi os.FileInfo) time.Time { if st, ok := fi.Sys().(*syscall.Stat_t); ok { - return time.Unix(int64(sys.StatAtime(st).Sec), - int64(sys.StatAtime(st).Nsec)) + return sys.StatATimeAsTime(st) } return fi.ModTime() diff --git a/components/engine/vendor/github.com/containerd/containerd/content/local/store_windows.go b/components/engine/vendor/github.com/containerd/containerd/content/local/store_windows.go index f745aafdbd..bce8499790 100644 --- a/components/engine/vendor/github.com/containerd/containerd/content/local/store_windows.go +++ b/components/engine/vendor/github.com/containerd/containerd/content/local/store_windows.go @@ -1,3 +1,19 @@ +/* + 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 local import ( diff --git a/components/engine/vendor/github.com/containerd/containerd/content/local/writer.go b/components/engine/vendor/github.com/containerd/containerd/content/local/writer.go index e6b4276b42..a6579a9d21 100644 --- a/components/engine/vendor/github.com/containerd/containerd/content/local/writer.go +++ b/components/engine/vendor/github.com/containerd/containerd/content/local/writer.go @@ -1,3 +1,19 @@ +/* + 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 local import ( diff --git a/components/engine/vendor/github.com/containerd/containerd/content_reader.go b/components/engine/vendor/github.com/containerd/containerd/content_reader.go index 7acd2d30e8..72628e6ca3 100644 --- a/components/engine/vendor/github.com/containerd/containerd/content_reader.go +++ b/components/engine/vendor/github.com/containerd/containerd/content_reader.go @@ -1,3 +1,19 @@ +/* + 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 ( diff --git a/components/engine/vendor/github.com/containerd/containerd/content_store.go b/components/engine/vendor/github.com/containerd/containerd/content_store.go index 1b539694d1..790249c2bf 100644 --- a/components/engine/vendor/github.com/containerd/containerd/content_store.go +++ b/components/engine/vendor/github.com/containerd/containerd/content_store.go @@ -1,3 +1,19 @@ +/* + 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 ( diff --git a/components/engine/vendor/github.com/containerd/containerd/content_writer.go b/components/engine/vendor/github.com/containerd/containerd/content_writer.go index b18f3512a2..a4247daa09 100644 --- a/components/engine/vendor/github.com/containerd/containerd/content_writer.go +++ b/components/engine/vendor/github.com/containerd/containerd/content_writer.go @@ -1,3 +1,19 @@ +/* + 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 ( diff --git a/components/engine/vendor/github.com/containerd/containerd/defaults/defaults_unix.go b/components/engine/vendor/github.com/containerd/containerd/defaults/defaults_unix.go new file mode 100644 index 0000000000..30ed42235e --- /dev/null +++ b/components/engine/vendor/github.com/containerd/containerd/defaults/defaults_unix.go @@ -0,0 +1,35 @@ +// +build !windows + +/* + 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 defaults + +const ( + // DefaultRootDir is the default location used by containerd to store + // persistent data + DefaultRootDir = "/var/lib/containerd" + // DefaultStateDir is the default location used by containerd to store + // transient data + DefaultStateDir = "/run/containerd" + // DefaultAddress is the default unix socket address + DefaultAddress = "/run/containerd/containerd.sock" + // DefaultDebugAddress is the default unix socket address for pprof data + DefaultDebugAddress = "/run/containerd/debug.sock" + // DefaultFIFODir is the default location used by client-side cio library + // to store FIFOs. + DefaultFIFODir = "/run/containerd/fifo" +) diff --git a/components/engine/vendor/github.com/containerd/containerd/defaults/defaults_windows.go b/components/engine/vendor/github.com/containerd/containerd/defaults/defaults_windows.go new file mode 100644 index 0000000000..983bf762f7 --- /dev/null +++ b/components/engine/vendor/github.com/containerd/containerd/defaults/defaults_windows.go @@ -0,0 +1,43 @@ +// +build windows + +/* + 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 defaults + +import ( + "os" + "path/filepath" +) + +var ( + // DefaultRootDir is the default location used by containerd to store + // persistent data + DefaultRootDir = filepath.Join(os.Getenv("programfiles"), "containerd", "root") + // DefaultStateDir is the default location used by containerd to store + // transient data + DefaultStateDir = filepath.Join(os.Getenv("programfiles"), "containerd", "state") +) + +const ( + // DefaultAddress is the default winpipe address + DefaultAddress = `\\.\pipe\containerd-containerd` + // DefaultDebugAddress is the default winpipe address for pprof data + DefaultDebugAddress = `\\.\pipe\containerd-debug` + // DefaultFIFODir is the default location used by client-side cio library + // to store FIFOs. Unused on Windows. + DefaultFIFODir = "" +) diff --git a/components/engine/vendor/github.com/containerd/containerd/defaults/doc.go b/components/engine/vendor/github.com/containerd/containerd/defaults/doc.go new file mode 100644 index 0000000000..274d504a38 --- /dev/null +++ b/components/engine/vendor/github.com/containerd/containerd/defaults/doc.go @@ -0,0 +1,19 @@ +/* + 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 defaults provides several common defaults for interacting wtih +// containerd. These can be used on the client-side or server-side. +package defaults diff --git a/components/engine/vendor/github.com/containerd/containerd/dialer/dialer.go b/components/engine/vendor/github.com/containerd/containerd/dialer/dialer.go index 65af69f9bc..766d344934 100644 --- a/components/engine/vendor/github.com/containerd/containerd/dialer/dialer.go +++ b/components/engine/vendor/github.com/containerd/containerd/dialer/dialer.go @@ -1,3 +1,19 @@ +/* + 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 dialer import ( @@ -42,7 +58,7 @@ func Dialer(address string, timeout time.Duration) (net.Conn, error) { close(stopC) go func() { dr := <-synC - if dr != nil { + if dr != nil && dr.c != nil { dr.c.Close() } }() diff --git a/components/engine/vendor/github.com/containerd/containerd/dialer/dialer_unix.go b/components/engine/vendor/github.com/containerd/containerd/dialer/dialer_unix.go index 7f8d43b031..e7d1958339 100644 --- a/components/engine/vendor/github.com/containerd/containerd/dialer/dialer_unix.go +++ b/components/engine/vendor/github.com/containerd/containerd/dialer/dialer_unix.go @@ -1,5 +1,21 @@ // +build !windows +/* + 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 dialer import ( diff --git a/components/engine/vendor/github.com/containerd/containerd/dialer/dialer_windows.go b/components/engine/vendor/github.com/containerd/containerd/dialer/dialer_windows.go index 2aac03898a..64d30dea0c 100644 --- a/components/engine/vendor/github.com/containerd/containerd/dialer/dialer_windows.go +++ b/components/engine/vendor/github.com/containerd/containerd/dialer/dialer_windows.go @@ -1,3 +1,19 @@ +/* + 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 dialer import ( diff --git a/components/engine/vendor/github.com/containerd/containerd/diff.go b/components/engine/vendor/github.com/containerd/containerd/diff.go index 4e47efafc4..af95e03e7e 100644 --- a/components/engine/vendor/github.com/containerd/containerd/diff.go +++ b/components/engine/vendor/github.com/containerd/containerd/diff.go @@ -1,17 +1,40 @@ +/* + 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" + diffapi "github.com/containerd/containerd/api/services/diff/v1" "github.com/containerd/containerd/api/types" "github.com/containerd/containerd/diff" "github.com/containerd/containerd/mount" ocispec "github.com/opencontainers/image-spec/specs-go/v1" - "golang.org/x/net/context" ) +// DiffService handles the computation and application of diffs +type DiffService interface { + diff.Comparer + diff.Applier +} + // NewDiffServiceFromClient returns a new diff service which communicates // over a GRPC connection. -func NewDiffServiceFromClient(client diffapi.DiffClient) diff.Differ { +func NewDiffServiceFromClient(client diffapi.DiffClient) DiffService { return &diffRemote{ client: client, } @@ -33,7 +56,7 @@ func (r *diffRemote) Apply(ctx context.Context, diff ocispec.Descriptor, mounts return toDescriptor(resp.Applied), nil } -func (r *diffRemote) DiffMounts(ctx context.Context, a, b []mount.Mount, opts ...diff.Opt) (ocispec.Descriptor, error) { +func (r *diffRemote) Compare(ctx context.Context, a, b []mount.Mount, opts ...diff.Opt) (ocispec.Descriptor, error) { var config diff.Config for _, opt := range opts { if err := opt(&config); err != nil { diff --git a/components/engine/vendor/github.com/containerd/containerd/diff/diff.go b/components/engine/vendor/github.com/containerd/containerd/diff/diff.go index 85cef35835..2b6f01c74e 100644 --- a/components/engine/vendor/github.com/containerd/containerd/diff/diff.go +++ b/components/engine/vendor/github.com/containerd/containerd/diff/diff.go @@ -1,9 +1,26 @@ +/* + 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 diff import ( + "context" + "github.com/containerd/containerd/mount" ocispec "github.com/opencontainers/image-spec/specs-go/v1" - "golang.org/x/net/context" ) // Config is used to hold parameters needed for a diff operation @@ -24,21 +41,24 @@ type Config struct { // Opt is used to configure a diff operation type Opt func(*Config) error -// Differ allows the apply and creation of filesystem diffs between mounts -type Differ interface { +// Comparer allows creation of filesystem diffs between mounts +type Comparer interface { + // Compare computes the difference between two mounts and returns a + // descriptor for the computed diff. The options can provide + // a ref which can be used to track the content creation of the diff. + // The media type which is used to determine the format of the created + // content can also be provided as an option. + Compare(ctx context.Context, lower, upper []mount.Mount, opts ...Opt) (ocispec.Descriptor, error) +} + +// Applier allows applying diffs between mounts +type Applier interface { // Apply applies the content referred to by the given descriptor to // the provided mount. The method of applying is based on the // implementation and content descriptor. For example, in the common // case the descriptor is a file system difference in tar format, // that tar would be applied on top of the mounts. Apply(ctx context.Context, desc ocispec.Descriptor, mount []mount.Mount) (ocispec.Descriptor, error) - - // DiffMounts computes the difference between two mounts and returns a - // descriptor for the computed diff. The options can provide - // a ref which can be used to track the content creation of the diff. - // The media type which is used to determine the format of the created - // content can also be provided as an option. - DiffMounts(ctx context.Context, lower, upper []mount.Mount, opts ...Opt) (ocispec.Descriptor, error) } // WithMediaType sets the media type to use for creating the diff, without diff --git a/components/engine/vendor/github.com/containerd/containerd/errdefs/errors.go b/components/engine/vendor/github.com/containerd/containerd/errdefs/errors.go index b4d6ea860b..40427fc5a5 100644 --- a/components/engine/vendor/github.com/containerd/containerd/errdefs/errors.go +++ b/components/engine/vendor/github.com/containerd/containerd/errdefs/errors.go @@ -1,3 +1,19 @@ +/* + 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 errdefs defines the common errors used throughout containerd // packages. // diff --git a/components/engine/vendor/github.com/containerd/containerd/errdefs/grpc.go b/components/engine/vendor/github.com/containerd/containerd/errdefs/grpc.go index 6a3bbcaa14..4eab03ab86 100644 --- a/components/engine/vendor/github.com/containerd/containerd/errdefs/grpc.go +++ b/components/engine/vendor/github.com/containerd/containerd/errdefs/grpc.go @@ -1,3 +1,19 @@ +/* + 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 errdefs import ( diff --git a/components/engine/vendor/github.com/containerd/containerd/events/events.go b/components/engine/vendor/github.com/containerd/containerd/events/events.go index 2bfedb1e83..b7eb86f1eb 100644 --- a/components/engine/vendor/github.com/containerd/containerd/events/events.go +++ b/components/engine/vendor/github.com/containerd/containerd/events/events.go @@ -1,3 +1,19 @@ +/* + 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 events import ( @@ -26,9 +42,9 @@ func (e *Envelope) Field(fieldpath []string) (string, bool) { switch fieldpath[0] { // unhandled: timestamp case "namespace": - return string(e.Namespace), len(e.Namespace) > 0 + return e.Namespace, len(e.Namespace) > 0 case "topic": - return string(e.Topic), len(e.Topic) > 0 + return e.Topic, len(e.Topic) > 0 case "event": decoded, err := typeurl.UnmarshalAny(e.Event) if err != nil { diff --git a/components/engine/vendor/github.com/containerd/containerd/events/exchange/exchange.go b/components/engine/vendor/github.com/containerd/containerd/events/exchange/exchange.go index 3178fc407a..51c760f045 100644 --- a/components/engine/vendor/github.com/containerd/containerd/events/exchange/exchange.go +++ b/components/engine/vendor/github.com/containerd/containerd/events/exchange/exchange.go @@ -1,3 +1,19 @@ +/* + 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 exchange import ( diff --git a/components/engine/vendor/github.com/containerd/containerd/filters/adaptor.go b/components/engine/vendor/github.com/containerd/containerd/filters/adaptor.go index 5a5ac7ec13..5a9c559c1e 100644 --- a/components/engine/vendor/github.com/containerd/containerd/filters/adaptor.go +++ b/components/engine/vendor/github.com/containerd/containerd/filters/adaptor.go @@ -1,3 +1,19 @@ +/* + 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 filters // Adaptor specifies the mapping of fieldpaths to a type. For the given field diff --git a/components/engine/vendor/github.com/containerd/containerd/filters/filter.go b/components/engine/vendor/github.com/containerd/containerd/filters/filter.go index 621755762d..30debadc96 100644 --- a/components/engine/vendor/github.com/containerd/containerd/filters/filter.go +++ b/components/engine/vendor/github.com/containerd/containerd/filters/filter.go @@ -1,3 +1,19 @@ +/* + 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 filters defines a syntax and parser that can be used for the // filtration of items across the containerd API. The core is built on the // concept of protobuf field paths, with quoting. Several operators allow the diff --git a/components/engine/vendor/github.com/containerd/containerd/filters/parser.go b/components/engine/vendor/github.com/containerd/containerd/filters/parser.go index c765ea00c8..9dced523b1 100644 --- a/components/engine/vendor/github.com/containerd/containerd/filters/parser.go +++ b/components/engine/vendor/github.com/containerd/containerd/filters/parser.go @@ -1,3 +1,19 @@ +/* + 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 filters import ( diff --git a/components/engine/vendor/github.com/containerd/containerd/filters/quote.go b/components/engine/vendor/github.com/containerd/containerd/filters/quote.go index 08698e1ba5..2d64e23a30 100644 --- a/components/engine/vendor/github.com/containerd/containerd/filters/quote.go +++ b/components/engine/vendor/github.com/containerd/containerd/filters/quote.go @@ -1,3 +1,19 @@ +/* + 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 filters import ( diff --git a/components/engine/vendor/github.com/containerd/containerd/filters/scanner.go b/components/engine/vendor/github.com/containerd/containerd/filters/scanner.go index 3a8e72395c..c3961962cc 100644 --- a/components/engine/vendor/github.com/containerd/containerd/filters/scanner.go +++ b/components/engine/vendor/github.com/containerd/containerd/filters/scanner.go @@ -1,3 +1,19 @@ +/* + 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 filters import ( diff --git a/components/engine/vendor/github.com/containerd/containerd/fs/copy.go b/components/engine/vendor/github.com/containerd/containerd/fs/copy.go deleted file mode 100644 index e8f452819b..0000000000 --- a/components/engine/vendor/github.com/containerd/containerd/fs/copy.go +++ /dev/null @@ -1,119 +0,0 @@ -package fs - -import ( - "io/ioutil" - "os" - "path/filepath" - "sync" - - "github.com/pkg/errors" -) - -var bufferPool = &sync.Pool{ - New: func() interface{} { - buffer := make([]byte, 32*1024) - return &buffer - }, -} - -// CopyDir copies the directory from src to dst. -// Most efficient copy of files is attempted. -func CopyDir(dst, src string) error { - inodes := map[uint64]string{} - return copyDirectory(dst, src, inodes) -} - -func copyDirectory(dst, src string, inodes map[uint64]string) error { - stat, err := os.Stat(src) - if err != nil { - return errors.Wrapf(err, "failed to stat %s", src) - } - if !stat.IsDir() { - return errors.Errorf("source is not directory") - } - - if st, err := os.Stat(dst); err != nil { - if err := os.Mkdir(dst, stat.Mode()); err != nil { - return errors.Wrapf(err, "failed to mkdir %s", dst) - } - } else if !st.IsDir() { - return errors.Errorf("cannot copy to non-directory: %s", dst) - } else { - if err := os.Chmod(dst, stat.Mode()); err != nil { - return errors.Wrapf(err, "failed to chmod on %s", dst) - } - } - - fis, err := ioutil.ReadDir(src) - if err != nil { - return errors.Wrapf(err, "failed to read %s", src) - } - - if err := copyFileInfo(stat, dst); err != nil { - return errors.Wrapf(err, "failed to copy file info for %s", dst) - } - - for _, fi := range fis { - source := filepath.Join(src, fi.Name()) - target := filepath.Join(dst, fi.Name()) - - switch { - case fi.IsDir(): - if err := copyDirectory(target, source, inodes); err != nil { - return err - } - continue - case (fi.Mode() & os.ModeType) == 0: - link, err := getLinkSource(target, fi, inodes) - if err != nil { - return errors.Wrap(err, "failed to get hardlink") - } - if link != "" { - if err := os.Link(link, target); err != nil { - return errors.Wrap(err, "failed to create hard link") - } - } else if err := copyFile(source, target); err != nil { - return errors.Wrap(err, "failed to copy files") - } - case (fi.Mode() & os.ModeSymlink) == os.ModeSymlink: - link, err := os.Readlink(source) - if err != nil { - return errors.Wrapf(err, "failed to read link: %s", source) - } - if err := os.Symlink(link, target); err != nil { - return errors.Wrapf(err, "failed to create symlink: %s", target) - } - case (fi.Mode() & os.ModeDevice) == os.ModeDevice: - if err := copyDevice(target, fi); err != nil { - return errors.Wrapf(err, "failed to create device") - } - default: - // TODO: Support pipes and sockets - return errors.Wrapf(err, "unsupported mode %s", fi.Mode()) - } - if err := copyFileInfo(fi, target); err != nil { - return errors.Wrap(err, "failed to copy file info") - } - - if err := copyXAttrs(target, source); err != nil { - return errors.Wrap(err, "failed to copy xattrs") - } - } - - return nil -} - -func copyFile(source, target string) error { - src, err := os.Open(source) - if err != nil { - return errors.Wrapf(err, "failed to open source %s", source) - } - defer src.Close() - tgt, err := os.Create(target) - if err != nil { - return errors.Wrapf(err, "failed to open target %s", target) - } - defer tgt.Close() - - return copyFileContent(tgt, src) -} diff --git a/components/engine/vendor/github.com/containerd/containerd/fs/copy_linux.go b/components/engine/vendor/github.com/containerd/containerd/fs/copy_linux.go deleted file mode 100644 index c1fb2d1c40..0000000000 --- a/components/engine/vendor/github.com/containerd/containerd/fs/copy_linux.go +++ /dev/null @@ -1,83 +0,0 @@ -package fs - -import ( - "io" - "os" - "syscall" - - "github.com/containerd/containerd/sys" - "github.com/containerd/continuity/sysx" - "github.com/pkg/errors" - "golang.org/x/sys/unix" -) - -func copyFileInfo(fi os.FileInfo, name string) error { - st := fi.Sys().(*syscall.Stat_t) - if err := os.Lchown(name, int(st.Uid), int(st.Gid)); err != nil { - return errors.Wrapf(err, "failed to chown %s", name) - } - - if (fi.Mode() & os.ModeSymlink) != os.ModeSymlink { - if err := os.Chmod(name, fi.Mode()); err != nil { - return errors.Wrapf(err, "failed to chmod %s", name) - } - } - - timespec := []unix.Timespec{unix.Timespec(sys.StatAtime(st)), unix.Timespec(sys.StatMtime(st))} - if err := unix.UtimesNanoAt(unix.AT_FDCWD, name, timespec, unix.AT_SYMLINK_NOFOLLOW); err != nil { - return errors.Wrapf(err, "failed to utime %s", name) - } - - return nil -} - -func copyFileContent(dst, src *os.File) error { - st, err := src.Stat() - if err != nil { - return errors.Wrap(err, "unable to stat source") - } - - n, err := unix.CopyFileRange(int(src.Fd()), nil, int(dst.Fd()), nil, int(st.Size()), 0) - if err != nil { - if err != unix.ENOSYS && err != unix.EXDEV { - return errors.Wrap(err, "copy file range failed") - } - - buf := bufferPool.Get().(*[]byte) - _, err = io.CopyBuffer(dst, src, *buf) - bufferPool.Put(buf) - return err - } - - if int64(n) != st.Size() { - return errors.Wrapf(err, "short copy: %d of %d", int64(n), st.Size()) - } - - return nil -} - -func copyXAttrs(dst, src string) error { - xattrKeys, err := sysx.LListxattr(src) - if err != nil { - return errors.Wrapf(err, "failed to list xattrs on %s", src) - } - for _, xattr := range xattrKeys { - data, err := sysx.LGetxattr(src, xattr) - if err != nil { - return errors.Wrapf(err, "failed to get xattr %q on %s", xattr, src) - } - if err := sysx.LSetxattr(dst, xattr, data, 0); err != nil { - return errors.Wrapf(err, "failed to set xattr %q on %s", xattr, dst) - } - } - - return nil -} - -func copyDevice(dst string, fi os.FileInfo) error { - st, ok := fi.Sys().(*syscall.Stat_t) - if !ok { - return errors.New("unsupported stat type") - } - return unix.Mknod(dst, uint32(fi.Mode()), int(st.Rdev)) -} diff --git a/components/engine/vendor/github.com/containerd/containerd/fs/copy_unix.go b/components/engine/vendor/github.com/containerd/containerd/fs/copy_unix.go deleted file mode 100644 index b31a14fcdb..0000000000 --- a/components/engine/vendor/github.com/containerd/containerd/fs/copy_unix.go +++ /dev/null @@ -1,68 +0,0 @@ -// +build solaris darwin freebsd - -package fs - -import ( - "io" - "os" - "syscall" - - "github.com/containerd/containerd/sys" - "github.com/containerd/continuity/sysx" - "github.com/pkg/errors" - "golang.org/x/sys/unix" -) - -func copyFileInfo(fi os.FileInfo, name string) error { - st := fi.Sys().(*syscall.Stat_t) - if err := os.Lchown(name, int(st.Uid), int(st.Gid)); err != nil { - return errors.Wrapf(err, "failed to chown %s", name) - } - - if (fi.Mode() & os.ModeSymlink) != os.ModeSymlink { - if err := os.Chmod(name, fi.Mode()); err != nil { - return errors.Wrapf(err, "failed to chmod %s", name) - } - } - - timespec := []syscall.Timespec{sys.StatAtime(st), sys.StatMtime(st)} - if err := syscall.UtimesNano(name, timespec); err != nil { - return errors.Wrapf(err, "failed to utime %s", name) - } - - return nil -} - -func copyFileContent(dst, src *os.File) error { - buf := bufferPool.Get().(*[]byte) - _, err := io.CopyBuffer(dst, src, *buf) - bufferPool.Put(buf) - - return err -} - -func copyXAttrs(dst, src string) error { - xattrKeys, err := sysx.LListxattr(src) - if err != nil { - return errors.Wrapf(err, "failed to list xattrs on %s", src) - } - for _, xattr := range xattrKeys { - data, err := sysx.LGetxattr(src, xattr) - if err != nil { - return errors.Wrapf(err, "failed to get xattr %q on %s", xattr, src) - } - if err := sysx.LSetxattr(dst, xattr, data, 0); err != nil { - return errors.Wrapf(err, "failed to set xattr %q on %s", xattr, dst) - } - } - - return nil -} - -func copyDevice(dst string, fi os.FileInfo) error { - st, ok := fi.Sys().(*syscall.Stat_t) - if !ok { - return errors.New("unsupported stat type") - } - return unix.Mknod(dst, uint32(fi.Mode()), int(st.Rdev)) -} diff --git a/components/engine/vendor/github.com/containerd/containerd/fs/copy_windows.go b/components/engine/vendor/github.com/containerd/containerd/fs/copy_windows.go deleted file mode 100644 index 6fb3de5710..0000000000 --- a/components/engine/vendor/github.com/containerd/containerd/fs/copy_windows.go +++ /dev/null @@ -1,33 +0,0 @@ -package fs - -import ( - "io" - "os" - - "github.com/pkg/errors" -) - -func copyFileInfo(fi os.FileInfo, name string) error { - if err := os.Chmod(name, fi.Mode()); err != nil { - return errors.Wrapf(err, "failed to chmod %s", name) - } - - // TODO: copy windows specific metadata - - return nil -} - -func copyFileContent(dst, src *os.File) error { - buf := bufferPool.Get().(*[]byte) - _, err := io.CopyBuffer(dst, src, *buf) - bufferPool.Put(buf) - return err -} - -func copyXAttrs(dst, src string) error { - return nil -} - -func copyDevice(dst string, fi os.FileInfo) error { - return errors.New("device copy not supported") -} diff --git a/components/engine/vendor/github.com/containerd/containerd/fs/diff.go b/components/engine/vendor/github.com/containerd/containerd/fs/diff.go deleted file mode 100644 index 3a53f42150..0000000000 --- a/components/engine/vendor/github.com/containerd/containerd/fs/diff.go +++ /dev/null @@ -1,381 +0,0 @@ -package fs - -import ( - "context" - "os" - "path/filepath" - "strings" - - "golang.org/x/sync/errgroup" - - "github.com/sirupsen/logrus" -) - -// ChangeKind is the type of modification that -// a change is making. -type ChangeKind int - -const ( - // ChangeKindUnmodified represents an unmodified - // file - ChangeKindUnmodified = iota - - // ChangeKindAdd represents an addition of - // a file - ChangeKindAdd - - // ChangeKindModify represents a change to - // an existing file - ChangeKindModify - - // ChangeKindDelete represents a delete of - // a file - ChangeKindDelete -) - -func (k ChangeKind) String() string { - switch k { - case ChangeKindUnmodified: - return "unmodified" - case ChangeKindAdd: - return "add" - case ChangeKindModify: - return "modify" - case ChangeKindDelete: - return "delete" - default: - return "" - } -} - -// Change represents single change between a diff and its parent. -type Change struct { - Kind ChangeKind - Path string -} - -// ChangeFunc is the type of function called for each change -// computed during a directory changes calculation. -type ChangeFunc func(ChangeKind, string, os.FileInfo, error) error - -// Changes computes changes between two directories calling the -// given change function for each computed change. The first -// directory is intended to the base directory and second -// directory the changed directory. -// -// The change callback is called by the order of path names and -// should be appliable in that order. -// Due to this apply ordering, the following is true -// - Removed directory trees only create a single change for the root -// directory removed. Remaining changes are implied. -// - A directory which is modified to become a file will not have -// delete entries for sub-path items, their removal is implied -// by the removal of the parent directory. -// -// Opaque directories will not be treated specially and each file -// removed from the base directory will show up as a removal. -// -// File content comparisons will be done on files which have timestamps -// which may have been truncated. If either of the files being compared -// has a zero value nanosecond value, each byte will be compared for -// differences. If 2 files have the same seconds value but different -// nanosecond values where one of those values is zero, the files will -// be considered unchanged if the content is the same. This behavior -// is to account for timestamp truncation during archiving. -func Changes(ctx context.Context, a, b string, changeFn ChangeFunc) error { - if a == "" { - logrus.Debugf("Using single walk diff for %s", b) - return addDirChanges(ctx, changeFn, b) - } else if diffOptions := detectDirDiff(b, a); diffOptions != nil { - logrus.Debugf("Using single walk diff for %s from %s", diffOptions.diffDir, a) - return diffDirChanges(ctx, changeFn, a, diffOptions) - } - - logrus.Debugf("Using double walk diff for %s from %s", b, a) - return doubleWalkDiff(ctx, changeFn, a, b) -} - -func addDirChanges(ctx context.Context, changeFn ChangeFunc, root string) error { - return filepath.Walk(root, func(path string, f os.FileInfo, err error) error { - if err != nil { - return err - } - - // Rebase path - path, err = filepath.Rel(root, path) - if err != nil { - return err - } - - path = filepath.Join(string(os.PathSeparator), path) - - // Skip root - if path == string(os.PathSeparator) { - return nil - } - - return changeFn(ChangeKindAdd, path, f, nil) - }) -} - -// diffDirOptions is used when the diff can be directly calculated from -// a diff directory to its base, without walking both trees. -type diffDirOptions struct { - diffDir string - skipChange func(string) (bool, error) - deleteChange func(string, string, os.FileInfo) (string, error) -} - -// diffDirChanges walks the diff directory and compares changes against the base. -func diffDirChanges(ctx context.Context, changeFn ChangeFunc, base string, o *diffDirOptions) error { - changedDirs := make(map[string]struct{}) - return filepath.Walk(o.diffDir, func(path string, f os.FileInfo, err error) error { - if err != nil { - return err - } - - // Rebase path - path, err = filepath.Rel(o.diffDir, path) - if err != nil { - return err - } - - path = filepath.Join(string(os.PathSeparator), path) - - // Skip root - if path == string(os.PathSeparator) { - return nil - } - - // TODO: handle opaqueness, start new double walker at this - // location to get deletes, and skip tree in single walker - - if o.skipChange != nil { - if skip, err := o.skipChange(path); skip { - return err - } - } - - var kind ChangeKind - - deletedFile, err := o.deleteChange(o.diffDir, path, f) - if err != nil { - return err - } - - // Find out what kind of modification happened - if deletedFile != "" { - path = deletedFile - kind = ChangeKindDelete - f = nil - } else { - // Otherwise, the file was added - kind = ChangeKindAdd - - // ...Unless it already existed in a base, in which case, it's a modification - stat, err := os.Stat(filepath.Join(base, path)) - if err != nil && !os.IsNotExist(err) { - return err - } - if err == nil { - // The file existed in the base, so that's a modification - - // However, if it's a directory, maybe it wasn't actually modified. - // If you modify /foo/bar/baz, then /foo will be part of the changed files only because it's the parent of bar - if stat.IsDir() && f.IsDir() { - if f.Size() == stat.Size() && f.Mode() == stat.Mode() && sameFsTime(f.ModTime(), stat.ModTime()) { - // Both directories are the same, don't record the change - return nil - } - } - kind = ChangeKindModify - } - } - - // If /foo/bar/file.txt is modified, then /foo/bar must be part of the changed files. - // This block is here to ensure the change is recorded even if the - // modify time, mode and size of the parent directory in the rw and ro layers are all equal. - // Check https://github.com/docker/docker/pull/13590 for details. - if f.IsDir() { - changedDirs[path] = struct{}{} - } - if kind == ChangeKindAdd || kind == ChangeKindDelete { - parent := filepath.Dir(path) - if _, ok := changedDirs[parent]; !ok && parent != "/" { - pi, err := os.Stat(filepath.Join(o.diffDir, parent)) - if err := changeFn(ChangeKindModify, parent, pi, err); err != nil { - return err - } - changedDirs[parent] = struct{}{} - } - } - - return changeFn(kind, path, f, nil) - }) -} - -// doubleWalkDiff walks both directories to create a diff -func doubleWalkDiff(ctx context.Context, changeFn ChangeFunc, a, b string) (err error) { - g, ctx := errgroup.WithContext(ctx) - - var ( - c1 = make(chan *currentPath) - c2 = make(chan *currentPath) - - f1, f2 *currentPath - rmdir string - lastEmittedDir = string(filepath.Separator) - parents []os.FileInfo - ) - g.Go(func() error { - defer close(c1) - return pathWalk(ctx, a, c1) - }) - g.Go(func() error { - defer close(c2) - return pathWalk(ctx, b, c2) - }) - g.Go(func() error { - for c1 != nil || c2 != nil { - if f1 == nil && c1 != nil { - f1, err = nextPath(ctx, c1) - if err != nil { - return err - } - if f1 == nil { - c1 = nil - } - } - - if f2 == nil && c2 != nil { - f2, err = nextPath(ctx, c2) - if err != nil { - return err - } - if f2 == nil { - c2 = nil - } - } - if f1 == nil && f2 == nil { - continue - } - - var ( - f os.FileInfo - emit = true - ) - k, p := pathChange(f1, f2) - switch k { - case ChangeKindAdd: - if rmdir != "" { - rmdir = "" - } - f = f2.f - f2 = nil - case ChangeKindDelete: - // Check if this file is already removed by being - // under of a removed directory - if rmdir != "" && strings.HasPrefix(f1.path, rmdir) { - f1 = nil - continue - } else if rmdir == "" && f1.f.IsDir() { - rmdir = f1.path + string(os.PathSeparator) - } else if rmdir != "" { - rmdir = "" - } - f1 = nil - case ChangeKindModify: - same, err := sameFile(f1, f2) - if err != nil { - return err - } - if f1.f.IsDir() && !f2.f.IsDir() { - rmdir = f1.path + string(os.PathSeparator) - } else if rmdir != "" { - rmdir = "" - } - f = f2.f - f1 = nil - f2 = nil - if same { - if !isLinked(f) { - emit = false - } - k = ChangeKindUnmodified - } - } - if emit { - emittedDir, emitParents := commonParents(lastEmittedDir, p, parents) - for _, pf := range emitParents { - p := filepath.Join(emittedDir, pf.Name()) - if err := changeFn(ChangeKindUnmodified, p, pf, nil); err != nil { - return err - } - emittedDir = p - } - - if err := changeFn(k, p, f, nil); err != nil { - return err - } - - if f != nil && f.IsDir() { - lastEmittedDir = p - } else { - lastEmittedDir = emittedDir - } - - parents = parents[:0] - } else if f.IsDir() { - lastEmittedDir, parents = commonParents(lastEmittedDir, p, parents) - parents = append(parents, f) - } - } - return nil - }) - - return g.Wait() -} - -func commonParents(base, updated string, dirs []os.FileInfo) (string, []os.FileInfo) { - if basePrefix := makePrefix(base); strings.HasPrefix(updated, basePrefix) { - var ( - parents []os.FileInfo - last = base - ) - for _, d := range dirs { - next := filepath.Join(last, d.Name()) - if strings.HasPrefix(updated, makePrefix(last)) { - parents = append(parents, d) - last = next - } else { - break - } - } - return base, parents - } - - baseS := strings.Split(base, string(filepath.Separator)) - updatedS := strings.Split(updated, string(filepath.Separator)) - commonS := []string{string(filepath.Separator)} - - min := len(baseS) - if len(updatedS) < min { - min = len(updatedS) - } - for i := 0; i < min; i++ { - if baseS[i] == updatedS[i] { - commonS = append(commonS, baseS[i]) - } else { - break - } - } - - return filepath.Join(commonS...), []os.FileInfo{} -} - -func makePrefix(d string) string { - if d == "" || d[len(d)-1] != filepath.Separator { - return d + string(filepath.Separator) - } - return d -} diff --git a/components/engine/vendor/github.com/containerd/containerd/fs/diff_unix.go b/components/engine/vendor/github.com/containerd/containerd/fs/diff_unix.go deleted file mode 100644 index 3751814443..0000000000 --- a/components/engine/vendor/github.com/containerd/containerd/fs/diff_unix.go +++ /dev/null @@ -1,58 +0,0 @@ -// +build !windows - -package fs - -import ( - "bytes" - "os" - "syscall" - - "github.com/containerd/continuity/sysx" - "github.com/pkg/errors" -) - -// detectDirDiff returns diff dir options if a directory could -// be found in the mount info for upper which is the direct -// diff with the provided lower directory -func detectDirDiff(upper, lower string) *diffDirOptions { - // TODO: get mount options for upper - // TODO: detect AUFS - // TODO: detect overlay - return nil -} - -// compareSysStat returns whether the stats are equivalent, -// whether the files are considered the same file, and -// an error -func compareSysStat(s1, s2 interface{}) (bool, error) { - ls1, ok := s1.(*syscall.Stat_t) - if !ok { - return false, nil - } - ls2, ok := s2.(*syscall.Stat_t) - if !ok { - return false, nil - } - - return ls1.Mode == ls2.Mode && ls1.Uid == ls2.Uid && ls1.Gid == ls2.Gid && ls1.Rdev == ls2.Rdev, nil -} - -func compareCapabilities(p1, p2 string) (bool, error) { - c1, err := sysx.LGetxattr(p1, "security.capability") - if err != nil && err != sysx.ENODATA { - return false, errors.Wrapf(err, "failed to get xattr for %s", p1) - } - c2, err := sysx.LGetxattr(p2, "security.capability") - if err != nil && err != sysx.ENODATA { - return false, errors.Wrapf(err, "failed to get xattr for %s", p2) - } - return bytes.Equal(c1, c2), nil -} - -func isLinked(f os.FileInfo) bool { - s, ok := f.Sys().(*syscall.Stat_t) - if !ok { - return false - } - return !f.IsDir() && s.Nlink > 1 -} diff --git a/components/engine/vendor/github.com/containerd/containerd/fs/diff_windows.go b/components/engine/vendor/github.com/containerd/containerd/fs/diff_windows.go deleted file mode 100644 index 8eed36507e..0000000000 --- a/components/engine/vendor/github.com/containerd/containerd/fs/diff_windows.go +++ /dev/null @@ -1,32 +0,0 @@ -package fs - -import ( - "os" - - "golang.org/x/sys/windows" -) - -func detectDirDiff(upper, lower string) *diffDirOptions { - return nil -} - -func compareSysStat(s1, s2 interface{}) (bool, error) { - f1, ok := s1.(windows.Win32FileAttributeData) - if !ok { - return false, nil - } - f2, ok := s2.(windows.Win32FileAttributeData) - if !ok { - return false, nil - } - return f1.FileAttributes == f2.FileAttributes, nil -} - -func compareCapabilities(p1, p2 string) (bool, error) { - // TODO: Use windows equivalent - return true, nil -} - -func isLinked(os.FileInfo) bool { - return false -} diff --git a/components/engine/vendor/github.com/containerd/containerd/fs/dtype_linux.go b/components/engine/vendor/github.com/containerd/containerd/fs/dtype_linux.go deleted file mode 100644 index cc06573f1b..0000000000 --- a/components/engine/vendor/github.com/containerd/containerd/fs/dtype_linux.go +++ /dev/null @@ -1,87 +0,0 @@ -// +build linux - -package fs - -import ( - "fmt" - "io/ioutil" - "os" - "syscall" - "unsafe" -) - -func locateDummyIfEmpty(path string) (string, error) { - children, err := ioutil.ReadDir(path) - if err != nil { - return "", err - } - if len(children) != 0 { - return "", nil - } - dummyFile, err := ioutil.TempFile(path, "fsutils-dummy") - if err != nil { - return "", err - } - name := dummyFile.Name() - err = dummyFile.Close() - return name, err -} - -// SupportsDType returns whether the filesystem mounted on path supports d_type -func SupportsDType(path string) (bool, error) { - // locate dummy so that we have at least one dirent - dummy, err := locateDummyIfEmpty(path) - if err != nil { - return false, err - } - if dummy != "" { - defer os.Remove(dummy) - } - - visited := 0 - supportsDType := true - fn := func(ent *syscall.Dirent) bool { - visited++ - if ent.Type == syscall.DT_UNKNOWN { - supportsDType = false - // stop iteration - return true - } - // continue iteration - return false - } - if err = iterateReadDir(path, fn); err != nil { - return false, err - } - if visited == 0 { - return false, fmt.Errorf("did not hit any dirent during iteration %s", path) - } - return supportsDType, nil -} - -func iterateReadDir(path string, fn func(*syscall.Dirent) bool) error { - d, err := os.Open(path) - if err != nil { - return err - } - defer d.Close() - fd := int(d.Fd()) - buf := make([]byte, 4096) - for { - nbytes, err := syscall.ReadDirent(fd, buf) - if err != nil { - return err - } - if nbytes == 0 { - break - } - for off := 0; off < nbytes; { - ent := (*syscall.Dirent)(unsafe.Pointer(&buf[off])) - if stop := fn(ent); stop { - return nil - } - off += int(ent.Reclen) - } - } - return nil -} diff --git a/components/engine/vendor/github.com/containerd/containerd/fs/du.go b/components/engine/vendor/github.com/containerd/containerd/fs/du.go deleted file mode 100644 index 26f5333154..0000000000 --- a/components/engine/vendor/github.com/containerd/containerd/fs/du.go +++ /dev/null @@ -1,22 +0,0 @@ -package fs - -import "context" - -// Usage of disk information -type Usage struct { - Inodes int64 - Size int64 -} - -// DiskUsage counts the number of inodes and disk usage for the resources under -// path. -func DiskUsage(roots ...string) (Usage, error) { - return diskUsage(roots...) -} - -// DiffUsage counts the numbers of inodes and disk usage in the -// diff between the 2 directories. The first path is intended -// as the base directory and the second as the changed directory. -func DiffUsage(ctx context.Context, a, b string) (Usage, error) { - return diffUsage(ctx, a, b) -} diff --git a/components/engine/vendor/github.com/containerd/containerd/fs/du_unix.go b/components/engine/vendor/github.com/containerd/containerd/fs/du_unix.go deleted file mode 100644 index 6328e80f3a..0000000000 --- a/components/engine/vendor/github.com/containerd/containerd/fs/du_unix.go +++ /dev/null @@ -1,83 +0,0 @@ -// +build !windows - -package fs - -import ( - "context" - "os" - "path/filepath" - "syscall" -) - -type inode struct { - // TODO(stevvooe): Can probably reduce memory usage by not tracking - // device, but we can leave this right for now. - dev, ino uint64 -} - -func diskUsage(roots ...string) (Usage, error) { - - var ( - size int64 - inodes = map[inode]struct{}{} // expensive! - ) - - for _, root := range roots { - if err := filepath.Walk(root, func(path string, fi os.FileInfo, err error) error { - if err != nil { - return err - } - - stat := fi.Sys().(*syscall.Stat_t) - - inoKey := inode{dev: uint64(stat.Dev), ino: uint64(stat.Ino)} - if _, ok := inodes[inoKey]; !ok { - inodes[inoKey] = struct{}{} - size += fi.Size() - } - - return nil - }); err != nil { - return Usage{}, err - } - } - - return Usage{ - Inodes: int64(len(inodes)), - Size: size, - }, nil -} - -func diffUsage(ctx context.Context, a, b string) (Usage, error) { - var ( - size int64 - inodes = map[inode]struct{}{} // expensive! - ) - - if err := Changes(ctx, a, b, func(kind ChangeKind, _ string, fi os.FileInfo, err error) error { - if err != nil { - return err - } - - if kind == ChangeKindAdd || kind == ChangeKindModify { - stat := fi.Sys().(*syscall.Stat_t) - - inoKey := inode{dev: uint64(stat.Dev), ino: uint64(stat.Ino)} - if _, ok := inodes[inoKey]; !ok { - inodes[inoKey] = struct{}{} - size += fi.Size() - } - - return nil - - } - return nil - }); err != nil { - return Usage{}, err - } - - return Usage{ - Inodes: int64(len(inodes)), - Size: size, - }, nil -} diff --git a/components/engine/vendor/github.com/containerd/containerd/fs/du_windows.go b/components/engine/vendor/github.com/containerd/containerd/fs/du_windows.go deleted file mode 100644 index 3f852fc15e..0000000000 --- a/components/engine/vendor/github.com/containerd/containerd/fs/du_windows.go +++ /dev/null @@ -1,60 +0,0 @@ -// +build windows - -package fs - -import ( - "context" - "os" - "path/filepath" -) - -func diskUsage(roots ...string) (Usage, error) { - var ( - size int64 - ) - - // TODO(stevvooe): Support inodes (or equivalent) for windows. - - for _, root := range roots { - if err := filepath.Walk(root, func(path string, fi os.FileInfo, err error) error { - if err != nil { - return err - } - - size += fi.Size() - return nil - }); err != nil { - return Usage{}, err - } - } - - return Usage{ - Size: size, - }, nil -} - -func diffUsage(ctx context.Context, a, b string) (Usage, error) { - var ( - size int64 - ) - - if err := Changes(ctx, a, b, func(kind ChangeKind, _ string, fi os.FileInfo, err error) error { - if err != nil { - return err - } - - if kind == ChangeKindAdd || kind == ChangeKindModify { - size += fi.Size() - - return nil - - } - return nil - }); err != nil { - return Usage{}, err - } - - return Usage{ - Size: size, - }, nil -} diff --git a/components/engine/vendor/github.com/containerd/containerd/fs/hardlink.go b/components/engine/vendor/github.com/containerd/containerd/fs/hardlink.go deleted file mode 100644 index 38da93813c..0000000000 --- a/components/engine/vendor/github.com/containerd/containerd/fs/hardlink.go +++ /dev/null @@ -1,27 +0,0 @@ -package fs - -import "os" - -// GetLinkInfo returns an identifier representing the node a hardlink is pointing -// to. If the file is not hard linked then 0 will be returned. -func GetLinkInfo(fi os.FileInfo) (uint64, bool) { - return getLinkInfo(fi) -} - -// getLinkSource returns a path for the given name and -// file info to its link source in the provided inode -// map. If the given file name is not in the map and -// has other links, it is added to the inode map -// to be a source for other link locations. -func getLinkSource(name string, fi os.FileInfo, inodes map[uint64]string) (string, error) { - inode, isHardlink := getLinkInfo(fi) - if !isHardlink { - return "", nil - } - - path, ok := inodes[inode] - if !ok { - inodes[inode] = name - } - return path, nil -} diff --git a/components/engine/vendor/github.com/containerd/containerd/fs/hardlink_unix.go b/components/engine/vendor/github.com/containerd/containerd/fs/hardlink_unix.go deleted file mode 100644 index 3b825c940b..0000000000 --- a/components/engine/vendor/github.com/containerd/containerd/fs/hardlink_unix.go +++ /dev/null @@ -1,17 +0,0 @@ -// +build !windows - -package fs - -import ( - "os" - "syscall" -) - -func getLinkInfo(fi os.FileInfo) (uint64, bool) { - s, ok := fi.Sys().(*syscall.Stat_t) - if !ok { - return 0, false - } - - return uint64(s.Ino), !fi.IsDir() && s.Nlink > 1 -} diff --git a/components/engine/vendor/github.com/containerd/containerd/fs/hardlink_windows.go b/components/engine/vendor/github.com/containerd/containerd/fs/hardlink_windows.go deleted file mode 100644 index ad8845a7fb..0000000000 --- a/components/engine/vendor/github.com/containerd/containerd/fs/hardlink_windows.go +++ /dev/null @@ -1,7 +0,0 @@ -package fs - -import "os" - -func getLinkInfo(fi os.FileInfo) (uint64, bool) { - return 0, false -} diff --git a/components/engine/vendor/github.com/containerd/containerd/fs/path.go b/components/engine/vendor/github.com/containerd/containerd/fs/path.go deleted file mode 100644 index 412da67115..0000000000 --- a/components/engine/vendor/github.com/containerd/containerd/fs/path.go +++ /dev/null @@ -1,276 +0,0 @@ -package fs - -import ( - "bytes" - "context" - "io" - "os" - "path/filepath" - "strings" - - "github.com/pkg/errors" -) - -var ( - errTooManyLinks = errors.New("too many links") -) - -type currentPath struct { - path string - f os.FileInfo - fullPath string -} - -func pathChange(lower, upper *currentPath) (ChangeKind, string) { - if lower == nil { - if upper == nil { - panic("cannot compare nil paths") - } - return ChangeKindAdd, upper.path - } - if upper == nil { - return ChangeKindDelete, lower.path - } - // TODO: compare by directory - - switch i := strings.Compare(lower.path, upper.path); { - case i < 0: - // File in lower that is not in upper - return ChangeKindDelete, lower.path - case i > 0: - // File in upper that is not in lower - return ChangeKindAdd, upper.path - default: - return ChangeKindModify, upper.path - } -} - -func sameFile(f1, f2 *currentPath) (bool, error) { - if os.SameFile(f1.f, f2.f) { - return true, nil - } - - equalStat, err := compareSysStat(f1.f.Sys(), f2.f.Sys()) - if err != nil || !equalStat { - return equalStat, err - } - - if eq, err := compareCapabilities(f1.fullPath, f2.fullPath); err != nil || !eq { - return eq, err - } - - // If not a directory also check size, modtime, and content - if !f1.f.IsDir() { - if f1.f.Size() != f2.f.Size() { - return false, nil - } - t1 := f1.f.ModTime() - t2 := f2.f.ModTime() - - if t1.Unix() != t2.Unix() { - return false, nil - } - - // If the timestamp may have been truncated in one of the - // files, check content of file to determine difference - if t1.Nanosecond() == 0 || t2.Nanosecond() == 0 { - var eq bool - if (f1.f.Mode() & os.ModeSymlink) == os.ModeSymlink { - eq, err = compareSymlinkTarget(f1.fullPath, f2.fullPath) - } else if f1.f.Size() > 0 { - eq, err = compareFileContent(f1.fullPath, f2.fullPath) - } - if err != nil || !eq { - return eq, err - } - } else if t1.Nanosecond() != t2.Nanosecond() { - return false, nil - } - } - - return true, nil -} - -func compareSymlinkTarget(p1, p2 string) (bool, error) { - t1, err := os.Readlink(p1) - if err != nil { - return false, err - } - t2, err := os.Readlink(p2) - if err != nil { - return false, err - } - return t1 == t2, nil -} - -const compareChuckSize = 32 * 1024 - -// compareFileContent compares the content of 2 same sized files -// by comparing each byte. -func compareFileContent(p1, p2 string) (bool, error) { - f1, err := os.Open(p1) - if err != nil { - return false, err - } - defer f1.Close() - f2, err := os.Open(p2) - if err != nil { - return false, err - } - defer f2.Close() - - b1 := make([]byte, compareChuckSize) - b2 := make([]byte, compareChuckSize) - for { - n1, err1 := f1.Read(b1) - if err1 != nil && err1 != io.EOF { - return false, err1 - } - n2, err2 := f2.Read(b2) - if err2 != nil && err2 != io.EOF { - return false, err2 - } - if n1 != n2 || !bytes.Equal(b1[:n1], b2[:n2]) { - return false, nil - } - if err1 == io.EOF && err2 == io.EOF { - return true, nil - } - } -} - -func pathWalk(ctx context.Context, root string, pathC chan<- *currentPath) error { - return filepath.Walk(root, func(path string, f os.FileInfo, err error) error { - if err != nil { - return err - } - - // Rebase path - path, err = filepath.Rel(root, path) - if err != nil { - return err - } - - path = filepath.Join(string(os.PathSeparator), path) - - // Skip root - if path == string(os.PathSeparator) { - return nil - } - - p := ¤tPath{ - path: path, - f: f, - fullPath: filepath.Join(root, path), - } - - select { - case <-ctx.Done(): - return ctx.Err() - case pathC <- p: - return nil - } - }) -} - -func nextPath(ctx context.Context, pathC <-chan *currentPath) (*currentPath, error) { - select { - case <-ctx.Done(): - return nil, ctx.Err() - case p := <-pathC: - return p, nil - } -} - -// RootPath joins a path with a root, evaluating and bounding any -// symlink to the root directory. -func RootPath(root, path string) (string, error) { - if path == "" { - return root, nil - } - var linksWalked int // to protect against cycles - for { - i := linksWalked - newpath, err := walkLinks(root, path, &linksWalked) - if err != nil { - return "", err - } - path = newpath - if i == linksWalked { - newpath = filepath.Join("/", newpath) - if path == newpath { - return filepath.Join(root, newpath), nil - } - path = newpath - } - } -} - -func walkLink(root, path string, linksWalked *int) (newpath string, islink bool, err error) { - if *linksWalked > 255 { - return "", false, errTooManyLinks - } - - path = filepath.Join("/", path) - if path == "/" { - return path, false, nil - } - realPath := filepath.Join(root, path) - - fi, err := os.Lstat(realPath) - if err != nil { - // If path does not yet exist, treat as non-symlink - if os.IsNotExist(err) { - return path, false, nil - } - return "", false, err - } - if fi.Mode()&os.ModeSymlink == 0 { - return path, false, nil - } - newpath, err = os.Readlink(realPath) - if err != nil { - return "", false, err - } - if filepath.IsAbs(newpath) && strings.HasPrefix(newpath, root) { - newpath = newpath[:len(root)] - if !strings.HasPrefix(newpath, "/") { - newpath = "/" + newpath - } - } - *linksWalked++ - return newpath, true, nil -} - -func walkLinks(root, path string, linksWalked *int) (string, error) { - switch dir, file := filepath.Split(path); { - case dir == "": - newpath, _, err := walkLink(root, file, linksWalked) - return newpath, err - case file == "": - if os.IsPathSeparator(dir[len(dir)-1]) { - if dir == "/" { - return dir, nil - } - return walkLinks(root, dir[:len(dir)-1], linksWalked) - } - newpath, _, err := walkLink(root, dir, linksWalked) - return newpath, err - default: - newdir, err := walkLinks(root, dir, linksWalked) - if err != nil { - return "", err - } - newpath, islink, err := walkLink(root, filepath.Join(newdir, file), linksWalked) - if err != nil { - return "", err - } - if !islink { - return newpath, nil - } - if filepath.IsAbs(newpath) { - return newpath, nil - } - return filepath.Join(newdir, newpath), nil - } -} diff --git a/components/engine/vendor/github.com/containerd/containerd/fs/time.go b/components/engine/vendor/github.com/containerd/containerd/fs/time.go deleted file mode 100644 index c336f4d881..0000000000 --- a/components/engine/vendor/github.com/containerd/containerd/fs/time.go +++ /dev/null @@ -1,13 +0,0 @@ -package fs - -import "time" - -// Gnu tar and the go tar writer don't have sub-second mtime -// precision, which is problematic when we apply changes via tar -// files, we handle this by comparing for exact times, *or* same -// second count and either a or b having exactly 0 nanoseconds -func sameFsTime(a, b time.Time) bool { - return a == b || - (a.Unix() == b.Unix() && - (a.Nanosecond() == 0 || b.Nanosecond() == 0)) -} diff --git a/components/engine/vendor/github.com/containerd/containerd/gc/gc.go b/components/engine/vendor/github.com/containerd/containerd/gc/gc.go index 66898c5deb..35a1712cb3 100644 --- a/components/engine/vendor/github.com/containerd/containerd/gc/gc.go +++ b/components/engine/vendor/github.com/containerd/containerd/gc/gc.go @@ -1,3 +1,19 @@ +/* + 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 gc experiments with providing central gc tooling to ensure // deterministic resource removal within containerd. // @@ -8,6 +24,7 @@ package gc import ( "context" "sync" + "time" ) // ResourceType represents type of resource at a node @@ -21,6 +38,11 @@ type Node struct { Key string } +// Stats about a garbage collection run +type Stats interface { + Elapsed() time.Duration +} + // Tricolor implements basic, single-thread tri-color GC. Given the roots, the // complete set and a refs function, this function returns a map of all // reachable objects. diff --git a/components/engine/vendor/github.com/containerd/containerd/grpc.go b/components/engine/vendor/github.com/containerd/containerd/grpc.go index c56eeada34..05fd5cca24 100644 --- a/components/engine/vendor/github.com/containerd/containerd/grpc.go +++ b/components/engine/vendor/github.com/containerd/containerd/grpc.go @@ -1,3 +1,19 @@ +/* + 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 ( diff --git a/components/engine/vendor/github.com/containerd/containerd/identifiers/validate.go b/components/engine/vendor/github.com/containerd/containerd/identifiers/validate.go index 37f9b72ffa..c58513c025 100644 --- a/components/engine/vendor/github.com/containerd/containerd/identifiers/validate.go +++ b/components/engine/vendor/github.com/containerd/containerd/identifiers/validate.go @@ -1,3 +1,19 @@ +/* + 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 identifiers provides common validation for identifiers and keys // across containerd. // diff --git a/components/engine/vendor/github.com/containerd/containerd/image.go b/components/engine/vendor/github.com/containerd/containerd/image.go index 6e9f4bd19d..5ae6db2323 100644 --- a/components/engine/vendor/github.com/containerd/containerd/image.go +++ b/components/engine/vendor/github.com/containerd/containerd/image.go @@ -1,3 +1,19 @@ +/* + 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 ( diff --git a/components/engine/vendor/github.com/containerd/containerd/image_store.go b/components/engine/vendor/github.com/containerd/containerd/image_store.go index 9a3aafc84f..3676bdadad 100644 --- a/components/engine/vendor/github.com/containerd/containerd/image_store.go +++ b/components/engine/vendor/github.com/containerd/containerd/image_store.go @@ -1,3 +1,19 @@ +/* + 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 ( diff --git a/components/engine/vendor/github.com/containerd/containerd/images/handlers.go b/components/engine/vendor/github.com/containerd/containerd/images/handlers.go index 63acdb7220..b95251c576 100644 --- a/components/engine/vendor/github.com/containerd/containerd/images/handlers.go +++ b/components/engine/vendor/github.com/containerd/containerd/images/handlers.go @@ -1,3 +1,19 @@ +/* + 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 images import ( @@ -5,6 +21,7 @@ import ( "fmt" "github.com/containerd/containerd/content" + "github.com/containerd/containerd/platforms" ocispec "github.com/opencontainers/image-spec/specs-go/v1" "github.com/pkg/errors" "golang.org/x/sync/errgroup" @@ -128,8 +145,78 @@ func Dispatch(ctx context.Context, handler Handler, descs ...ocispec.Descriptor) // // One can also replace this with another implementation to allow descending of // arbitrary types. -func ChildrenHandler(provider content.Provider, platform string) HandlerFunc { +func ChildrenHandler(provider content.Provider) HandlerFunc { return func(ctx context.Context, desc ocispec.Descriptor) ([]ocispec.Descriptor, error) { - return Children(ctx, provider, desc, platform) + return Children(ctx, provider, desc) + } +} + +// SetChildrenLabels is a handler wrapper which sets labels for the content on +// the children returned by the handler and passes through the children. +// Must follow a handler that returns the children to be labeled. +func SetChildrenLabels(manager content.Manager, f HandlerFunc) HandlerFunc { + return func(ctx context.Context, desc ocispec.Descriptor) ([]ocispec.Descriptor, error) { + children, err := f(ctx, desc) + if err != nil { + return children, err + } + + if len(children) > 0 { + info := content.Info{ + Digest: desc.Digest, + Labels: map[string]string{}, + } + fields := []string{} + for i, ch := range children { + info.Labels[fmt.Sprintf("containerd.io/gc.ref.content.%d", i)] = ch.Digest.String() + fields = append(fields, fmt.Sprintf("labels.containerd.io/gc.ref.content.%d", i)) + } + + _, err := manager.Update(ctx, info, fields...) + if err != nil { + return nil, err + } + } + + return children, err + } +} + +// FilterPlatform is a handler wrapper which limits the descriptors returned +// by a handler to a single platform. +func FilterPlatform(platform string, f HandlerFunc) HandlerFunc { + return func(ctx context.Context, desc ocispec.Descriptor) ([]ocispec.Descriptor, error) { + children, err := f(ctx, desc) + if err != nil { + return children, err + } + + var descs []ocispec.Descriptor + if platform != "" && isMultiPlatform(desc.MediaType) { + matcher, err := platforms.Parse(platform) + if err != nil { + return nil, err + } + + for _, d := range children { + if d.Platform == nil || matcher.Match(*d.Platform) { + descs = append(descs, d) + } + } + } else { + descs = children + } + + return descs, nil + } + +} + +func isMultiPlatform(mediaType string) bool { + switch mediaType { + case MediaTypeDockerSchema2ManifestList, ocispec.MediaTypeImageIndex: + return true + default: + return false } } diff --git a/components/engine/vendor/github.com/containerd/containerd/images/image.go b/components/engine/vendor/github.com/containerd/containerd/images/image.go index 7b4215faf6..cdcf0af341 100644 --- a/components/engine/vendor/github.com/containerd/containerd/images/image.go +++ b/components/engine/vendor/github.com/containerd/containerd/images/image.go @@ -1,8 +1,25 @@ +/* + 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 images import ( "context" "encoding/json" + "strings" "time" "github.com/containerd/containerd/content" @@ -101,7 +118,7 @@ func (image *Image) Size(ctx context.Context, provider content.Provider, platfor } size += desc.Size return nil, nil - }), ChildrenHandler(provider, platform)), image.Target) + }), FilterPlatform(platform, ChildrenHandler(provider))), image.Target) } // Manifest resolves a manifest from the image for the given platform. @@ -237,7 +254,7 @@ func Platforms(ctx context.Context, provider content.Provider, image ocispec.Des platforms.Normalize(ocispec.Platform{OS: image.OS, Architecture: image.Architecture})) } return nil, nil - }), ChildrenHandler(provider, "")), image) + }), ChildrenHandler(provider)), image) } // Check returns nil if the all components of an image are available in the @@ -284,7 +301,7 @@ func Check(ctx context.Context, provider content.Provider, image ocispec.Descrip } // Children returns the immediate children of content described by the descriptor. -func Children(ctx context.Context, provider content.Provider, desc ocispec.Descriptor, platform string) ([]ocispec.Descriptor, error) { +func Children(ctx context.Context, provider content.Provider, desc ocispec.Descriptor) ([]ocispec.Descriptor, error) { var descs []ocispec.Descriptor switch desc.MediaType { case MediaTypeDockerSchema2Manifest, ocispec.MediaTypeImageManifest: @@ -313,21 +330,7 @@ func Children(ctx context.Context, provider content.Provider, desc ocispec.Descr return nil, err } - if platform != "" { - matcher, err := platforms.Parse(platform) - if err != nil { - return nil, err - } - - for _, d := range index.Manifests { - if d.Platform == nil || matcher.Match(*d.Platform) { - descs = append(descs, d) - } - } - } else { - descs = append(descs, index.Manifests...) - } - + descs = append(descs, index.Manifests...) case MediaTypeDockerSchema2Layer, MediaTypeDockerSchema2LayerGzip, MediaTypeDockerSchema2LayerForeign, MediaTypeDockerSchema2LayerForeignGzip, MediaTypeDockerSchema2Config, ocispec.MediaTypeImageConfig, @@ -357,13 +360,24 @@ func RootFS(ctx context.Context, provider content.Provider, configDesc ocispec.D if err := json.Unmarshal(p, &config); err != nil { return nil, err } - - // TODO(stevvooe): Remove this bit when OCI structure uses correct type for - // rootfs.DiffIDs. - var diffIDs []digest.Digest - for _, diffID := range config.RootFS.DiffIDs { - diffIDs = append(diffIDs, digest.Digest(diffID)) - } - - return diffIDs, nil + return config.RootFS.DiffIDs, nil +} + +// IsCompressedDiff returns true if mediaType is a known compressed diff media type. +// It returns false if the media type is a diff, but not compressed. If the media type +// is not a known diff type, it returns errdefs.ErrNotImplemented +func IsCompressedDiff(ctx context.Context, mediaType string) (bool, error) { + switch mediaType { + case ocispec.MediaTypeImageLayer, MediaTypeDockerSchema2Layer: + case ocispec.MediaTypeImageLayerGzip, MediaTypeDockerSchema2LayerGzip: + return true, nil + default: + // Still apply all generic media types *.tar[.+]gzip and *.tar + if strings.HasSuffix(mediaType, ".tar.gzip") || strings.HasSuffix(mediaType, ".tar+gzip") { + return true, nil + } else if !strings.HasSuffix(mediaType, ".tar") { + return false, errdefs.ErrNotImplemented + } + } + return false, nil } diff --git a/components/engine/vendor/github.com/containerd/containerd/images/importexport.go b/components/engine/vendor/github.com/containerd/containerd/images/importexport.go index f8cf742bad..04a55fd383 100644 --- a/components/engine/vendor/github.com/containerd/containerd/images/importexport.go +++ b/components/engine/vendor/github.com/containerd/containerd/images/importexport.go @@ -1,3 +1,19 @@ +/* + 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 images import ( @@ -17,5 +33,5 @@ type Importer interface { // Exporter is the interface for image exporter. type Exporter interface { // Export exports an image to a tar stream. - Export(ctx context.Context, store content.Store, desc ocispec.Descriptor, writer io.Writer) error + Export(ctx context.Context, store content.Provider, desc ocispec.Descriptor, writer io.Writer) error } diff --git a/components/engine/vendor/github.com/containerd/containerd/images/mediatypes.go b/components/engine/vendor/github.com/containerd/containerd/images/mediatypes.go index f01f615c4b..ca4ca071b3 100644 --- a/components/engine/vendor/github.com/containerd/containerd/images/mediatypes.go +++ b/components/engine/vendor/github.com/containerd/containerd/images/mediatypes.go @@ -1,3 +1,19 @@ +/* + 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 images // mediatype definitions for image components handled in containerd. diff --git a/components/engine/vendor/github.com/containerd/containerd/labels/validate.go b/components/engine/vendor/github.com/containerd/containerd/labels/validate.go index b05fe1857c..0de461663a 100644 --- a/components/engine/vendor/github.com/containerd/containerd/labels/validate.go +++ b/components/engine/vendor/github.com/containerd/containerd/labels/validate.go @@ -1,3 +1,19 @@ +/* + 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 labels import ( diff --git a/components/engine/vendor/github.com/containerd/containerd/lease.go b/components/engine/vendor/github.com/containerd/containerd/lease.go index 8eb3bc0fe1..6187c1df77 100644 --- a/components/engine/vendor/github.com/containerd/containerd/lease.go +++ b/components/engine/vendor/github.com/containerd/containerd/lease.go @@ -1,3 +1,19 @@ +/* + 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 ( diff --git a/components/engine/vendor/github.com/containerd/containerd/leases/context.go b/components/engine/vendor/github.com/containerd/containerd/leases/context.go index cfd7e4a46e..b66b154ce4 100644 --- a/components/engine/vendor/github.com/containerd/containerd/leases/context.go +++ b/components/engine/vendor/github.com/containerd/containerd/leases/context.go @@ -1,3 +1,19 @@ +/* + 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 leases import "context" diff --git a/components/engine/vendor/github.com/containerd/containerd/leases/grpc.go b/components/engine/vendor/github.com/containerd/containerd/leases/grpc.go index cea5b25feb..284924e7d7 100644 --- a/components/engine/vendor/github.com/containerd/containerd/leases/grpc.go +++ b/components/engine/vendor/github.com/containerd/containerd/leases/grpc.go @@ -1,3 +1,19 @@ +/* + 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 leases import ( diff --git a/components/engine/vendor/github.com/containerd/containerd/linux/bundle.go b/components/engine/vendor/github.com/containerd/containerd/linux/bundle.go index 629d7f5bfb..735547c5c7 100644 --- a/components/engine/vendor/github.com/containerd/containerd/linux/bundle.go +++ b/components/engine/vendor/github.com/containerd/containerd/linux/bundle.go @@ -1,11 +1,26 @@ // +build linux +/* + 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 linux import ( - "bytes" "context" - "io" + "io/ioutil" "os" "path/filepath" @@ -52,12 +67,7 @@ func newBundle(id, path, workDir string, spec []byte) (b *bundle, err error) { if err := os.Mkdir(filepath.Join(path, "rootfs"), 0711); err != nil { return nil, err } - f, err := os.Create(filepath.Join(path, configFilename)) - if err != nil { - return nil, err - } - defer f.Close() - _, err = io.Copy(f, bytes.NewReader(spec)) + err = ioutil.WriteFile(filepath.Join(path, configFilename), spec, 0666) return &bundle{ id: id, path: path, @@ -90,9 +100,9 @@ func ShimLocal(exchange *exchange.Exchange) ShimOpt { } // ShimConnect is a ShimOpt for connecting to an existing remote shim -func ShimConnect() ShimOpt { +func ShimConnect(onClose func()) ShimOpt { return func(b *bundle, ns string, ropts *runctypes.RuncOptions) (shim.Config, client.Opt) { - return b.shimConfig(ns, ropts), client.WithConnect(b.shimAddress(ns)) + return b.shimConfig(ns, ropts), client.WithConnect(b.shimAddress(ns), onClose) } } diff --git a/components/engine/vendor/github.com/containerd/containerd/linux/proc/deleted_state.go b/components/engine/vendor/github.com/containerd/containerd/linux/proc/deleted_state.go index fb25878047..87a3fd0c06 100644 --- a/components/engine/vendor/github.com/containerd/containerd/linux/proc/deleted_state.go +++ b/components/engine/vendor/github.com/containerd/containerd/linux/proc/deleted_state.go @@ -1,5 +1,21 @@ // +build !windows +/* + 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 proc import ( @@ -48,3 +64,7 @@ func (s *deletedState) Kill(ctx context.Context, sig uint32, all bool) error { func (s *deletedState) SetExited(status int) { // no op } + +func (s *deletedState) Exec(ctx context.Context, path string, r *ExecConfig) (Process, error) { + return nil, errors.Errorf("cannot exec in a deleted state") +} diff --git a/components/engine/vendor/github.com/containerd/containerd/linux/proc/exec.go b/components/engine/vendor/github.com/containerd/containerd/linux/proc/exec.go index 00a8547b87..636879da19 100644 --- a/components/engine/vendor/github.com/containerd/containerd/linux/proc/exec.go +++ b/components/engine/vendor/github.com/containerd/containerd/linux/proc/exec.go @@ -1,5 +1,21 @@ // +build !windows +/* + 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 proc import ( diff --git a/components/engine/vendor/github.com/containerd/containerd/linux/proc/exec_state.go b/components/engine/vendor/github.com/containerd/containerd/linux/proc/exec_state.go index 3c3c265829..617ec0d978 100644 --- a/components/engine/vendor/github.com/containerd/containerd/linux/proc/exec_state.go +++ b/components/engine/vendor/github.com/containerd/containerd/linux/proc/exec_state.go @@ -1,5 +1,21 @@ // +build !windows +/* + 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 proc import ( diff --git a/components/engine/vendor/github.com/containerd/containerd/linux/proc/init.go b/components/engine/vendor/github.com/containerd/containerd/linux/proc/init.go index f24f92f7da..82f9ebdf2f 100644 --- a/components/engine/vendor/github.com/containerd/containerd/linux/proc/init.go +++ b/components/engine/vendor/github.com/containerd/containerd/linux/proc/init.go @@ -1,5 +1,21 @@ // +build !windows +/* + 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 proc import ( @@ -346,8 +362,8 @@ func (p *Init) Runtime() *runc.Runc { return p.runtime } -// Exec returns a new exec'd process -func (p *Init) Exec(context context.Context, path string, r *ExecConfig) (Process, error) { +// exec returns a new exec'd process +func (p *Init) exec(context context.Context, path string, r *ExecConfig) (Process, error) { // process exec request var spec specs.Process if err := json.Unmarshal(r.Spec.Value, &spec); err != nil { diff --git a/components/engine/vendor/github.com/containerd/containerd/linux/proc/init_state.go b/components/engine/vendor/github.com/containerd/containerd/linux/proc/init_state.go index b5b398ec39..8944d6192e 100644 --- a/components/engine/vendor/github.com/containerd/containerd/linux/proc/init_state.go +++ b/components/engine/vendor/github.com/containerd/containerd/linux/proc/init_state.go @@ -1,5 +1,21 @@ // +build !windows +/* + 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 proc import ( @@ -22,6 +38,7 @@ type initState interface { Resume(context.Context) error Update(context.Context, *google_protobuf.Any) error Checkpoint(context.Context, *CheckpointConfig) error + Exec(context.Context, string, *ExecConfig) (Process, error) } type createdState struct { @@ -113,6 +130,12 @@ func (s *createdState) SetExited(status int) { } } +func (s *createdState) Exec(ctx context.Context, path string, r *ExecConfig) (Process, error) { + s.p.mu.Lock() + defer s.p.mu.Unlock() + return s.p.exec(ctx, path, r) +} + type createdCheckpointState struct { p *Init opts *runc.RestoreOpts @@ -227,6 +250,13 @@ func (s *createdCheckpointState) SetExited(status int) { } } +func (s *createdCheckpointState) Exec(ctx context.Context, path string, r *ExecConfig) (Process, error) { + s.p.mu.Lock() + defer s.p.mu.Unlock() + + return nil, errors.Errorf("cannot exec in a created state") +} + type runningState struct { p *Init } @@ -312,6 +342,12 @@ func (s *runningState) SetExited(status int) { } } +func (s *runningState) Exec(ctx context.Context, path string, r *ExecConfig) (Process, error) { + s.p.mu.Lock() + defer s.p.mu.Unlock() + return s.p.exec(ctx, path, r) +} + type pausedState struct { p *Init } @@ -396,7 +432,13 @@ func (s *pausedState) SetExited(status int) { if err := s.transition("stopped"); err != nil { panic(err) } +} +func (s *pausedState) Exec(ctx context.Context, path string, r *ExecConfig) (Process, error) { + s.p.mu.Lock() + defer s.p.mu.Unlock() + + return nil, errors.Errorf("cannot exec in a paused state") } type stoppedState struct { @@ -471,3 +513,10 @@ func (s *stoppedState) Kill(ctx context.Context, sig uint32, all bool) error { func (s *stoppedState) SetExited(status int) { // no op } + +func (s *stoppedState) Exec(ctx context.Context, path string, r *ExecConfig) (Process, error) { + s.p.mu.Lock() + defer s.p.mu.Unlock() + + return nil, errors.Errorf("cannot exec in a stopped state") +} diff --git a/components/engine/vendor/github.com/containerd/containerd/linux/proc/io.go b/components/engine/vendor/github.com/containerd/containerd/linux/proc/io.go index e78b383008..335b8b89ca 100644 --- a/components/engine/vendor/github.com/containerd/containerd/linux/proc/io.go +++ b/components/engine/vendor/github.com/containerd/containerd/linux/proc/io.go @@ -1,5 +1,21 @@ // +build !windows +/* + 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 proc import ( @@ -13,6 +29,13 @@ import ( runc "github.com/containerd/go-runc" ) +var bufPool = sync.Pool{ + New: func() interface{} { + buffer := make([]byte, 32<<10) + return &buffer + }, +} + func copyPipes(ctx context.Context, rio runc.IO, stdin, stdout, stderr string, wg, cwg *sync.WaitGroup) error { for name, dest := range map[string]func(wc io.WriteCloser, rc io.Closer){ stdout: func(wc io.WriteCloser, rc io.Closer) { @@ -20,7 +43,9 @@ func copyPipes(ctx context.Context, rio runc.IO, stdin, stdout, stderr string, w cwg.Add(1) go func() { cwg.Done() - io.Copy(wc, rio.Stdout()) + p := bufPool.Get().(*[]byte) + defer bufPool.Put(p) + io.CopyBuffer(wc, rio.Stdout(), *p) wg.Done() wc.Close() rc.Close() @@ -31,7 +56,10 @@ func copyPipes(ctx context.Context, rio runc.IO, stdin, stdout, stderr string, w cwg.Add(1) go func() { cwg.Done() - io.Copy(wc, rio.Stderr()) + p := bufPool.Get().(*[]byte) + defer bufPool.Put(p) + + io.CopyBuffer(wc, rio.Stderr(), *p) wg.Done() wc.Close() rc.Close() @@ -59,7 +87,10 @@ func copyPipes(ctx context.Context, rio runc.IO, stdin, stdout, stderr string, w cwg.Add(1) go func() { cwg.Done() - io.Copy(rio.Stdin(), f) + p := bufPool.Get().(*[]byte) + defer bufPool.Put(p) + + io.CopyBuffer(rio.Stdin(), f, *p) rio.Stdin().Close() f.Close() }() diff --git a/components/engine/vendor/github.com/containerd/containerd/linux/proc/process.go b/components/engine/vendor/github.com/containerd/containerd/linux/proc/process.go index c0d33adbce..135f9962b1 100644 --- a/components/engine/vendor/github.com/containerd/containerd/linux/proc/process.go +++ b/components/engine/vendor/github.com/containerd/containerd/linux/proc/process.go @@ -1,5 +1,21 @@ // +build !windows +/* + 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 proc import ( diff --git a/components/engine/vendor/github.com/containerd/containerd/linux/proc/types.go b/components/engine/vendor/github.com/containerd/containerd/linux/proc/types.go index 9055c25d10..0cc123fd81 100644 --- a/components/engine/vendor/github.com/containerd/containerd/linux/proc/types.go +++ b/components/engine/vendor/github.com/containerd/containerd/linux/proc/types.go @@ -1,16 +1,39 @@ +/* + 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 proc import ( - containerd_types "github.com/containerd/containerd/api/types" google_protobuf "github.com/gogo/protobuf/types" ) +// Mount holds filesystem mount configuration +type Mount struct { + Type string + Source string + Target string + Options []string +} + // CreateConfig hold task creation configuration type CreateConfig struct { ID string Bundle string Runtime string - Rootfs []*containerd_types.Mount + Rootfs []Mount Terminal bool Stdin string Stdout string diff --git a/components/engine/vendor/github.com/containerd/containerd/linux/proc/utils.go b/components/engine/vendor/github.com/containerd/containerd/linux/proc/utils.go index 1197957b57..3d0334c450 100644 --- a/components/engine/vendor/github.com/containerd/containerd/linux/proc/utils.go +++ b/components/engine/vendor/github.com/containerd/containerd/linux/proc/utils.go @@ -1,5 +1,21 @@ // +build !windows +/* + 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 proc import ( @@ -66,7 +82,10 @@ func copyFile(to, from string) error { return err } defer tt.Close() - _, err = io.Copy(tt, ff) + + p := bufPool.Get().(*[]byte) + defer bufPool.Put(p) + _, err = io.CopyBuffer(tt, ff, *p) return err } diff --git a/components/engine/vendor/github.com/containerd/containerd/linux/process.go b/components/engine/vendor/github.com/containerd/containerd/linux/process.go index 10acc69d5b..0790d8a52d 100644 --- a/components/engine/vendor/github.com/containerd/containerd/linux/process.go +++ b/components/engine/vendor/github.com/containerd/containerd/linux/process.go @@ -1,5 +1,21 @@ // +build linux +/* + 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 linux import ( @@ -10,6 +26,8 @@ import ( "github.com/containerd/containerd/errdefs" shim "github.com/containerd/containerd/linux/shim/v1" "github.com/containerd/containerd/runtime" + "github.com/pkg/errors" + "github.com/stevvooe/ttrpc" ) // Process implements a linux process @@ -44,7 +62,14 @@ func (p *Process) State(ctx context.Context) (runtime.State, error) { ID: p.id, }) if err != nil { - return runtime.State{}, errdefs.FromGRPC(err) + if errors.Cause(err) != ttrpc.ErrClosed { + return runtime.State{}, errdefs.FromGRPC(err) + } + + // We treat ttrpc.ErrClosed as the shim being closed, but really this + // likely means that the process no longer exists. We'll have to plumb + // the connection differently if this causes problems. + return runtime.State{}, errdefs.ErrNotFound } var status runtime.Status switch response.Status { diff --git a/components/engine/vendor/github.com/containerd/containerd/linux/runtime.go b/components/engine/vendor/github.com/containerd/containerd/linux/runtime.go index 82ed4f4ea6..1e1b77da7e 100644 --- a/components/engine/vendor/github.com/containerd/containerd/linux/runtime.go +++ b/components/engine/vendor/github.com/containerd/containerd/linux/runtime.go @@ -1,5 +1,21 @@ // +build linux +/* + 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 linux import ( @@ -26,9 +42,7 @@ import ( "github.com/containerd/containerd/namespaces" "github.com/containerd/containerd/platforms" "github.com/containerd/containerd/plugin" - "github.com/containerd/containerd/reaper" "github.com/containerd/containerd/runtime" - "github.com/containerd/containerd/sys" runc "github.com/containerd/go-runc" "github.com/containerd/typeurl" ptypes "github.com/gogo/protobuf/types" @@ -159,9 +173,6 @@ func (r *Runtime) Create(ctx context.Context, id string, opts runtime.CreateOpts return nil, err } - ec := reaper.Default.Subscribe() - defer reaper.Default.Unsubscribe(ec) - bundle, err := newBundle(id, filepath.Join(r.state, namespace), filepath.Join(r.root, namespace), @@ -206,10 +217,7 @@ func (r *Runtime) Create(ctx context.Context, id string, opts runtime.CreateOpts "id": id, "namespace": namespace, }).Warn("cleaning up after killed shim") - err = r.cleanupAfterDeadShim(context.Background(), bundle, namespace, id, lc.pid, ec) - if err == nil { - r.tasks.Delete(ctx, lc) - } else { + if err = r.cleanupAfterDeadShim(context.Background(), bundle, namespace, id, lc.pid); err != nil { log.G(ctx).WithError(err).WithFields(logrus.Fields{ "id": id, "namespace": namespace, @@ -313,12 +321,12 @@ func (r *Runtime) Delete(ctx context.Context, c runtime.Task) (*runtime.Exit, er rsp, err := lc.shim.Delete(ctx, empty) if err != nil { - if cerr := r.cleanupAfterDeadShim(ctx, bundle, namespace, c.ID(), lc.pid, nil); cerr != nil { + if cerr := r.cleanupAfterDeadShim(ctx, bundle, namespace, c.ID(), lc.pid); cerr != nil { log.G(ctx).WithError(err).Error("unable to cleanup task") } return nil, errdefs.FromGRPC(err) } - r.tasks.Delete(ctx, lc) + r.tasks.Delete(ctx, lc.id) if err := lc.shim.KillShim(ctx); err != nil { log.G(ctx).WithError(err).Error("failed to kill shim") } @@ -388,13 +396,19 @@ func (r *Runtime) loadTasks(ctx context.Context, ns string) ([]*Task, error) { ) ctx = namespaces.WithNamespace(ctx, ns) pid, _ := runc.ReadPidFile(filepath.Join(bundle.path, proc.InitPidFile)) - s, err := bundle.NewShimClient(ctx, ns, ShimConnect(), nil) + s, err := bundle.NewShimClient(ctx, ns, ShimConnect(func() { + err := r.cleanupAfterDeadShim(ctx, bundle, ns, id, pid) + if err != nil { + log.G(ctx).WithError(err).WithField("bundle", bundle.path). + Error("cleaning up after dead shim") + } + }), nil) if err != nil { log.G(ctx).WithError(err).WithFields(logrus.Fields{ "id": id, "namespace": ns, }).Error("connecting to shim") - err := r.cleanupAfterDeadShim(ctx, bundle, ns, id, pid, nil) + err := r.cleanupAfterDeadShim(ctx, bundle, ns, id, pid) if err != nil { log.G(ctx).WithError(err).WithField("bundle", bundle.path). Error("cleaning up after dead shim") @@ -419,7 +433,7 @@ func (r *Runtime) loadTasks(ctx context.Context, ns string) ([]*Task, error) { return o, nil } -func (r *Runtime) cleanupAfterDeadShim(ctx context.Context, bundle *bundle, ns, id string, pid int, ec chan runc.Exit) error { +func (r *Runtime) cleanupAfterDeadShim(ctx context.Context, bundle *bundle, ns, id string, pid int) error { ctx = namespaces.WithNamespace(ctx, ns) if err := r.terminate(ctx, bundle, ns, id); err != nil { if r.config.ShimDebug { @@ -428,17 +442,6 @@ func (r *Runtime) cleanupAfterDeadShim(ctx context.Context, bundle *bundle, ns, log.G(ctx).WithError(err).Warn("failed to terminate task") } - if ec != nil { - // if sub-reaper is set, reap our new child - if v, err := sys.GetSubreaper(); err == nil && v == 1 { - for e := range ec { - if e.Pid == pid { - break - } - } - } - } - // Notify Client exitedAt := time.Now().UTC() r.events.Publish(ctx, runtime.TaskExitEventTopic, &eventstypes.TaskExit{ @@ -449,6 +452,7 @@ func (r *Runtime) cleanupAfterDeadShim(ctx context.Context, bundle *bundle, ns, ExitedAt: exitedAt, }) + r.tasks.Delete(ctx, id) if err := bundle.Delete(); err != nil { log.G(ctx).WithError(err).Error("delete bundle") } @@ -464,12 +468,10 @@ func (r *Runtime) cleanupAfterDeadShim(ctx context.Context, bundle *bundle, ns, } func (r *Runtime) terminate(ctx context.Context, bundle *bundle, ns, id string) error { - ctx = namespaces.WithNamespace(ctx, ns) rt, err := r.getRuntime(ctx, ns, id) if err != nil { return err } - if err := rt.Delete(ctx, id, &runc.DeleteOpts{ Force: true, }); err != nil { diff --git a/components/engine/vendor/github.com/containerd/containerd/linux/shim/client/client.go b/components/engine/vendor/github.com/containerd/containerd/linux/shim/client/client.go index 6e78d8bea3..37881a36f2 100644 --- a/components/engine/vendor/github.com/containerd/containerd/linux/shim/client/client.go +++ b/components/engine/vendor/github.com/containerd/containerd/linux/shim/client/client.go @@ -1,5 +1,21 @@ // +build !windows +/* + 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 client import ( @@ -23,7 +39,6 @@ import ( "github.com/containerd/containerd/linux/shim" shimapi "github.com/containerd/containerd/linux/shim/v1" "github.com/containerd/containerd/log" - "github.com/containerd/containerd/reaper" "github.com/containerd/containerd/sys" ptypes "github.com/gogo/protobuf/types" ) @@ -51,8 +66,7 @@ func WithStart(binary, address, daemonAddress, cgroup string, debug bool, exitHa if err != nil { return nil, nil, err } - ec, err := reaper.Default.Start(cmd) - if err != nil { + if err := cmd.Start(); err != nil { return nil, nil, errors.Wrapf(err, "failed to start shim") } defer func() { @@ -61,7 +75,7 @@ func WithStart(binary, address, daemonAddress, cgroup string, debug bool, exitHa } }() go func() { - reaper.Default.Wait(cmd, ec) + cmd.Wait() exitHandler() }() log.G(ctx).WithFields(logrus.Fields{ @@ -82,7 +96,7 @@ func WithStart(binary, address, daemonAddress, cgroup string, debug bool, exitHa if err = sys.SetOOMScore(cmd.Process.Pid, sys.OOMScoreMaxKillable); err != nil { return nil, nil, errors.Wrap(err, "failed to set OOM Score on shim") } - c, clo, err := WithConnect(address)(ctx, config) + c, clo, err := WithConnect(address, func() {})(ctx, config) if err != nil { return nil, nil, errors.Wrap(err, "failed to connect") } @@ -151,13 +165,15 @@ func annonDialer(address string, timeout time.Duration) (net.Conn, error) { } // WithConnect connects to an existing shim -func WithConnect(address string) Opt { +func WithConnect(address string, onClose func()) Opt { return func(ctx context.Context, config shim.Config) (shimapi.ShimService, io.Closer, error) { conn, err := connect(address, annonDialer) if err != nil { return nil, nil, err } - return shimapi.NewShimClient(ttrpc.NewClient(conn)), conn, nil + client := ttrpc.NewClient(conn) + client.OnClose(onClose) + return shimapi.NewShimClient(client), conn, nil } } diff --git a/components/engine/vendor/github.com/containerd/containerd/linux/shim/client/client_linux.go b/components/engine/vendor/github.com/containerd/containerd/linux/shim/client/client_linux.go index 3125541eda..2519380f5d 100644 --- a/components/engine/vendor/github.com/containerd/containerd/linux/shim/client/client_linux.go +++ b/components/engine/vendor/github.com/containerd/containerd/linux/shim/client/client_linux.go @@ -1,5 +1,21 @@ // +build linux +/* + 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 client import ( diff --git a/components/engine/vendor/github.com/containerd/containerd/linux/shim/client/client_unix.go b/components/engine/vendor/github.com/containerd/containerd/linux/shim/client/client_unix.go index 0a24ce45fe..8a5b22fb78 100644 --- a/components/engine/vendor/github.com/containerd/containerd/linux/shim/client/client_unix.go +++ b/components/engine/vendor/github.com/containerd/containerd/linux/shim/client/client_unix.go @@ -1,5 +1,21 @@ // +build !linux,!windows +/* + 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 client import ( diff --git a/components/engine/vendor/github.com/containerd/containerd/linux/shim/local.go b/components/engine/vendor/github.com/containerd/containerd/linux/shim/local.go index 6e2192693f..1600ef6f1e 100644 --- a/components/engine/vendor/github.com/containerd/containerd/linux/shim/local.go +++ b/components/engine/vendor/github.com/containerd/containerd/linux/shim/local.go @@ -1,5 +1,21 @@ // +build !windows +/* + 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 shim import ( diff --git a/components/engine/vendor/github.com/containerd/containerd/linux/shim/service.go b/components/engine/vendor/github.com/containerd/containerd/linux/shim/service.go index 129b1790fc..49d847e87d 100644 --- a/components/engine/vendor/github.com/containerd/containerd/linux/shim/service.go +++ b/components/engine/vendor/github.com/containerd/containerd/linux/shim/service.go @@ -1,5 +1,21 @@ // +build !windows +/* + 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 shim import ( @@ -29,7 +45,15 @@ import ( "google.golang.org/grpc/status" ) -var empty = &ptypes.Empty{} +var ( + empty = &ptypes.Empty{} + bufPool = sync.Pool{ + New: func() interface{} { + buffer := make([]byte, 32<<10) + return &buffer + }, + } +) // Config contains shim specific configuration type Config struct { @@ -87,6 +111,16 @@ type Service struct { func (s *Service) Create(ctx context.Context, r *shimapi.CreateTaskRequest) (*shimapi.CreateTaskResponse, error) { s.mu.Lock() defer s.mu.Unlock() + + var mounts []proc.Mount + for _, m := range r.Rootfs { + mounts = append(mounts, proc.Mount{ + Type: m.Type, + Source: m.Source, + Target: m.Target, + Options: m.Options, + }) + } process, err := proc.New( ctx, s.config.Path, @@ -100,7 +134,7 @@ func (s *Service) Create(ctx context.Context, r *shimapi.CreateTaskRequest) (*sh ID: r.ID, Bundle: r.Bundle, Runtime: r.Runtime, - Rootfs: r.Rootfs, + Rootfs: mounts, Terminal: r.Terminal, Stdin: r.Stdin, Stdout: r.Stdout, @@ -129,7 +163,7 @@ func (s *Service) Start(ctx context.Context, r *shimapi.StartRequest) (*shimapi. defer s.mu.Unlock() p := s.processes[r.ID] if p == nil { - return nil, errdefs.ToGRPCf(errdefs.ErrNotFound, "process %s not found", r.ID) + return nil, errdefs.ToGRPCf(errdefs.ErrNotFound, "process %s", r.ID) } if err := p.Start(ctx); err != nil { return nil, err @@ -235,10 +269,10 @@ func (s *Service) ResizePty(ctx context.Context, r *shimapi.ResizePtyRequest) (* // State returns runtime state information for a process func (s *Service) State(ctx context.Context, r *shimapi.StateRequest) (*shimapi.StateResponse, error) { s.mu.Lock() + defer s.mu.Unlock() p := s.processes[r.ID] - s.mu.Unlock() if p == nil { - return nil, errdefs.ToGRPCf(errdefs.ErrNotFound, "process id %s not found", r.ID) + return nil, errdefs.ToGRPCf(errdefs.ErrNotFound, "process id %s", r.ID) } st, err := p.Status(ctx) if err != nil { diff --git a/components/engine/vendor/github.com/containerd/containerd/linux/shim/service_linux.go b/components/engine/vendor/github.com/containerd/containerd/linux/shim/service_linux.go index bbe9d188a0..18ae6503b4 100644 --- a/components/engine/vendor/github.com/containerd/containerd/linux/shim/service_linux.go +++ b/components/engine/vendor/github.com/containerd/containerd/linux/shim/service_linux.go @@ -1,3 +1,19 @@ +/* + 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 shim import ( @@ -33,7 +49,9 @@ func (p *linuxPlatform) CopyConsole(ctx context.Context, console console.Console cwg.Add(1) go func() { cwg.Done() - io.Copy(epollConsole, in) + p := bufPool.Get().(*[]byte) + defer bufPool.Put(p) + io.CopyBuffer(epollConsole, in, *p) }() } @@ -49,7 +67,9 @@ func (p *linuxPlatform) CopyConsole(ctx context.Context, console console.Console cwg.Add(1) go func() { cwg.Done() - io.Copy(outw, epollConsole) + p := bufPool.Get().(*[]byte) + defer bufPool.Put(p) + io.CopyBuffer(outw, epollConsole, *p) epollConsole.Close() outr.Close() outw.Close() diff --git a/components/engine/vendor/github.com/containerd/containerd/linux/shim/service_unix.go b/components/engine/vendor/github.com/containerd/containerd/linux/shim/service_unix.go index d4419e56ae..708e45c296 100644 --- a/components/engine/vendor/github.com/containerd/containerd/linux/shim/service_unix.go +++ b/components/engine/vendor/github.com/containerd/containerd/linux/shim/service_unix.go @@ -1,5 +1,21 @@ // +build !windows,!linux +/* + 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 shim import ( @@ -24,7 +40,10 @@ func (p *unixPlatform) CopyConsole(ctx context.Context, console console.Console, cwg.Add(1) go func() { cwg.Done() - io.Copy(console, in) + p := bufPool.Get().(*[]byte) + defer bufPool.Put(p) + + io.CopyBuffer(console, in, *p) }() } outw, err := fifo.OpenFifo(ctx, stdout, syscall.O_WRONLY, 0) @@ -39,7 +58,10 @@ func (p *unixPlatform) CopyConsole(ctx context.Context, console console.Console, cwg.Add(1) go func() { cwg.Done() - io.Copy(outw, console) + p := bufPool.Get().(*[]byte) + defer bufPool.Put(p) + + io.CopyBuffer(outw, console, *p) console.Close() outr.Close() outw.Close() diff --git a/components/engine/vendor/github.com/containerd/containerd/linux/task.go b/components/engine/vendor/github.com/containerd/containerd/linux/task.go index 4d1e93fb1f..eca82fbbd0 100644 --- a/components/engine/vendor/github.com/containerd/containerd/linux/task.go +++ b/components/engine/vendor/github.com/containerd/containerd/linux/task.go @@ -1,14 +1,27 @@ // +build linux +/* + 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 linux import ( "context" "sync" - "github.com/pkg/errors" - "google.golang.org/grpc" - "github.com/containerd/cgroups" eventstypes "github.com/containerd/containerd/api/events" "github.com/containerd/containerd/api/types/task" @@ -20,6 +33,8 @@ import ( "github.com/containerd/containerd/runtime" runc "github.com/containerd/go-runc" "github.com/gogo/protobuf/types" + "github.com/pkg/errors" + "github.com/stevvooe/ttrpc" ) // Task on a linux based system @@ -109,7 +124,7 @@ func (t *Task) State(ctx context.Context) (runtime.State, error) { ID: t.id, }) if err != nil { - if err != grpc.ErrServerStopped { + if errors.Cause(err) != ttrpc.ErrClosed { return runtime.State{}, errdefs.FromGRPC(err) } return runtime.State{}, errdefs.ErrNotFound diff --git a/components/engine/vendor/github.com/containerd/containerd/log/context.go b/components/engine/vendor/github.com/containerd/containerd/log/context.go index 1081719c11..f40603b17b 100644 --- a/components/engine/vendor/github.com/containerd/containerd/log/context.go +++ b/components/engine/vendor/github.com/containerd/containerd/log/context.go @@ -1,8 +1,24 @@ +/* + 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 log import ( "context" - "path" + "sync/atomic" "github.com/sirupsen/logrus" ) @@ -20,9 +36,21 @@ var ( type ( loggerKey struct{} - moduleKey struct{} ) +// TraceLevel is the log level for tracing. Trace level is lower than debug level, +// and is usually used to trace detailed behavior of the program. +const TraceLevel = logrus.Level(uint32(logrus.DebugLevel + 1)) + +// ParseLevel takes a string level and returns the Logrus log level constant. +// It supports trace level. +func ParseLevel(lvl string) (logrus.Level, error) { + if lvl == "trace" { + return TraceLevel, nil + } + return logrus.ParseLevel(lvl) +} + // WithLogger returns a new context with the provided logger. Use in // combination with logger.WithField(s) for great effect. func WithLogger(ctx context.Context, logger *logrus.Entry) context.Context { @@ -41,41 +69,18 @@ func GetLogger(ctx context.Context) *logrus.Entry { return logger.(*logrus.Entry) } -// WithModule adds the module to the context, appending it with a slash if a -// module already exists. A module is just an roughly correlated defined by the -// call tree for a given context. -// -// As an example, we might have a "node" module already part of a context. If -// this function is called with "tls", the new value of module will be -// "node/tls". -// -// Modules represent the call path. If the new module and last module are the -// same, a new module entry will not be created. If the new module and old -// older module are the same but separated by other modules, the cycle will be -// represented by the module path. -func WithModule(ctx context.Context, module string) context.Context { - parent := GetModulePath(ctx) - - if parent != "" { - // don't re-append module when module is the same. - if path.Base(parent) == module { - return ctx - } - - module = path.Join(parent, module) +// Trace logs a message at level Trace with the log entry passed-in. +func Trace(e *logrus.Entry, args ...interface{}) { + level := logrus.Level(atomic.LoadUint32((*uint32)(&e.Logger.Level))) + if level >= TraceLevel { + e.Debug(args...) } - - ctx = WithLogger(ctx, GetLogger(ctx).WithField("module", module)) - return context.WithValue(ctx, moduleKey{}, module) } -// GetModulePath returns the module path for the provided context. If no module -// is set, an empty string is returned. -func GetModulePath(ctx context.Context) string { - module := ctx.Value(moduleKey{}) - if module == nil { - return "" +// Tracef logs a message at level Trace with the log entry passed-in. +func Tracef(e *logrus.Entry, format string, args ...interface{}) { + level := logrus.Level(atomic.LoadUint32((*uint32)(&e.Logger.Level))) + if level >= TraceLevel { + e.Debugf(format, args...) } - - return module.(string) } diff --git a/components/engine/vendor/github.com/containerd/containerd/log/grpc.go b/components/engine/vendor/github.com/containerd/containerd/log/grpc.go deleted file mode 100644 index cb2c92182f..0000000000 --- a/components/engine/vendor/github.com/containerd/containerd/log/grpc.go +++ /dev/null @@ -1,12 +0,0 @@ -package log - -import ( - "io/ioutil" - "log" - - "google.golang.org/grpc/grpclog" -) - -func init() { - grpclog.SetLogger(log.New(ioutil.Discard, "", log.LstdFlags)) -} diff --git a/components/engine/vendor/github.com/containerd/containerd/metadata/adaptors.go b/components/engine/vendor/github.com/containerd/containerd/metadata/adaptors.go index 4e7ef673dd..8145f9acee 100644 --- a/components/engine/vendor/github.com/containerd/containerd/metadata/adaptors.go +++ b/components/engine/vendor/github.com/containerd/containerd/metadata/adaptors.go @@ -1,3 +1,19 @@ +/* + 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 metadata import ( diff --git a/components/engine/vendor/github.com/containerd/containerd/metadata/bolt.go b/components/engine/vendor/github.com/containerd/containerd/metadata/bolt.go index 2e4c352705..156a33593f 100644 --- a/components/engine/vendor/github.com/containerd/containerd/metadata/bolt.go +++ b/components/engine/vendor/github.com/containerd/containerd/metadata/bolt.go @@ -1,3 +1,19 @@ +/* + 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 metadata import ( diff --git a/components/engine/vendor/github.com/containerd/containerd/metadata/boltutil/helpers.go b/components/engine/vendor/github.com/containerd/containerd/metadata/boltutil/helpers.go index b713132dc0..4b2ede8763 100644 --- a/components/engine/vendor/github.com/containerd/containerd/metadata/boltutil/helpers.go +++ b/components/engine/vendor/github.com/containerd/containerd/metadata/boltutil/helpers.go @@ -1,3 +1,19 @@ +/* + 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 boltutil import ( diff --git a/components/engine/vendor/github.com/containerd/containerd/metadata/buckets.go b/components/engine/vendor/github.com/containerd/containerd/metadata/buckets.go index 9325f1698a..cade7eea34 100644 --- a/components/engine/vendor/github.com/containerd/containerd/metadata/buckets.go +++ b/components/engine/vendor/github.com/containerd/containerd/metadata/buckets.go @@ -1,3 +1,19 @@ +/* + 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 metadata import ( @@ -106,13 +122,8 @@ func imagesBucketPath(namespace string) [][]byte { return [][]byte{bucketKeyVersion, []byte(namespace), bucketKeyObjectImages} } -func withImagesBucket(tx *bolt.Tx, namespace string, fn func(bkt *bolt.Bucket) error) error { - bkt, err := createBucketIfNotExists(tx, imagesBucketPath(namespace)...) - if err != nil { - return err - } - - return fn(bkt) +func createImagesBucket(tx *bolt.Tx, namespace string) (*bolt.Bucket, error) { + return createBucketIfNotExists(tx, imagesBucketPath(namespace)...) } func getImagesBucket(tx *bolt.Tx, namespace string) *bolt.Bucket { @@ -143,6 +154,10 @@ func createSnapshotterBucket(tx *bolt.Tx, namespace, snapshotter string) (*bolt. return bkt, nil } +func getSnapshottersBucket(tx *bolt.Tx, namespace string) *bolt.Bucket { + return getBucket(tx, bucketKeyVersion, []byte(namespace), bucketKeyObjectSnapshots) +} + func getSnapshotterBucket(tx *bolt.Tx, namespace, snapshotter string) *bolt.Bucket { return getBucket(tx, bucketKeyVersion, []byte(namespace), bucketKeyObjectSnapshots, []byte(snapshotter)) } diff --git a/components/engine/vendor/github.com/containerd/containerd/metadata/containers.go b/components/engine/vendor/github.com/containerd/containerd/metadata/containers.go index 32f339afef..2ba45c72ff 100644 --- a/components/engine/vendor/github.com/containerd/containerd/metadata/containers.go +++ b/components/engine/vendor/github.com/containerd/containerd/metadata/containers.go @@ -1,3 +1,19 @@ +/* + 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 metadata import ( diff --git a/components/engine/vendor/github.com/containerd/containerd/metadata/content.go b/components/engine/vendor/github.com/containerd/containerd/metadata/content.go index c13f7867ee..3a746c0167 100644 --- a/components/engine/vendor/github.com/containerd/containerd/metadata/content.go +++ b/components/engine/vendor/github.com/containerd/containerd/metadata/content.go @@ -1,3 +1,19 @@ +/* + 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 metadata import ( @@ -318,12 +334,23 @@ func (cs *contentStore) Writer(ctx context.Context, ref string, size int64, expe cs.l.RLock() defer cs.l.RUnlock() - var w content.Writer + var ( + w content.Writer + exists bool + ) if err := update(ctx, cs.db, func(tx *bolt.Tx) error { if expected != "" { cbkt := getBlobBucket(tx, ns, expected) if cbkt != nil { - return errors.Wrapf(errdefs.ErrAlreadyExists, "content %v", expected) + // Add content to lease to prevent other reference removals + // from effecting this object during a provided lease + if err := addContentLease(ctx, tx, expected); err != nil { + return errors.Wrap(err, "unable to lease content") + } + // Return error outside of transaction to ensure + // commit succeeds with the lease. + exists = true + return nil } } @@ -363,6 +390,9 @@ func (cs *contentStore) Writer(ctx context.Context, ref string, size int64, expe }); err != nil { return nil, err } + if exists { + return nil, errors.Wrapf(errdefs.ErrAlreadyExists, "content %v", expected) + } // TODO: keep the expected in the writer to use on commit // when no expected is provided there. diff --git a/components/engine/vendor/github.com/containerd/containerd/metadata/db.go b/components/engine/vendor/github.com/containerd/containerd/metadata/db.go index 8be62a95c3..f08e1d46c3 100644 --- a/components/engine/vendor/github.com/containerd/containerd/metadata/db.go +++ b/components/engine/vendor/github.com/containerd/containerd/metadata/db.go @@ -1,3 +1,19 @@ +/* + 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 metadata import ( @@ -204,7 +220,7 @@ func (m *DB) Update(fn func(*bolt.Tx) error) error { // RegisterMutationCallback registers a function to be called after a metadata // mutations has been performed. // -// The callback function in an argument for whether a deletion has occurred +// The callback function is an argument for whether a deletion has occurred // since the last garbage collection. func (m *DB) RegisterMutationCallback(fn func(bool)) { m.dirtyL.Lock() @@ -219,15 +235,20 @@ type GCStats struct { SnapshotD map[string]time.Duration } +// Elapsed returns the duration which elapsed during a collection +func (s GCStats) Elapsed() time.Duration { + return s.MetaD +} + // GarbageCollect starts garbage collection -func (m *DB) GarbageCollect(ctx context.Context) (stats GCStats, err error) { +func (m *DB) GarbageCollect(ctx context.Context) (gc.Stats, error) { m.wlock.Lock() t1 := time.Now() marked, err := m.getMarked(ctx) if err != nil { m.wlock.Unlock() - return GCStats{}, err + return nil, err } m.dirtyL.Lock() @@ -259,9 +280,10 @@ func (m *DB) GarbageCollect(ctx context.Context) (stats GCStats, err error) { }); err != nil { m.dirtyL.Unlock() m.wlock.Unlock() - return GCStats{}, err + return nil, err } + var stats GCStats var wg sync.WaitGroup if len(m.dirtySS) > 0 { @@ -303,7 +325,7 @@ func (m *DB) GarbageCollect(ctx context.Context) (stats GCStats, err error) { wg.Wait() - return + return stats, err } func (m *DB) getMarked(ctx context.Context) (map[gc.Node]struct{}, error) { diff --git a/components/engine/vendor/github.com/containerd/containerd/metadata/gc.go b/components/engine/vendor/github.com/containerd/containerd/metadata/gc.go index 186f350ee3..d13047eb1c 100644 --- a/components/engine/vendor/github.com/containerd/containerd/metadata/gc.go +++ b/components/engine/vendor/github.com/containerd/containerd/metadata/gc.go @@ -1,3 +1,19 @@ +/* + 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 metadata import ( diff --git a/components/engine/vendor/github.com/containerd/containerd/metadata/images.go b/components/engine/vendor/github.com/containerd/containerd/metadata/images.go index 070439a8ca..62b1179cd3 100644 --- a/components/engine/vendor/github.com/containerd/containerd/metadata/images.go +++ b/components/engine/vendor/github.com/containerd/containerd/metadata/images.go @@ -1,3 +1,19 @@ +/* + 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 metadata import ( @@ -20,12 +36,12 @@ import ( ) type imageStore struct { - tx *bolt.Tx + db *DB } // NewImageStore returns a store backed by a bolt DB -func NewImageStore(tx *bolt.Tx) images.Store { - return &imageStore{tx: tx} +func NewImageStore(db *DB) images.Store { + return &imageStore{db: db} } func (s *imageStore) Get(ctx context.Context, name string) (images.Image, error) { @@ -36,19 +52,25 @@ func (s *imageStore) Get(ctx context.Context, name string) (images.Image, error) return images.Image{}, err } - bkt := getImagesBucket(s.tx, namespace) - if bkt == nil { - return images.Image{}, errors.Wrapf(errdefs.ErrNotFound, "image %q", name) - } + if err := view(ctx, s.db, func(tx *bolt.Tx) error { + bkt := getImagesBucket(tx, namespace) + if bkt == nil { + return errors.Wrapf(errdefs.ErrNotFound, "image %q", name) + } - ibkt := bkt.Bucket([]byte(name)) - if ibkt == nil { - return images.Image{}, errors.Wrapf(errdefs.ErrNotFound, "image %q", name) - } + ibkt := bkt.Bucket([]byte(name)) + if ibkt == nil { + return errors.Wrapf(errdefs.ErrNotFound, "image %q", name) + } - image.Name = name - if err := readImage(&image, ibkt); err != nil { - return images.Image{}, errors.Wrapf(err, "image %q", name) + image.Name = name + if err := readImage(&image, ibkt); err != nil { + return errors.Wrapf(err, "image %q", name) + } + + return nil + }); err != nil { + return images.Image{}, err } return image, nil @@ -65,28 +87,30 @@ func (s *imageStore) List(ctx context.Context, fs ...string) ([]images.Image, er return nil, errors.Wrapf(errdefs.ErrInvalidArgument, err.Error()) } - bkt := getImagesBucket(s.tx, namespace) - if bkt == nil { - return nil, nil // empty store - } - var m []images.Image - if err := bkt.ForEach(func(k, v []byte) error { - var ( - image = images.Image{ - Name: string(k), + if err := view(ctx, s.db, func(tx *bolt.Tx) error { + bkt := getImagesBucket(tx, namespace) + if bkt == nil { + return nil // empty store + } + + return bkt.ForEach(func(k, v []byte) error { + var ( + image = images.Image{ + Name: string(k), + } + kbkt = bkt.Bucket(k) + ) + + if err := readImage(&image, kbkt); err != nil { + return err } - kbkt = bkt.Bucket(k) - ) - if err := readImage(&image, kbkt); err != nil { - return err - } - - if filter.Match(adaptImage(image)) { - m = append(m, image) - } - return nil + if filter.Match(adaptImage(image)) { + m = append(m, image) + } + return nil + }) }); err != nil { return nil, err } @@ -100,11 +124,16 @@ func (s *imageStore) Create(ctx context.Context, image images.Image) (images.Ima return images.Image{}, err } - if err := validateImage(&image); err != nil { - return images.Image{}, err - } + if err := update(ctx, s.db, func(tx *bolt.Tx) error { + if err := validateImage(&image); err != nil { + return err + } + + bkt, err := createImagesBucket(tx, namespace) + if err != nil { + return err + } - return image, withImagesBucket(s.tx, namespace, func(bkt *bolt.Bucket) error { ibkt, err := bkt.CreateBucket([]byte(image.Name)) if err != nil { if err != bolt.ErrBucketExists { @@ -117,7 +146,11 @@ func (s *imageStore) Create(ctx context.Context, image images.Image) (images.Ima image.CreatedAt = time.Now().UTC() image.UpdatedAt = image.CreatedAt return writeImage(ibkt, &image) - }) + }); err != nil { + return images.Image{}, err + } + + return image, nil } func (s *imageStore) Update(ctx context.Context, image images.Image, fieldpaths ...string) (images.Image, error) { @@ -131,7 +164,13 @@ func (s *imageStore) Update(ctx context.Context, image images.Image, fieldpaths } var updated images.Image - return updated, withImagesBucket(s.tx, namespace, func(bkt *bolt.Bucket) error { + + if err := update(ctx, s.db, func(tx *bolt.Tx) error { + bkt, err := createImagesBucket(tx, namespace) + if err != nil { + return err + } + ibkt := bkt.Bucket([]byte(image.Name)) if ibkt == nil { return errors.Wrapf(errdefs.ErrNotFound, "image %q", image.Name) @@ -180,7 +219,12 @@ func (s *imageStore) Update(ctx context.Context, image images.Image, fieldpaths updated.CreatedAt = createdat updated.UpdatedAt = time.Now().UTC() return writeImage(ibkt, &updated) - }) + }); err != nil { + return images.Image{}, err + } + + return updated, nil + } func (s *imageStore) Delete(ctx context.Context, name string, opts ...images.DeleteOpt) error { @@ -189,11 +233,24 @@ func (s *imageStore) Delete(ctx context.Context, name string, opts ...images.Del return err } - return withImagesBucket(s.tx, namespace, func(bkt *bolt.Bucket) error { - err := bkt.DeleteBucket([]byte(name)) + return update(ctx, s.db, func(tx *bolt.Tx) error { + bkt := getImagesBucket(tx, namespace) + if bkt == nil { + return errors.Wrapf(errdefs.ErrNotFound, "image %q", name) + } + + err = bkt.DeleteBucket([]byte(name)) if err == bolt.ErrBucketNotFound { return errors.Wrapf(errdefs.ErrNotFound, "image %q", name) } + + // A reference to a piece of content has been removed, + // mark content store as dirty for triggering garbage + // collection + s.db.dirtyL.Lock() + s.db.dirtyCS = true + s.db.dirtyL.Unlock() + return err }) } @@ -275,7 +332,7 @@ func writeImage(bkt *bolt.Bucket, image *images.Image) error { } // write the target bucket - tbkt, err := bkt.CreateBucketIfNotExists([]byte(bucketKeyTarget)) + tbkt, err := bkt.CreateBucketIfNotExists(bucketKeyTarget) if err != nil { return err } diff --git a/components/engine/vendor/github.com/containerd/containerd/metadata/leases.go b/components/engine/vendor/github.com/containerd/containerd/metadata/leases.go index eff0b20987..317f000ce1 100644 --- a/components/engine/vendor/github.com/containerd/containerd/metadata/leases.go +++ b/components/engine/vendor/github.com/containerd/containerd/metadata/leases.go @@ -1,3 +1,19 @@ +/* + 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 metadata import ( diff --git a/components/engine/vendor/github.com/containerd/containerd/metadata/migrations.go b/components/engine/vendor/github.com/containerd/containerd/metadata/migrations.go index 997aee298d..5be5f83011 100644 --- a/components/engine/vendor/github.com/containerd/containerd/metadata/migrations.go +++ b/components/engine/vendor/github.com/containerd/containerd/metadata/migrations.go @@ -1,3 +1,19 @@ +/* + 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 metadata import "github.com/boltdb/bolt" diff --git a/components/engine/vendor/github.com/containerd/containerd/metadata/namespaces.go b/components/engine/vendor/github.com/containerd/containerd/metadata/namespaces.go index 4b4c4e5fe7..000bef6c9c 100644 --- a/components/engine/vendor/github.com/containerd/containerd/metadata/namespaces.go +++ b/components/engine/vendor/github.com/containerd/containerd/metadata/namespaces.go @@ -1,3 +1,19 @@ +/* + 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 metadata import ( @@ -133,31 +149,38 @@ func (s *namespaceStore) Delete(ctx context.Context, namespace string) error { } func (s *namespaceStore) namespaceEmpty(ctx context.Context, namespace string) (bool, error) { - ctx = namespaces.WithNamespace(ctx, namespace) - - // need to check the various object stores. - - imageStore := NewImageStore(s.tx) - images, err := imageStore.List(ctx) - if err != nil { - return false, err + // Get all data buckets + buckets := []*bolt.Bucket{ + getImagesBucket(s.tx, namespace), + getBlobsBucket(s.tx, namespace), + getContainersBucket(s.tx, namespace), } - if len(images) > 0 { - return false, nil + if snbkt := getSnapshottersBucket(s.tx, namespace); snbkt != nil { + if err := snbkt.ForEach(func(k, v []byte) error { + if v == nil { + buckets = append(buckets, snbkt.Bucket(k)) + } + return nil + }); err != nil { + return false, err + } } - containerStore := NewContainerStore(s.tx) - containers, err := containerStore.List(ctx) - if err != nil { - return false, err + // Ensure data buckets are empty + for _, bkt := range buckets { + if !isBucketEmpty(bkt) { + return false, nil + } } - if len(containers) > 0 { - return false, nil - } - - // TODO(stevvooe): Need to add check for content store, as well. Still need - // to make content store namespace aware. - return true, nil } + +func isBucketEmpty(bkt *bolt.Bucket) bool { + if bkt == nil { + return true + } + + k, _ := bkt.Cursor().First() + return k == nil +} diff --git a/components/engine/vendor/github.com/containerd/containerd/metadata/snapshot.go b/components/engine/vendor/github.com/containerd/containerd/metadata/snapshot.go index 6c34e49c22..b126bc9841 100644 --- a/components/engine/vendor/github.com/containerd/containerd/metadata/snapshot.go +++ b/components/engine/vendor/github.com/containerd/containerd/metadata/snapshot.go @@ -1,3 +1,19 @@ +/* + 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 metadata import ( diff --git a/components/engine/vendor/github.com/containerd/containerd/mount/lookup_unix.go b/components/engine/vendor/github.com/containerd/containerd/mount/lookup_unix.go index df9625a968..e8b0a0b483 100644 --- a/components/engine/vendor/github.com/containerd/containerd/mount/lookup_unix.go +++ b/components/engine/vendor/github.com/containerd/containerd/mount/lookup_unix.go @@ -1,24 +1,34 @@ // +build !windows +/* + 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 mount import ( - "fmt" "path/filepath" "sort" "strings" - "syscall" "github.com/pkg/errors" ) // Lookup returns the mount info corresponds to the path. func Lookup(dir string) (Info, error) { - var dirStat syscall.Stat_t dir = filepath.Clean(dir) - if err := syscall.Stat(dir, &dirStat); err != nil { - return Info{}, errors.Wrapf(err, "failed to access %q", dir) - } mounts, err := Self() if err != nil { @@ -26,21 +36,18 @@ func Lookup(dir string) (Info, error) { } // Sort descending order by Info.Mountpoint - sort.Slice(mounts, func(i, j int) bool { + sort.SliceStable(mounts, func(i, j int) bool { return mounts[j].Mountpoint < mounts[i].Mountpoint }) for _, m := range mounts { // Note that m.{Major, Minor} are generally unreliable for our purpose here // https://www.spinics.net/lists/linux-btrfs/msg58908.html - var st syscall.Stat_t - if err := syscall.Stat(m.Mountpoint, &st); err != nil { - // may fail; ignore err - continue - } - if st.Dev == dirStat.Dev && strings.HasPrefix(dir, m.Mountpoint) { + // Note that device number is not checked here, because for overlayfs files + // may have different device number with the mountpoint. + if strings.HasPrefix(dir, m.Mountpoint) { return m, nil } } - return Info{}, fmt.Errorf("failed to find the mount info for %q", dir) + return Info{}, errors.Errorf("failed to find the mount info for %q", dir) } diff --git a/components/engine/vendor/github.com/containerd/containerd/mount/lookup_unsupported.go b/components/engine/vendor/github.com/containerd/containerd/mount/lookup_unsupported.go index e5f84e7f28..46ec66a904 100644 --- a/components/engine/vendor/github.com/containerd/containerd/mount/lookup_unsupported.go +++ b/components/engine/vendor/github.com/containerd/containerd/mount/lookup_unsupported.go @@ -1,5 +1,21 @@ // +build windows +/* + 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 mount import ( diff --git a/components/engine/vendor/github.com/containerd/containerd/mount/mount.go b/components/engine/vendor/github.com/containerd/containerd/mount/mount.go index 94c2c9f927..b25556b2e0 100644 --- a/components/engine/vendor/github.com/containerd/containerd/mount/mount.go +++ b/components/engine/vendor/github.com/containerd/containerd/mount/mount.go @@ -1,3 +1,19 @@ +/* + 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 mount // Mount is the lingua franca of containerd. A mount represents a diff --git a/components/engine/vendor/github.com/containerd/containerd/mount/mount_linux.go b/components/engine/vendor/github.com/containerd/containerd/mount/mount_linux.go index de2e8bb7d2..82fc0b279e 100644 --- a/components/engine/vendor/github.com/containerd/containerd/mount/mount_linux.go +++ b/components/engine/vendor/github.com/containerd/containerd/mount/mount_linux.go @@ -1,3 +1,19 @@ +/* + 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 mount import ( diff --git a/components/engine/vendor/github.com/containerd/containerd/mount/mount_unix.go b/components/engine/vendor/github.com/containerd/containerd/mount/mount_unix.go index edb0e8dd19..6741293f89 100644 --- a/components/engine/vendor/github.com/containerd/containerd/mount/mount_unix.go +++ b/components/engine/vendor/github.com/containerd/containerd/mount/mount_unix.go @@ -1,5 +1,21 @@ // +build darwin freebsd +/* + 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 mount import "github.com/pkg/errors" diff --git a/components/engine/vendor/github.com/containerd/containerd/mount/mount_windows.go b/components/engine/vendor/github.com/containerd/containerd/mount/mount_windows.go index 8ad7eab129..f7c97894b4 100644 --- a/components/engine/vendor/github.com/containerd/containerd/mount/mount_windows.go +++ b/components/engine/vendor/github.com/containerd/containerd/mount/mount_windows.go @@ -1,6 +1,29 @@ +/* + 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 mount -import "github.com/pkg/errors" +import ( + "encoding/json" + "path/filepath" + "strings" + + "github.com/Microsoft/hcsshim" + "github.com/pkg/errors" +) var ( // ErrNotImplementOnWindows is returned when an action is not implemented for windows @@ -9,15 +32,70 @@ var ( // Mount to the provided target func (m *Mount) Mount(target string) error { - return ErrNotImplementOnWindows + home, layerID := filepath.Split(m.Source) + + parentLayerPaths, err := m.GetParentPaths() + if err != nil { + return err + } + + var di = hcsshim.DriverInfo{ + HomeDir: home, + } + + if err = hcsshim.ActivateLayer(di, layerID); err != nil { + return errors.Wrapf(err, "failed to activate layer %s", m.Source) + } + defer func() { + if err != nil { + hcsshim.DeactivateLayer(di, layerID) + } + }() + + if err = hcsshim.PrepareLayer(di, layerID, parentLayerPaths); err != nil { + return errors.Wrapf(err, "failed to prepare layer %s", m.Source) + } + return nil +} + +// ParentLayerPathsFlag is the options flag used to represent the JSON encoded +// list of parent layers required to use the layer +const ParentLayerPathsFlag = "parentLayerPaths=" + +// GetParentPaths of the mount +func (m *Mount) GetParentPaths() ([]string, error) { + var parentLayerPaths []string + for _, option := range m.Options { + if strings.HasPrefix(option, ParentLayerPathsFlag) { + err := json.Unmarshal([]byte(option[len(ParentLayerPathsFlag):]), &parentLayerPaths) + if err != nil { + return nil, errors.Wrap(err, "failed to unmarshal parent layer paths from mount") + } + } + } + return parentLayerPaths, nil } // Unmount the mount at the provided path func Unmount(mount string, flags int) error { - return ErrNotImplementOnWindows + var ( + home, layerID = filepath.Split(mount) + di = hcsshim.DriverInfo{ + HomeDir: home, + } + ) + + if err := hcsshim.UnprepareLayer(di, layerID); err != nil { + return errors.Wrapf(err, "failed to unprepare layer %s", mount) + } + if err := hcsshim.DeactivateLayer(di, layerID); err != nil { + return errors.Wrapf(err, "failed to deactivate layer %s", mount) + } + + return nil } -// UnmountAll mounts at the provided path +// UnmountAll unmounts from the provided path func UnmountAll(mount string, flags int) error { - return ErrNotImplementOnWindows + return Unmount(mount, flags) } diff --git a/components/engine/vendor/github.com/containerd/containerd/mount/mountinfo.go b/components/engine/vendor/github.com/containerd/containerd/mount/mountinfo.go index 2192cce20f..e7a68402f5 100644 --- a/components/engine/vendor/github.com/containerd/containerd/mount/mountinfo.go +++ b/components/engine/vendor/github.com/containerd/containerd/mount/mountinfo.go @@ -1,3 +1,19 @@ +/* + 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 mount // Info reveals information about a particular mounted filesystem. This diff --git a/components/engine/vendor/github.com/containerd/containerd/mount/mountinfo_freebsd.go b/components/engine/vendor/github.com/containerd/containerd/mount/mountinfo_freebsd.go index d2bc075a6b..bbe79767e3 100644 --- a/components/engine/vendor/github.com/containerd/containerd/mount/mountinfo_freebsd.go +++ b/components/engine/vendor/github.com/containerd/containerd/mount/mountinfo_freebsd.go @@ -1,3 +1,19 @@ +/* + 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 mount /* diff --git a/components/engine/vendor/github.com/containerd/containerd/mount/mountinfo_linux.go b/components/engine/vendor/github.com/containerd/containerd/mount/mountinfo_linux.go index 023772264a..9c442c8ed0 100644 --- a/components/engine/vendor/github.com/containerd/containerd/mount/mountinfo_linux.go +++ b/components/engine/vendor/github.com/containerd/containerd/mount/mountinfo_linux.go @@ -1,5 +1,21 @@ // +build linux +/* + 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 mount import ( diff --git a/components/engine/vendor/github.com/containerd/containerd/mount/mountinfo_unsupported.go b/components/engine/vendor/github.com/containerd/containerd/mount/mountinfo_unsupported.go index aa659d899a..eba602f1a6 100644 --- a/components/engine/vendor/github.com/containerd/containerd/mount/mountinfo_unsupported.go +++ b/components/engine/vendor/github.com/containerd/containerd/mount/mountinfo_unsupported.go @@ -1,5 +1,21 @@ // +build !linux,!freebsd,!solaris freebsd,!cgo solaris,!cgo +/* + 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 mount import ( diff --git a/components/engine/vendor/github.com/containerd/containerd/mount/temp.go b/components/engine/vendor/github.com/containerd/containerd/mount/temp.go new file mode 100644 index 0000000000..ec7a06bcbe --- /dev/null +++ b/components/engine/vendor/github.com/containerd/containerd/mount/temp.go @@ -0,0 +1,50 @@ +package mount + +import ( + "context" + "io/ioutil" + "os" + + "github.com/containerd/containerd/log" + "github.com/pkg/errors" +) + +var tempMountLocation = os.TempDir() + +// WithTempMount mounts the provided mounts to a temp dir, and pass the temp dir to f. +// The mounts are valid during the call to the f. +// Finally we will unmount and remove the temp dir regardless of the result of f. +func WithTempMount(ctx context.Context, mounts []Mount, f func(root string) error) (err error) { + root, uerr := ioutil.TempDir(tempMountLocation, "containerd-mount") + if uerr != nil { + return errors.Wrapf(uerr, "failed to create temp dir") + } + // We use Remove here instead of RemoveAll. + // The RemoveAll will delete the temp dir and all children it contains. + // When the Unmount fails, RemoveAll will incorrectly delete data from + // the mounted dir. However, if we use Remove, even though we won't + // successfully delete the temp dir and it may leak, we won't loss data + // from the mounted dir. + // For details, please refer to #1868 #1785. + defer func() { + if uerr = os.Remove(root); uerr != nil { + log.G(ctx).WithError(uerr).WithField("dir", root).Errorf("failed to remove mount temp dir") + } + }() + + // We should do defer first, if not we will not do Unmount when only a part of Mounts are failed. + defer func() { + if uerr = UnmountAll(root, 0); uerr != nil { + uerr = errors.Wrapf(uerr, "failed to unmount %s", root) + if err == nil { + err = uerr + } else { + err = errors.Wrap(err, uerr.Error()) + } + } + }() + if uerr = All(mounts, root); uerr != nil { + return errors.Wrapf(uerr, "failed to mount %s", root) + } + return errors.Wrapf(f(root), "mount callback failed on %s", root) +} diff --git a/components/engine/vendor/github.com/containerd/containerd/mount/temp_unix.go b/components/engine/vendor/github.com/containerd/containerd/mount/temp_unix.go new file mode 100644 index 0000000000..770631362a --- /dev/null +++ b/components/engine/vendor/github.com/containerd/containerd/mount/temp_unix.go @@ -0,0 +1,47 @@ +// +build !windows + +package mount + +import ( + "os" + "path/filepath" + "sort" + "strings" +) + +// SetTempMountLocation sets the temporary mount location +func SetTempMountLocation(root string) error { + root, err := filepath.Abs(root) + if err != nil { + return err + } + if err := os.MkdirAll(root, 0700); err != nil { + return err + } + tempMountLocation = root + return nil +} + +// CleanupTempMounts all temp mounts and remove the directories +func CleanupTempMounts(flags int) error { + mounts, err := Self() + if err != nil { + return err + } + var toUnmount []string + for _, m := range mounts { + if strings.HasPrefix(m.Mountpoint, tempMountLocation) { + toUnmount = append(toUnmount, m.Mountpoint) + } + } + sort.Sort(sort.Reverse(sort.StringSlice(toUnmount))) + for _, path := range toUnmount { + if err := UnmountAll(path, flags); err != nil { + return err + } + if err := os.Remove(path); err != nil { + return err + } + } + return nil +} diff --git a/components/engine/vendor/github.com/containerd/containerd/mount/temp_unsupported.go b/components/engine/vendor/github.com/containerd/containerd/mount/temp_unsupported.go new file mode 100644 index 0000000000..d3a188fc06 --- /dev/null +++ b/components/engine/vendor/github.com/containerd/containerd/mount/temp_unsupported.go @@ -0,0 +1,13 @@ +// +build windows + +package mount + +// SetTempMountLocation sets the temporary mount location +func SetTempMountLocation(root string) error { + return nil +} + +// CleanupTempMounts all temp mounts and remove the directories +func CleanupTempMounts(flags int) error { + return nil +} diff --git a/components/engine/vendor/github.com/containerd/containerd/namespaces.go b/components/engine/vendor/github.com/containerd/containerd/namespaces.go index 36fc50cabf..eea70ca33a 100644 --- a/components/engine/vendor/github.com/containerd/containerd/namespaces.go +++ b/components/engine/vendor/github.com/containerd/containerd/namespaces.go @@ -1,3 +1,19 @@ +/* + 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 ( diff --git a/components/engine/vendor/github.com/containerd/containerd/namespaces/context.go b/components/engine/vendor/github.com/containerd/containerd/namespaces/context.go index 7087114873..afcd9d1b0d 100644 --- a/components/engine/vendor/github.com/containerd/containerd/namespaces/context.go +++ b/components/engine/vendor/github.com/containerd/containerd/namespaces/context.go @@ -1,3 +1,19 @@ +/* + 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 namespaces import ( diff --git a/components/engine/vendor/github.com/containerd/containerd/namespaces/grpc.go b/components/engine/vendor/github.com/containerd/containerd/namespaces/grpc.go index c18fc933d1..fe1ca1d7cb 100644 --- a/components/engine/vendor/github.com/containerd/containerd/namespaces/grpc.go +++ b/components/engine/vendor/github.com/containerd/containerd/namespaces/grpc.go @@ -1,3 +1,19 @@ +/* + 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 namespaces import ( diff --git a/components/engine/vendor/github.com/containerd/containerd/namespaces/store.go b/components/engine/vendor/github.com/containerd/containerd/namespaces/store.go index 68ff714bb7..0b5c985691 100644 --- a/components/engine/vendor/github.com/containerd/containerd/namespaces/store.go +++ b/components/engine/vendor/github.com/containerd/containerd/namespaces/store.go @@ -1,3 +1,19 @@ +/* + 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 namespaces import "context" diff --git a/components/engine/vendor/github.com/containerd/containerd/namespaces/validate.go b/components/engine/vendor/github.com/containerd/containerd/namespaces/validate.go index ff97a8cc8b..222da3ea43 100644 --- a/components/engine/vendor/github.com/containerd/containerd/namespaces/validate.go +++ b/components/engine/vendor/github.com/containerd/containerd/namespaces/validate.go @@ -1,3 +1,19 @@ +/* + 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 namespaces provides tools for working with namespaces across // containerd. // diff --git a/components/engine/vendor/github.com/containerd/containerd/oci/client.go b/components/engine/vendor/github.com/containerd/containerd/oci/client.go index d2cd355c56..9923101bfa 100644 --- a/components/engine/vendor/github.com/containerd/containerd/oci/client.go +++ b/components/engine/vendor/github.com/containerd/containerd/oci/client.go @@ -1,3 +1,19 @@ +/* + 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 oci import ( diff --git a/components/engine/vendor/github.com/containerd/containerd/oci/spec.go b/components/engine/vendor/github.com/containerd/containerd/oci/spec.go index 558a3570f1..78284187a5 100644 --- a/components/engine/vendor/github.com/containerd/containerd/oci/spec.go +++ b/components/engine/vendor/github.com/containerd/containerd/oci/spec.go @@ -1,3 +1,19 @@ +/* + 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 oci import ( diff --git a/components/engine/vendor/github.com/containerd/containerd/oci/spec_opts.go b/components/engine/vendor/github.com/containerd/containerd/oci/spec_opts.go index c940c7aabd..53741ea80b 100644 --- a/components/engine/vendor/github.com/containerd/containerd/oci/spec_opts.go +++ b/components/engine/vendor/github.com/containerd/containerd/oci/spec_opts.go @@ -1,7 +1,24 @@ +/* + 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 oci import ( "context" + "strings" "github.com/containerd/containerd/containers" specs "github.com/opencontainers/runtime-spec/specs-go" @@ -33,3 +50,59 @@ func WithHostname(name string) SpecOpts { return nil } } + +// WithEnv appends environment variables +func WithEnv(environmentVariables []string) SpecOpts { + return func(_ context.Context, _ Client, _ *containers.Container, s *specs.Spec) error { + if len(environmentVariables) > 0 { + s.Process.Env = replaceOrAppendEnvValues(s.Process.Env, environmentVariables) + } + return nil + } +} + +// WithMounts appends mounts +func WithMounts(mounts []specs.Mount) SpecOpts { + return func(_ context.Context, _ Client, _ *containers.Container, s *specs.Spec) error { + s.Mounts = append(s.Mounts, mounts...) + return nil + } +} + +// replaceOrAppendEnvValues returns the defaults with the overrides either +// replaced by env key or appended to the list +func replaceOrAppendEnvValues(defaults, overrides []string) []string { + cache := make(map[string]int, len(defaults)) + for i, e := range defaults { + parts := strings.SplitN(e, "=", 2) + cache[parts[0]] = i + } + + for _, value := range overrides { + // Values w/o = means they want this env to be removed/unset. + if !strings.Contains(value, "=") { + if i, exists := cache[value]; exists { + defaults[i] = "" // Used to indicate it should be removed + } + continue + } + + // Just do a normal set/update + parts := strings.SplitN(value, "=", 2) + if i, exists := cache[parts[0]]; exists { + defaults[i] = value + } else { + defaults = append(defaults, value) + } + } + + // Now remove all entries that we want to "unset" + for i := 0; i < len(defaults); i++ { + if defaults[i] == "" { + defaults = append(defaults[:i], defaults[i+1:]...) + i-- + } + } + + return defaults +} diff --git a/components/engine/vendor/github.com/containerd/containerd/oci/spec_opts_unix.go b/components/engine/vendor/github.com/containerd/containerd/oci/spec_opts_unix.go index 865aff29a3..87d313addb 100644 --- a/components/engine/vendor/github.com/containerd/containerd/oci/spec_opts_unix.go +++ b/components/engine/vendor/github.com/containerd/containerd/oci/spec_opts_unix.go @@ -1,12 +1,27 @@ // +build !windows +/* + 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 oci import ( "context" "encoding/json" "fmt" - "io/ioutil" "os" "path/filepath" "strconv" @@ -14,14 +29,15 @@ import ( "github.com/containerd/containerd/containers" "github.com/containerd/containerd/content" - "github.com/containerd/containerd/fs" "github.com/containerd/containerd/images" "github.com/containerd/containerd/mount" "github.com/containerd/containerd/namespaces" + "github.com/containerd/continuity/fs" "github.com/opencontainers/image-spec/specs-go/v1" "github.com/opencontainers/runc/libcontainer/user" specs "github.com/opencontainers/runtime-spec/specs-go" "github.com/pkg/errors" + "github.com/syndtr/gocapability/capability" ) // WithTTY sets the information on the spec as well as the environment variables for @@ -96,22 +112,25 @@ func WithImageConfig(image Image) SpecOpts { s.Process.Env = append(s.Process.Env, config.Env...) cmd := config.Cmd s.Process.Args = append(config.Entrypoint, cmd...) + cwd := config.WorkingDir + if cwd == "" { + cwd = "/" + } + s.Process.Cwd = cwd if config.User != "" { + // According to OCI Image Spec v1.0.0, the following are valid for Linux: + // user, uid, user:group, uid:gid, uid:group, user:gid parts := strings.Split(config.User, ":") switch len(parts) { case 1: v, err := strconv.Atoi(parts[0]) if err != nil { // if we cannot parse as a uint they try to see if it is a username - if err := WithUsername(config.User)(ctx, client, c, s); err != nil { - return err - } - return err - } - if err := WithUserID(uint32(v))(ctx, client, c, s); err != nil { - return err + return WithUsername(config.User)(ctx, client, c, s) } + return WithUserID(uint32(v))(ctx, client, c, s) case 2: + // TODO: support username and groupname v, err := strconv.Atoi(parts[0]) if err != nil { return errors.Wrapf(err, "parse uid %s", parts[0]) @@ -126,11 +145,6 @@ func WithImageConfig(image Image) SpecOpts { return fmt.Errorf("invalid USER value %s", config.User) } } - cwd := config.WorkingDir - if cwd == "" { - cwd = "/" - } - s.Process.Cwd = cwd return nil } } @@ -260,6 +274,24 @@ func WithUIDGID(uid, gid uint32) SpecOpts { // uid, and not returns error. func WithUserID(uid uint32) SpecOpts { return func(ctx context.Context, client Client, c *containers.Container, s *specs.Spec) (err error) { + if c.Snapshotter == "" && c.SnapshotKey == "" { + if !isRootfsAbs(s.Root.Path) { + return errors.Errorf("rootfs absolute path is required") + } + uuid, ugid, err := getUIDGIDFromPath(s.Root.Path, func(u user.User) bool { + return u.Uid == int(uid) + }) + if err != nil { + if os.IsNotExist(err) || err == errNoUsersFound { + s.Process.User.UID, s.Process.User.GID = uid, uid + return nil + } + return err + } + s.Process.User.UID, s.Process.User.GID = uuid, ugid + return nil + + } if c.Snapshotter == "" { return errors.Errorf("no snapshotter set for container") } @@ -271,49 +303,20 @@ func WithUserID(uid uint32) SpecOpts { if err != nil { return err } - root, err := ioutil.TempDir("", "ctd-username") - if err != nil { - return err - } - defer os.Remove(root) - for _, m := range mounts { - if err := m.Mount(root); err != nil { + return mount.WithTempMount(ctx, mounts, func(root string) error { + uuid, ugid, err := getUIDGIDFromPath(root, func(u user.User) bool { + return u.Uid == int(uid) + }) + if err != nil { + if os.IsNotExist(err) || err == errNoUsersFound { + s.Process.User.UID, s.Process.User.GID = uid, uid + return nil + } return err } - } - defer func() { - if uerr := mount.Unmount(root, 0); uerr != nil { - if err == nil { - err = uerr - } - } - }() - ppath, err := fs.RootPath(root, "/etc/passwd") - if err != nil { - return err - } - f, err := os.Open(ppath) - if err != nil { - if os.IsNotExist(err) { - s.Process.User.UID, s.Process.User.GID = uid, uid - return nil - } - return err - } - defer f.Close() - users, err := user.ParsePasswdFilter(f, func(u user.User) bool { - return u.Uid == int(uid) - }) - if err != nil { - return err - } - if len(users) == 0 { - s.Process.User.UID, s.Process.User.GID = uid, uid + s.Process.User.UID, s.Process.User.GID = uuid, ugid return nil - } - u := users[0] - s.Process.User.UID, s.Process.User.GID = uint32(u.Uid), uint32(u.Gid) - return nil + }) } } @@ -323,6 +326,19 @@ func WithUserID(uid uint32) SpecOpts { // it returns error. func WithUsername(username string) SpecOpts { return func(ctx context.Context, client Client, c *containers.Container, s *specs.Spec) (err error) { + if c.Snapshotter == "" && c.SnapshotKey == "" { + if !isRootfsAbs(s.Root.Path) { + return errors.Errorf("rootfs absolute path is required") + } + uid, gid, err := getUIDGIDFromPath(s.Root.Path, func(u user.User) bool { + return u.Name == username + }) + if err != nil { + return err + } + s.Process.User.UID, s.Process.User.GID = uid, gid + return nil + } if c.Snapshotter == "" { return errors.Errorf("no snapshotter set for container") } @@ -334,43 +350,70 @@ func WithUsername(username string) SpecOpts { if err != nil { return err } - root, err := ioutil.TempDir("", "ctd-username") - if err != nil { - return err - } - defer os.Remove(root) - for _, m := range mounts { - if err := m.Mount(root); err != nil { + return mount.WithTempMount(ctx, mounts, func(root string) error { + uid, gid, err := getUIDGIDFromPath(root, func(u user.User) bool { + return u.Name == username + }) + if err != nil { return err } - } - defer func() { - if uerr := mount.Unmount(root, 0); uerr != nil { - if err == nil { - err = uerr - } - } - }() - ppath, err := fs.RootPath(root, "/etc/passwd") - if err != nil { - return err - } - f, err := os.Open(ppath) - if err != nil { - return err - } - defer f.Close() - users, err := user.ParsePasswdFilter(f, func(u user.User) bool { - return u.Name == username + s.Process.User.UID, s.Process.User.GID = uid, gid + return nil }) - if err != nil { - return err - } - if len(users) == 0 { - return errors.Errorf("no users found for %s", username) - } - u := users[0] - s.Process.User.UID, s.Process.User.GID = uint32(u.Uid), uint32(u.Gid) - return nil } } + +// WithAllCapabilities set all linux capabilities for the process +func WithAllCapabilities(_ context.Context, _ Client, _ *containers.Container, s *specs.Spec) error { + caps := getAllCapabilities() + + s.Process.Capabilities.Bounding = caps + s.Process.Capabilities.Effective = caps + s.Process.Capabilities.Permitted = caps + s.Process.Capabilities.Inheritable = caps + + return nil +} + +func getAllCapabilities() []string { + last := capability.CAP_LAST_CAP + // hack for RHEL6 which has no /proc/sys/kernel/cap_last_cap + if last == capability.Cap(63) { + last = capability.CAP_BLOCK_SUSPEND + } + var caps []string + for _, cap := range capability.List() { + if cap > last { + continue + } + caps = append(caps, "CAP_"+strings.ToUpper(cap.String())) + } + return caps +} + +var errNoUsersFound = errors.New("no users found") + +func getUIDGIDFromPath(root string, filter func(user.User) bool) (uid, gid uint32, err error) { + ppath, err := fs.RootPath(root, "/etc/passwd") + if err != nil { + return 0, 0, err + } + f, err := os.Open(ppath) + if err != nil { + return 0, 0, err + } + defer f.Close() + users, err := user.ParsePasswdFilter(f, filter) + if err != nil { + return 0, 0, err + } + if len(users) == 0 { + return 0, 0, errNoUsersFound + } + u := users[0] + return uint32(u.Uid), uint32(u.Gid), nil +} + +func isRootfsAbs(root string) bool { + return filepath.IsAbs(root) +} diff --git a/components/engine/vendor/github.com/containerd/containerd/oci/spec_opts_windows.go b/components/engine/vendor/github.com/containerd/containerd/oci/spec_opts_windows.go index 796ad55981..5b8ebba130 100644 --- a/components/engine/vendor/github.com/containerd/containerd/oci/spec_opts_windows.go +++ b/components/engine/vendor/github.com/containerd/containerd/oci/spec_opts_windows.go @@ -1,5 +1,21 @@ // +build windows +/* + 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 oci import ( diff --git a/components/engine/vendor/github.com/containerd/containerd/oci/spec_unix.go b/components/engine/vendor/github.com/containerd/containerd/oci/spec_unix.go index c8f3b37afb..e52e422281 100644 --- a/components/engine/vendor/github.com/containerd/containerd/oci/spec_unix.go +++ b/components/engine/vendor/github.com/containerd/containerd/oci/spec_unix.go @@ -1,5 +1,21 @@ // +build !windows +/* + 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 oci import ( diff --git a/components/engine/vendor/github.com/containerd/containerd/oci/spec_windows.go b/components/engine/vendor/github.com/containerd/containerd/oci/spec_windows.go index 64c228883d..f8cdb8a9b4 100644 --- a/components/engine/vendor/github.com/containerd/containerd/oci/spec_windows.go +++ b/components/engine/vendor/github.com/containerd/containerd/oci/spec_windows.go @@ -1,3 +1,19 @@ +/* + 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 oci import ( diff --git a/components/engine/vendor/github.com/containerd/containerd/platforms/cpuinfo.go b/components/engine/vendor/github.com/containerd/containerd/platforms/cpuinfo.go new file mode 100644 index 0000000000..a5c5ab42b9 --- /dev/null +++ b/components/engine/vendor/github.com/containerd/containerd/platforms/cpuinfo.go @@ -0,0 +1,101 @@ +/* + 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 platforms + +import ( + "bufio" + "os" + "runtime" + "strings" + + "github.com/containerd/containerd/errdefs" + "github.com/containerd/containerd/log" + "github.com/pkg/errors" +) + +// Present the ARM instruction set architecture, eg: v7, v8 +var cpuVariant string + +func init() { + if isArmArch(runtime.GOARCH) { + cpuVariant = getCPUVariant() + } else { + cpuVariant = "" + } +} + +// For Linux, the kernel has already detected the ABI, ISA and Features. +// So we don't need to access the ARM registers to detect platform information +// by ourselves. We can just parse these information from /proc/cpuinfo +func getCPUInfo(pattern string) (info string, err error) { + if !isLinuxOS(runtime.GOOS) { + return "", errors.Wrapf(errdefs.ErrNotImplemented, "getCPUInfo for OS %s", runtime.GOOS) + } + + cpuinfo, err := os.Open("/proc/cpuinfo") + if err != nil { + return "", err + } + defer cpuinfo.Close() + + // Start to Parse the Cpuinfo line by line. For SMP SoC, we parse + // the first core is enough. + scanner := bufio.NewScanner(cpuinfo) + for scanner.Scan() { + newline := scanner.Text() + list := strings.Split(newline, ":") + + if len(list) > 1 && strings.EqualFold(strings.TrimSpace(list[0]), pattern) { + return strings.TrimSpace(list[1]), nil + } + } + + // Check whether the scanner encountered errors + err = scanner.Err() + if err != nil { + return "", err + } + + return "", errors.Wrapf(errdefs.ErrNotFound, "getCPUInfo for pattern: %s", pattern) +} + +func getCPUVariant() string { + variant, err := getCPUInfo("Cpu architecture") + if err != nil { + log.L.WithError(err).Error("failure getting variant") + return "" + } + + switch variant { + case "8": + variant = "v8" + case "7", "7M", "?(12)", "?(13)", "?(14)", "?(15)", "?(16)", "?(17)": + variant = "v7" + case "6", "6TEJ": + variant = "v6" + case "5", "5T", "5TE", "5TEJ": + variant = "v5" + case "4", "4T": + variant = "v4" + case "3": + variant = "v3" + default: + variant = "unknown" + } + + return variant +} diff --git a/components/engine/vendor/github.com/containerd/containerd/platforms/database.go b/components/engine/vendor/github.com/containerd/containerd/platforms/database.go index bd66e2517f..df9cc2392a 100644 --- a/components/engine/vendor/github.com/containerd/containerd/platforms/database.go +++ b/components/engine/vendor/github.com/containerd/containerd/platforms/database.go @@ -1,3 +1,19 @@ +/* + 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 platforms import ( @@ -5,6 +21,13 @@ import ( "strings" ) +// isLinuxOS returns true if the operating system is Linux. +// +// The OS value should be normalized before calling this function. +func isLinuxOS(os string) bool { + return os == "linux" +} + // These function are generated from from https://golang.org/src/go/build/syslist.go. // // We use switch statements because they are slightly faster than map lookups @@ -21,6 +44,17 @@ func isKnownOS(os string) bool { return false } +// isArmArch returns true if the architecture is ARM. +// +// The arch value should be normalized before being passed to this function. +func isArmArch(arch string) bool { + switch arch { + case "arm", "arm64": + return true + } + return false +} + // isKnownArch returns true if we know about the architecture. // // The arch value should be normalized before being passed to this function. diff --git a/components/engine/vendor/github.com/containerd/containerd/platforms/defaults.go b/components/engine/vendor/github.com/containerd/containerd/platforms/defaults.go index 2b57b49795..dee59abadc 100644 --- a/components/engine/vendor/github.com/containerd/containerd/platforms/defaults.go +++ b/components/engine/vendor/github.com/containerd/containerd/platforms/defaults.go @@ -1,3 +1,19 @@ +/* + 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 platforms import ( @@ -16,6 +32,7 @@ func DefaultSpec() specs.Platform { return specs.Platform{ OS: runtime.GOOS, Architecture: runtime.GOARCH, - // TODO(stevvooe): Need to resolve GOARM for arm hosts. + // The Variant field will be empty if arch != ARM. + Variant: cpuVariant, } } diff --git a/components/engine/vendor/github.com/containerd/containerd/platforms/platforms.go b/components/engine/vendor/github.com/containerd/containerd/platforms/platforms.go index 56c6ddc511..77b6d8410d 100644 --- a/components/engine/vendor/github.com/containerd/containerd/platforms/platforms.go +++ b/components/engine/vendor/github.com/containerd/containerd/platforms/platforms.go @@ -1,3 +1,19 @@ +/* + 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 platforms provides a toolkit for normalizing, matching and // specifying container platforms. // diff --git a/components/engine/vendor/github.com/containerd/containerd/plugin/context.go b/components/engine/vendor/github.com/containerd/containerd/plugin/context.go index 87e53b84f2..1211c907ef 100644 --- a/components/engine/vendor/github.com/containerd/containerd/plugin/context.go +++ b/components/engine/vendor/github.com/containerd/containerd/plugin/context.go @@ -1,3 +1,19 @@ +/* + 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 plugin import ( @@ -6,7 +22,6 @@ import ( "github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/events/exchange" - "github.com/containerd/containerd/log" ocispec "github.com/opencontainers/image-spec/specs-go/v1" "github.com/pkg/errors" ) @@ -28,7 +43,7 @@ type InitContext struct { // NewContext returns a new plugin InitContext func NewContext(ctx context.Context, r *Registration, plugins *Set, root, state string) *InitContext { return &InitContext{ - Context: log.WithModule(ctx, r.URI()), + Context: ctx, Root: filepath.Join(root, r.URI()), State: filepath.Join(state, r.URI()), Meta: &Meta{ diff --git a/components/engine/vendor/github.com/containerd/containerd/plugin/plugin.go b/components/engine/vendor/github.com/containerd/containerd/plugin/plugin.go index 5746bf72d7..470429a0c7 100644 --- a/components/engine/vendor/github.com/containerd/containerd/plugin/plugin.go +++ b/components/engine/vendor/github.com/containerd/containerd/plugin/plugin.go @@ -1,3 +1,19 @@ +/* + 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 plugin import ( @@ -140,10 +156,19 @@ func Register(r *Registration) { register.r = append(register.r, r) } -// Graph returns an ordered list of registered plugins for initialization -func Graph() (ordered []*Registration) { +// Graph returns an ordered list of registered plugins for initialization. +// Plugins in disableList specified by id will be disabled. +func Graph(disableList []string) (ordered []*Registration) { register.RLock() defer register.RUnlock() + for _, d := range disableList { + for i, r := range register.r { + if r.ID == d { + register.r = append(register.r[:i], register.r[i+1:]...) + break + } + } + } added := map[*Registration]bool{} for _, r := range register.r { diff --git a/components/engine/vendor/github.com/containerd/containerd/plugin/plugin_go18.go b/components/engine/vendor/github.com/containerd/containerd/plugin/plugin_go18.go index eee0e3fdb7..5b82db8685 100644 --- a/components/engine/vendor/github.com/containerd/containerd/plugin/plugin_go18.go +++ b/components/engine/vendor/github.com/containerd/containerd/plugin/plugin_go18.go @@ -1,5 +1,21 @@ // +build go1.8,!windows,amd64,!static_build +/* + 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 plugin import ( diff --git a/components/engine/vendor/github.com/containerd/containerd/plugin/plugin_other.go b/components/engine/vendor/github.com/containerd/containerd/plugin/plugin_other.go index 180917af80..2978f60fd3 100644 --- a/components/engine/vendor/github.com/containerd/containerd/plugin/plugin_other.go +++ b/components/engine/vendor/github.com/containerd/containerd/plugin/plugin_other.go @@ -1,5 +1,21 @@ // +build !go1.8 windows !amd64 static_build +/* + 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 plugin func loadPlugins(path string) error { diff --git a/components/engine/vendor/github.com/containerd/containerd/process.go b/components/engine/vendor/github.com/containerd/containerd/process.go index 32049cf075..6b11203373 100644 --- a/components/engine/vendor/github.com/containerd/containerd/process.go +++ b/components/engine/vendor/github.com/containerd/containerd/process.go @@ -1,3 +1,19 @@ +/* + 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 ( diff --git a/components/engine/vendor/github.com/containerd/containerd/protobuf/google/rpc/doc.go b/components/engine/vendor/github.com/containerd/containerd/protobuf/google/rpc/doc.go index 9ab1e3e8e7..c76291766b 100644 --- a/components/engine/vendor/github.com/containerd/containerd/protobuf/google/rpc/doc.go +++ b/components/engine/vendor/github.com/containerd/containerd/protobuf/google/rpc/doc.go @@ -1 +1,17 @@ +/* + 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 rpc diff --git a/components/engine/vendor/github.com/containerd/containerd/reaper/reaper.go b/components/engine/vendor/github.com/containerd/containerd/reaper/reaper.go index 9127fc5a18..bdcb14c267 100644 --- a/components/engine/vendor/github.com/containerd/containerd/reaper/reaper.go +++ b/components/engine/vendor/github.com/containerd/containerd/reaper/reaper.go @@ -1,5 +1,21 @@ // +build !windows +/* + 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 reaper import ( @@ -15,7 +31,7 @@ import ( // ErrNoSuchProcess is returned when the process no longer exists var ErrNoSuchProcess = errors.New("no such process") -const bufferSize = 1024 +const bufferSize = 32 // Reap should be called when the process receives an SIGCHLD. Reap will reap // all exited processes and close their wait channels diff --git a/components/engine/vendor/github.com/containerd/containerd/reference/reference.go b/components/engine/vendor/github.com/containerd/containerd/reference/reference.go index 55c43b881c..79f165de02 100644 --- a/components/engine/vendor/github.com/containerd/containerd/reference/reference.go +++ b/components/engine/vendor/github.com/containerd/containerd/reference/reference.go @@ -1,3 +1,19 @@ +/* + 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 reference import ( diff --git a/components/engine/vendor/github.com/containerd/containerd/remotes/docker/auth.go b/components/engine/vendor/github.com/containerd/containerd/remotes/docker/auth.go index aa33752a62..80bcb9dcf7 100644 --- a/components/engine/vendor/github.com/containerd/containerd/remotes/docker/auth.go +++ b/components/engine/vendor/github.com/containerd/containerd/remotes/docker/auth.go @@ -1,3 +1,19 @@ +/* + 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 ( diff --git a/components/engine/vendor/github.com/containerd/containerd/remotes/docker/fetcher.go b/components/engine/vendor/github.com/containerd/containerd/remotes/docker/fetcher.go index 222cf83c0c..51e605e12d 100644 --- a/components/engine/vendor/github.com/containerd/containerd/remotes/docker/fetcher.go +++ b/components/engine/vendor/github.com/containerd/containerd/remotes/docker/fetcher.go @@ -1,3 +1,19 @@ +/* + 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 ( diff --git a/components/engine/vendor/github.com/containerd/containerd/remotes/docker/httpreadseeker.go b/components/engine/vendor/github.com/containerd/containerd/remotes/docker/httpreadseeker.go index f6de60a274..5a77789537 100644 --- a/components/engine/vendor/github.com/containerd/containerd/remotes/docker/httpreadseeker.go +++ b/components/engine/vendor/github.com/containerd/containerd/remotes/docker/httpreadseeker.go @@ -1,3 +1,19 @@ +/* + 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 ( diff --git a/components/engine/vendor/github.com/containerd/containerd/remotes/docker/pusher.go b/components/engine/vendor/github.com/containerd/containerd/remotes/docker/pusher.go index 405480b541..e2caf70286 100644 --- a/components/engine/vendor/github.com/containerd/containerd/remotes/docker/pusher.go +++ b/components/engine/vendor/github.com/containerd/containerd/remotes/docker/pusher.go @@ -1,3 +1,19 @@ +/* + 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 ( diff --git a/components/engine/vendor/github.com/containerd/containerd/remotes/docker/resolver.go b/components/engine/vendor/github.com/containerd/containerd/remotes/docker/resolver.go index 57a18b664a..06b1724b44 100644 --- a/components/engine/vendor/github.com/containerd/containerd/remotes/docker/resolver.go +++ b/components/engine/vendor/github.com/containerd/containerd/remotes/docker/resolver.go @@ -1,3 +1,19 @@ +/* + 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 ( @@ -136,6 +152,9 @@ func (r *dockerResolver) Resolve(ctx context.Context, ref string) (string, ocisp log.G(ctx).Debug("resolving") resp, err := fetcher.doRequestWithRetries(ctx, req, nil) if err != nil { + if errors.Cause(err) == ErrInvalidAuthorization { + err = errors.Wrapf(err, "pull access denied, repository does not exist or may require authorization") + } return "", ocispec.Descriptor{}, err } resp.Body.Close() // don't care about body contents. diff --git a/components/engine/vendor/github.com/containerd/containerd/remotes/docker/schema1/converter.go b/components/engine/vendor/github.com/containerd/containerd/remotes/docker/schema1/converter.go index 6b74cd67ee..1cf4dd7a1b 100644 --- a/components/engine/vendor/github.com/containerd/containerd/remotes/docker/schema1/converter.go +++ b/components/engine/vendor/github.com/containerd/containerd/remotes/docker/schema1/converter.go @@ -1,3 +1,19 @@ +/* + 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 schema1 import ( @@ -103,8 +119,41 @@ func (c *Converter) Handle(ctx context.Context, desc ocispec.Descriptor) ([]ocis } } +// ConvertOptions provides options on converting a docker schema1 manifest. +type ConvertOptions struct { + // ManifestMediaType specifies the media type of the manifest OCI descriptor. + ManifestMediaType string + + // ConfigMediaType specifies the media type of the manifest config OCI + // descriptor. + ConfigMediaType string +} + +// ConvertOpt allows configuring a convert operation. +type ConvertOpt func(context.Context, *ConvertOptions) error + +// UseDockerSchema2 is used to indicate that a schema1 manifest should be +// converted into the media types for a docker schema2 manifest. +func UseDockerSchema2() ConvertOpt { + return func(ctx context.Context, o *ConvertOptions) error { + o.ManifestMediaType = images.MediaTypeDockerSchema2Manifest + o.ConfigMediaType = images.MediaTypeDockerSchema2Config + return nil + } +} + // Convert a docker manifest to an OCI descriptor -func (c *Converter) Convert(ctx context.Context) (ocispec.Descriptor, error) { +func (c *Converter) Convert(ctx context.Context, opts ...ConvertOpt) (ocispec.Descriptor, error) { + co := ConvertOptions{ + ManifestMediaType: ocispec.MediaTypeImageManifest, + ConfigMediaType: ocispec.MediaTypeImageConfig, + } + for _, opt := range opts { + if err := opt(ctx, &co); err != nil { + return ocispec.Descriptor{}, err + } + } + history, diffIDs, err := c.schema1ManifestHistory() if err != nil { return ocispec.Descriptor{}, errors.Wrap(err, "schema 1 conversion failed") @@ -121,13 +170,13 @@ func (c *Converter) Convert(ctx context.Context) (ocispec.Descriptor, error) { DiffIDs: diffIDs, } - b, err := json.Marshal(img) + b, err := json.MarshalIndent(img, "", " ") if err != nil { return ocispec.Descriptor{}, errors.Wrap(err, "failed to marshal image") } config := ocispec.Descriptor{ - MediaType: ocispec.MediaTypeImageConfig, + MediaType: co.ConfigMediaType, Digest: digest.Canonical.FromBytes(b), Size: int64(len(b)), } @@ -145,13 +194,13 @@ func (c *Converter) Convert(ctx context.Context) (ocispec.Descriptor, error) { Layers: layers, } - mb, err := json.Marshal(manifest) + mb, err := json.MarshalIndent(manifest, "", " ") if err != nil { return ocispec.Descriptor{}, errors.Wrap(err, "failed to marshal image") } desc := ocispec.Descriptor{ - MediaType: ocispec.MediaTypeImageManifest, + MediaType: co.ManifestMediaType, Digest: digest.Canonical.FromBytes(mb), Size: int64(len(mb)), } diff --git a/components/engine/vendor/github.com/containerd/containerd/remotes/docker/scope.go b/components/engine/vendor/github.com/containerd/containerd/remotes/docker/scope.go index 9cf0997dc2..52c2443118 100644 --- a/components/engine/vendor/github.com/containerd/containerd/remotes/docker/scope.go +++ b/components/engine/vendor/github.com/containerd/containerd/remotes/docker/scope.go @@ -1,3 +1,19 @@ +/* + 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 ( diff --git a/components/engine/vendor/github.com/containerd/containerd/remotes/docker/status.go b/components/engine/vendor/github.com/containerd/containerd/remotes/docker/status.go index 4b8dbbc5c4..8069d67671 100644 --- a/components/engine/vendor/github.com/containerd/containerd/remotes/docker/status.go +++ b/components/engine/vendor/github.com/containerd/containerd/remotes/docker/status.go @@ -1,3 +1,19 @@ +/* + 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 ( diff --git a/components/engine/vendor/github.com/containerd/containerd/remotes/handlers.go b/components/engine/vendor/github.com/containerd/containerd/remotes/handlers.go index ad4cd9f312..3353848100 100644 --- a/components/engine/vendor/github.com/containerd/containerd/remotes/handlers.go +++ b/components/engine/vendor/github.com/containerd/containerd/remotes/handlers.go @@ -1,17 +1,35 @@ +/* + 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 remotes import ( "context" - "encoding/json" "fmt" "io" "math/rand" + "strings" + "sync" "time" "github.com/containerd/containerd/content" "github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/images" "github.com/containerd/containerd/log" + "github.com/containerd/containerd/platforms" ocispec "github.com/opencontainers/image-spec/specs-go/v1" "github.com/pkg/errors" "github.com/sirupsen/logrus" @@ -99,88 +117,32 @@ func fetch(ctx context.Context, ingester content.Ingester, fetcher Fetcher, desc break } + ws, err := cw.Status() + if err != nil { + return err + } + + if ws.Offset == desc.Size { + // If writer is already complete, commit and return + err := cw.Commit(ctx, desc.Size, desc.Digest) + if err != nil && !errdefs.IsAlreadyExists(err) { + return errors.Wrapf(err, "failed commit on ref %q", ws.Ref) + } + return nil + } + rc, err := fetcher.Fetch(ctx, desc) if err != nil { return err } defer rc.Close() - r, opts := commitOpts(desc, rc) - return content.Copy(ctx, cw, r, desc.Size, desc.Digest, opts...) -} - -// commitOpts gets the appropriate content options to alter -// the content info on commit based on media type. -func commitOpts(desc ocispec.Descriptor, r io.Reader) (io.Reader, []content.Opt) { - var childrenF func(r io.Reader) ([]ocispec.Descriptor, error) - - // TODO(AkihiroSuda): use images/oci.GetChildrenDescriptors? - switch desc.MediaType { - case images.MediaTypeDockerSchema2Manifest, ocispec.MediaTypeImageManifest: - childrenF = func(r io.Reader) ([]ocispec.Descriptor, error) { - var ( - manifest ocispec.Manifest - decoder = json.NewDecoder(r) - ) - if err := decoder.Decode(&manifest); err != nil { - return nil, err - } - - return append([]ocispec.Descriptor{manifest.Config}, manifest.Layers...), nil - } - case images.MediaTypeDockerSchema2ManifestList, ocispec.MediaTypeImageIndex: - childrenF = func(r io.Reader) ([]ocispec.Descriptor, error) { - var ( - index ocispec.Index - decoder = json.NewDecoder(r) - ) - if err := decoder.Decode(&index); err != nil { - return nil, err - } - - return index.Manifests, nil - } - default: - return r, nil - } - - pr, pw := io.Pipe() - - var children []ocispec.Descriptor - errC := make(chan error) - - go func() { - defer close(errC) - ch, err := childrenF(pr) - if err != nil { - errC <- err - } - children = ch - }() - - opt := func(info *content.Info) error { - err := <-errC - if err != nil { - return errors.Wrap(err, "unable to get commit labels") - } - - if len(children) > 0 { - if info.Labels == nil { - info.Labels = map[string]string{} - } - for i, ch := range children { - info.Labels[fmt.Sprintf("containerd.io/gc.ref.content.%d", i)] = ch.Digest.String() - } - } - return nil - } - - return io.TeeReader(r, pw), []content.Opt{opt} + return content.Copy(ctx, cw, rc, desc.Size, desc.Digest) } // PushHandler returns a handler that will push all content from the provider // using a writer from the pusher. -func PushHandler(provider content.Provider, pusher Pusher) images.HandlerFunc { +func PushHandler(pusher Pusher, provider content.Provider) images.HandlerFunc { return func(ctx context.Context, desc ocispec.Descriptor) ([]ocispec.Descriptor, error) { ctx = log.WithLogger(ctx, log.G(ctx).WithFields(logrus.Fields{ "digest": desc.Digest, @@ -215,3 +177,55 @@ func push(ctx context.Context, provider content.Provider, pusher Pusher, desc oc rd := io.NewSectionReader(ra, 0, desc.Size) return content.Copy(ctx, cw, rd, desc.Size, desc.Digest) } + +// PushContent pushes content specified by the descriptor from the provider. +// +// Base handlers can be provided which will be called before any push specific +// handlers. +func PushContent(ctx context.Context, pusher Pusher, desc ocispec.Descriptor, provider content.Provider, baseHandlers ...images.Handler) error { + var m sync.Mutex + manifestStack := []ocispec.Descriptor{} + + filterHandler := images.HandlerFunc(func(ctx context.Context, desc ocispec.Descriptor) ([]ocispec.Descriptor, error) { + switch desc.MediaType { + case images.MediaTypeDockerSchema2Manifest, ocispec.MediaTypeImageManifest, + images.MediaTypeDockerSchema2ManifestList, ocispec.MediaTypeImageIndex: + m.Lock() + manifestStack = append(manifestStack, desc) + m.Unlock() + return nil, images.ErrStopHandler + default: + return nil, nil + } + }) + + pushHandler := PushHandler(pusher, provider) + + handlers := append(baseHandlers, + images.FilterPlatform(platforms.Default(), images.ChildrenHandler(provider)), + filterHandler, + pushHandler, + ) + + if err := images.Dispatch(ctx, images.Handlers(handlers...), desc); err != nil { + return err + } + + // Iterate in reverse order as seen, parent always uploaded after child + for i := len(manifestStack) - 1; i >= 0; i-- { + _, err := pushHandler(ctx, manifestStack[i]) + if err != nil { + // TODO(estesp): until we have a more complete method for index push, we need to report + // missing dependencies in an index/manifest list by sensing the "400 Bad Request" + // as a marker for this problem + if (manifestStack[i].MediaType == ocispec.MediaTypeImageIndex || + manifestStack[i].MediaType == images.MediaTypeDockerSchema2ManifestList) && + errors.Cause(err) != nil && strings.Contains(errors.Cause(err).Error(), "400 Bad Request") { + return errors.Wrap(err, "manifest list/index references to blobs and/or manifests are missing in your target registry") + } + return err + } + } + + return nil +} diff --git a/components/engine/vendor/github.com/containerd/containerd/remotes/resolver.go b/components/engine/vendor/github.com/containerd/containerd/remotes/resolver.go index caf4c97ce1..a9b2b78aa8 100644 --- a/components/engine/vendor/github.com/containerd/containerd/remotes/resolver.go +++ b/components/engine/vendor/github.com/containerd/containerd/remotes/resolver.go @@ -1,3 +1,19 @@ +/* + 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 remotes import ( diff --git a/components/engine/vendor/github.com/containerd/containerd/rootfs/apply.go b/components/engine/vendor/github.com/containerd/containerd/rootfs/apply.go index 405129564a..73613337df 100644 --- a/components/engine/vendor/github.com/containerd/containerd/rootfs/apply.go +++ b/components/engine/vendor/github.com/containerd/containerd/rootfs/apply.go @@ -1,3 +1,19 @@ +/* + 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 rootfs import ( @@ -30,7 +46,7 @@ type Layer struct { // The returned result is a chain id digest representing all the applied layers. // Layers are applied in order they are given, making the first layer the // bottom-most layer in the layer chain. -func ApplyLayers(ctx context.Context, layers []Layer, sn snapshots.Snapshotter, a diff.Differ) (digest.Digest, error) { +func ApplyLayers(ctx context.Context, layers []Layer, sn snapshots.Snapshotter, a diff.Applier) (digest.Digest, error) { var chain []digest.Digest for _, layer := range layers { if _, err := ApplyLayer(ctx, layer, chain, sn, a); err != nil { @@ -46,7 +62,7 @@ func ApplyLayers(ctx context.Context, layers []Layer, sn snapshots.Snapshotter, // ApplyLayer applies a single layer on top of the given provided layer chain, // using the provided snapshotter and applier. If the layer was unpacked true // is returned, if the layer already exists false is returned. -func ApplyLayer(ctx context.Context, layer Layer, chain []digest.Digest, sn snapshots.Snapshotter, a diff.Differ, opts ...snapshots.Opt) (bool, error) { +func ApplyLayer(ctx context.Context, layer Layer, chain []digest.Digest, sn snapshots.Snapshotter, a diff.Applier, opts ...snapshots.Opt) (bool, error) { var ( parent = identity.ChainID(chain) chainID = identity.ChainID(append(chain, layer.Diff.Digest)) diff --git a/components/engine/vendor/github.com/containerd/containerd/rootfs/diff.go b/components/engine/vendor/github.com/containerd/containerd/rootfs/diff.go index bab7a3cca1..c7f954e9ff 100644 --- a/components/engine/vendor/github.com/containerd/containerd/rootfs/diff.go +++ b/components/engine/vendor/github.com/containerd/containerd/rootfs/diff.go @@ -1,3 +1,19 @@ +/* + 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 rootfs import ( @@ -10,11 +26,11 @@ import ( "golang.org/x/net/context" ) -// Diff creates a layer diff for the given snapshot identifier from the parent -// of the snapshot. A content ref is provided to track the progress of the -// content creation and the provided snapshotter and mount differ are used +// CreateDiff creates a layer diff for the given snapshot identifier from the +// parent of the snapshot. A content ref is provided to track the progress of +// the content creation and the provided snapshotter and mount differ are used // for calculating the diff. The descriptor for the layer diff is returned. -func Diff(ctx context.Context, snapshotID string, sn snapshots.Snapshotter, d diff.Differ, opts ...diff.Opt) (ocispec.Descriptor, error) { +func CreateDiff(ctx context.Context, snapshotID string, sn snapshots.Snapshotter, d diff.Comparer, opts ...diff.Opt) (ocispec.Descriptor, error) { info, err := sn.Stat(ctx, snapshotID) if err != nil { return ocispec.Descriptor{}, err @@ -39,8 +55,8 @@ func Diff(ctx context.Context, snapshotID string, sn snapshots.Snapshotter, d di if err != nil { return ocispec.Descriptor{}, err } - defer sn.Remove(ctx, lowerKey) + defer sn.Remove(ctx, upperKey) } - return d.DiffMounts(ctx, lower, upper, opts...) + return d.Compare(ctx, lower, upper, opts...) } diff --git a/components/engine/vendor/github.com/containerd/containerd/rootfs/init.go b/components/engine/vendor/github.com/containerd/containerd/rootfs/init.go index 4f32f11ae7..326f30f709 100644 --- a/components/engine/vendor/github.com/containerd/containerd/rootfs/init.go +++ b/components/engine/vendor/github.com/containerd/containerd/rootfs/init.go @@ -1,3 +1,19 @@ +/* + 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 rootfs import ( diff --git a/components/engine/vendor/github.com/containerd/containerd/rootfs/init_linux.go b/components/engine/vendor/github.com/containerd/containerd/rootfs/init_linux.go index cabc4577e0..84dc56522d 100644 --- a/components/engine/vendor/github.com/containerd/containerd/rootfs/init_linux.go +++ b/components/engine/vendor/github.com/containerd/containerd/rootfs/init_linux.go @@ -1,3 +1,19 @@ +/* + 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 rootfs import ( diff --git a/components/engine/vendor/github.com/containerd/containerd/rootfs/init_other.go b/components/engine/vendor/github.com/containerd/containerd/rootfs/init_other.go index b5e04e2e60..261121085d 100644 --- a/components/engine/vendor/github.com/containerd/containerd/rootfs/init_other.go +++ b/components/engine/vendor/github.com/containerd/containerd/rootfs/init_other.go @@ -1,5 +1,21 @@ // +build !linux +/* + 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 rootfs const ( diff --git a/components/engine/vendor/github.com/containerd/containerd/runtime/events.go b/components/engine/vendor/github.com/containerd/containerd/runtime/events.go index 36b701dd3c..4a064c8854 100644 --- a/components/engine/vendor/github.com/containerd/containerd/runtime/events.go +++ b/components/engine/vendor/github.com/containerd/containerd/runtime/events.go @@ -1,3 +1,19 @@ +/* + 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 runtime const ( diff --git a/components/engine/vendor/github.com/containerd/containerd/runtime/monitor.go b/components/engine/vendor/github.com/containerd/containerd/runtime/monitor.go index f5f8f1c75f..eb07ebdb4a 100644 --- a/components/engine/vendor/github.com/containerd/containerd/runtime/monitor.go +++ b/components/engine/vendor/github.com/containerd/containerd/runtime/monitor.go @@ -1,3 +1,19 @@ +/* + 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 runtime // TaskMonitor provides an interface for monitoring of containers within containerd diff --git a/components/engine/vendor/github.com/containerd/containerd/runtime/runtime.go b/components/engine/vendor/github.com/containerd/containerd/runtime/runtime.go index 39ffe86b9f..000af4ad34 100644 --- a/components/engine/vendor/github.com/containerd/containerd/runtime/runtime.go +++ b/components/engine/vendor/github.com/containerd/containerd/runtime/runtime.go @@ -1,3 +1,19 @@ +/* + 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 runtime import ( diff --git a/components/engine/vendor/github.com/containerd/containerd/runtime/task.go b/components/engine/vendor/github.com/containerd/containerd/runtime/task.go index 4c02455dcf..f8a67cfaee 100644 --- a/components/engine/vendor/github.com/containerd/containerd/runtime/task.go +++ b/components/engine/vendor/github.com/containerd/containerd/runtime/task.go @@ -1,3 +1,19 @@ +/* + 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 runtime import ( diff --git a/components/engine/vendor/github.com/containerd/containerd/runtime/task_list.go b/components/engine/vendor/github.com/containerd/containerd/runtime/task_list.go index 05f34c3230..92f25715c8 100644 --- a/components/engine/vendor/github.com/containerd/containerd/runtime/task_list.go +++ b/components/engine/vendor/github.com/containerd/containerd/runtime/task_list.go @@ -1,3 +1,19 @@ +/* + 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 runtime import ( @@ -92,7 +108,7 @@ func (l *TaskList) AddWithNamespace(namespace string, t Task) error { } // Delete a task -func (l *TaskList) Delete(ctx context.Context, t Task) { +func (l *TaskList) Delete(ctx context.Context, id string) { l.mu.Lock() defer l.mu.Unlock() namespace, err := namespaces.NamespaceRequired(ctx) @@ -101,6 +117,6 @@ func (l *TaskList) Delete(ctx context.Context, t Task) { } tasks, ok := l.tasks[namespace] if ok { - delete(tasks, t.ID()) + delete(tasks, id) } } diff --git a/components/engine/vendor/github.com/containerd/containerd/runtime/typeurl.go b/components/engine/vendor/github.com/containerd/containerd/runtime/typeurl.go index 8ba2b43a61..eb54e250f3 100644 --- a/components/engine/vendor/github.com/containerd/containerd/runtime/typeurl.go +++ b/components/engine/vendor/github.com/containerd/containerd/runtime/typeurl.go @@ -1,3 +1,19 @@ +/* + 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 runtime import ( diff --git a/components/engine/vendor/github.com/containerd/containerd/server/config.go b/components/engine/vendor/github.com/containerd/containerd/server/config.go index f056c7b837..67d1f4bcb5 100644 --- a/components/engine/vendor/github.com/containerd/containerd/server/config.go +++ b/components/engine/vendor/github.com/containerd/containerd/server/config.go @@ -1,9 +1,22 @@ +/* + 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 server import ( - "bytes" - "io" - "github.com/BurntSushi/toml" "github.com/containerd/containerd/errdefs" "github.com/pkg/errors" @@ -21,10 +34,11 @@ type Config struct { Debug Debug `toml:"debug"` // Metrics and monitoring settings Metrics MetricsConfig `toml:"metrics"` + // DisabledPlugins are IDs of plugins to disable. Disabled plugins won't be + // initialized and started. + DisabledPlugins []string `toml:"disabled_plugins"` // Plugins provides plugin specific configuration for the initialization of a plugin Plugins map[string]toml.Primitive `toml:"plugins"` - // NoSubreaper disables containerd as a subreaper - NoSubreaper bool `toml:"no_subreaper"` // OOMScore adjust the containerd's oom score OOMScore int `toml:"oom_score"` // Cgroup specifies cgroup information for the containerd daemon process @@ -50,7 +64,8 @@ type Debug struct { // MetricsConfig provides metrics configuration type MetricsConfig struct { - Address string `toml:"address"` + Address string `toml:"address"` + GRPCHistogram bool `toml:"grpc_histogram"` } // CgroupConfig provides cgroup configuration @@ -70,16 +85,6 @@ func (c *Config) Decode(id string, v interface{}) (interface{}, error) { return v, nil } -// WriteTo marshals the config to the provided writer -func (c *Config) WriteTo(w io.Writer) (int64, error) { - buf := bytes.NewBuffer(nil) - e := toml.NewEncoder(buf) - if err := e.Encode(c); err != nil { - return 0, err - } - return io.Copy(w, buf) -} - // LoadConfig loads the containerd server config from the provided path func LoadConfig(path string, v *Config) error { if v == nil { diff --git a/components/engine/vendor/github.com/containerd/containerd/server/server.go b/components/engine/vendor/github.com/containerd/containerd/server/server.go index 6af6df073a..f5b24f6364 100644 --- a/components/engine/vendor/github.com/containerd/containerd/server/server.go +++ b/components/engine/vendor/github.com/containerd/containerd/server/server.go @@ -1,7 +1,24 @@ +/* + 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 server import ( "expvar" + "io" "net" "net/http" "net/http/pprof" @@ -10,17 +27,6 @@ import ( "strings" "github.com/boltdb/bolt" - containers "github.com/containerd/containerd/api/services/containers/v1" - contentapi "github.com/containerd/containerd/api/services/content/v1" - diff "github.com/containerd/containerd/api/services/diff/v1" - eventsapi "github.com/containerd/containerd/api/services/events/v1" - images "github.com/containerd/containerd/api/services/images/v1" - introspection "github.com/containerd/containerd/api/services/introspection/v1" - leasesapi "github.com/containerd/containerd/api/services/leases/v1" - namespaces "github.com/containerd/containerd/api/services/namespaces/v1" - snapshotsapi "github.com/containerd/containerd/api/services/snapshots/v1" - tasks "github.com/containerd/containerd/api/services/tasks/v1" - version "github.com/containerd/containerd/api/services/version/v1" "github.com/containerd/containerd/content" "github.com/containerd/containerd/content/local" "github.com/containerd/containerd/events/exchange" @@ -34,7 +40,6 @@ import ( "golang.org/x/net/context" "google.golang.org/grpc" - "google.golang.org/grpc/health/grpc_health_v1" ) // New creates and initializes a new containerd server @@ -57,12 +62,12 @@ func New(ctx context.Context, config *Config) (*Server, error) { if err := apply(ctx, config); err != nil { return nil, err } - plugins, err := loadPlugins(config) + plugins, err := LoadPlugins(config) if err != nil { return nil, err } rpc := grpc.NewServer( - grpc.UnaryInterceptor(interceptor), + grpc.UnaryInterceptor(grpc_prometheus.UnaryServerInterceptor), grpc.StreamInterceptor(grpc_prometheus.StreamServerInterceptor), ) var ( @@ -70,6 +75,7 @@ func New(ctx context.Context, config *Config) (*Server, error) { s = &Server{ rpc: rpc, events: exchange.NewExchange(), + config: config, } initialized = plugin.NewPluginSet() ) @@ -113,6 +119,7 @@ func New(ctx context.Context, config *Config) (*Server, error) { if service, ok := instance.(plugin.Service); ok { services = append(services, service) } + s.plugins = append(s.plugins, result) } // register services after all plugins have been initialized for _, service := range services { @@ -125,12 +132,18 @@ func New(ctx context.Context, config *Config) (*Server, error) { // Server is the containerd main daemon type Server struct { - rpc *grpc.Server - events *exchange.Exchange + rpc *grpc.Server + events *exchange.Exchange + config *Config + plugins []*plugin.Plugin } // ServeGRPC provides the containerd grpc APIs on the provided listener func (s *Server) ServeGRPC(l net.Listener) error { + if s.config.Metrics.GRPCHistogram { + // enable grpc time histograms to measure rpc latencies + grpc_prometheus.EnableHandlingTimeHistogram() + } // before we start serving the grpc API regster the grpc_prometheus metrics // handler. This needs to be the last service registered so that it can collect // metrics for every other service @@ -162,9 +175,28 @@ func (s *Server) ServeDebug(l net.Listener) error { // Stop the containerd server canceling any open connections func (s *Server) Stop() { s.rpc.Stop() + for i := len(s.plugins) - 1; i >= 0; i-- { + p := s.plugins[i] + instance, err := p.Instance() + if err != nil { + log.L.WithError(err).WithField("id", p.Registration.ID). + Errorf("could not get plugin instance") + continue + } + closer, ok := instance.(io.Closer) + if !ok { + continue + } + if err := closer.Close(); err != nil { + log.L.WithError(err).WithField("id", p.Registration.ID). + Errorf("failed to close plugin") + } + } } -func loadPlugins(config *Config) ([]*plugin.Registration, error) { +// LoadPlugins loads all plugins into containerd and generates an ordered graph +// of all plugins. +func LoadPlugins(config *Config) ([]*plugin.Registration, error) { // load all plugins into containerd if err := plugin.Load(filepath.Join(config.Root, "plugins")); err != nil { return nil, err @@ -226,45 +258,7 @@ func loadPlugins(config *Config) ([]*plugin.Registration, error) { }) // return the ordered graph for plugins - return plugin.Graph(), nil -} - -func interceptor( - ctx context.Context, - req interface{}, - info *grpc.UnaryServerInfo, - handler grpc.UnaryHandler, -) (interface{}, error) { - ctx = log.WithModule(ctx, "containerd") - switch info.Server.(type) { - case tasks.TasksServer: - ctx = log.WithModule(ctx, "tasks") - case containers.ContainersServer: - ctx = log.WithModule(ctx, "containers") - case contentapi.ContentServer: - ctx = log.WithModule(ctx, "content") - case images.ImagesServer: - ctx = log.WithModule(ctx, "images") - case grpc_health_v1.HealthServer: - // No need to change the context - case version.VersionServer: - ctx = log.WithModule(ctx, "version") - case snapshotsapi.SnapshotsServer: - ctx = log.WithModule(ctx, "snapshot") - case diff.DiffServer: - ctx = log.WithModule(ctx, "diff") - case namespaces.NamespacesServer: - ctx = log.WithModule(ctx, "namespaces") - case eventsapi.EventsServer: - ctx = log.WithModule(ctx, "events") - case introspection.IntrospectionServer: - ctx = log.WithModule(ctx, "introspection") - case leasesapi.LeasesServer: - ctx = log.WithModule(ctx, "leases") - default: - log.G(ctx).Warnf("unknown GRPC server type: %#v\n", info.Server) - } - return grpc_prometheus.UnaryServerInterceptor(ctx, req, info, handler) + return plugin.Graph(config.DisabledPlugins), nil } func trapClosedConnErr(err error) error { diff --git a/components/engine/vendor/github.com/containerd/containerd/server/server_linux.go b/components/engine/vendor/github.com/containerd/containerd/server/server_linux.go index 98bfbd7259..c45ccd3d51 100644 --- a/components/engine/vendor/github.com/containerd/containerd/server/server_linux.go +++ b/components/engine/vendor/github.com/containerd/containerd/server/server_linux.go @@ -1,3 +1,19 @@ +/* + 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 server import ( @@ -12,12 +28,6 @@ import ( // apply sets config settings on the server process func apply(ctx context.Context, config *Config) error { - if !config.NoSubreaper { - log.G(ctx).Info("setting subreaper...") - if err := sys.SetSubreaper(1); err != nil { - return err - } - } if config.OOMScore != 0 { log.G(ctx).Debugf("changing OOM score to %d", config.OOMScore) if err := sys.SetOOMScore(os.Getpid(), config.OOMScore); err != nil { diff --git a/components/engine/vendor/github.com/containerd/containerd/server/server_solaris.go b/components/engine/vendor/github.com/containerd/containerd/server/server_solaris.go index 3c39816be2..0dbbb9feac 100644 --- a/components/engine/vendor/github.com/containerd/containerd/server/server_solaris.go +++ b/components/engine/vendor/github.com/containerd/containerd/server/server_solaris.go @@ -1,3 +1,19 @@ +/* + 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 server import "context" diff --git a/components/engine/vendor/github.com/containerd/containerd/server/server_unsupported.go b/components/engine/vendor/github.com/containerd/containerd/server/server_unsupported.go index 4df599e114..c6211dbb2a 100644 --- a/components/engine/vendor/github.com/containerd/containerd/server/server_unsupported.go +++ b/components/engine/vendor/github.com/containerd/containerd/server/server_unsupported.go @@ -1,5 +1,21 @@ // +build !linux,!windows,!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 server import "context" diff --git a/components/engine/vendor/github.com/containerd/containerd/server/server_windows.go b/components/engine/vendor/github.com/containerd/containerd/server/server_windows.go index 37b71dfa1a..ac0b8481c2 100644 --- a/components/engine/vendor/github.com/containerd/containerd/server/server_windows.go +++ b/components/engine/vendor/github.com/containerd/containerd/server/server_windows.go @@ -1,5 +1,21 @@ // +build windows +/* + 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 server import ( diff --git a/components/engine/vendor/github.com/containerd/containerd/snapshot.go b/components/engine/vendor/github.com/containerd/containerd/snapshot.go index 85bdba1b68..155ec718f0 100644 --- a/components/engine/vendor/github.com/containerd/containerd/snapshot.go +++ b/components/engine/vendor/github.com/containerd/containerd/snapshot.go @@ -1,3 +1,19 @@ +/* + 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 ( diff --git a/components/engine/vendor/github.com/containerd/containerd/snapshots/snapshotter.go b/components/engine/vendor/github.com/containerd/containerd/snapshots/snapshotter.go index cde4c72618..d11252d1e3 100644 --- a/components/engine/vendor/github.com/containerd/containerd/snapshots/snapshotter.go +++ b/components/engine/vendor/github.com/containerd/containerd/snapshots/snapshotter.go @@ -1,3 +1,19 @@ +/* + 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 snapshots import ( diff --git a/components/engine/vendor/github.com/containerd/containerd/snapshotter_default_linux.go b/components/engine/vendor/github.com/containerd/containerd/snapshotter_default_linux.go index c432a2d552..d925d4ef94 100644 --- a/components/engine/vendor/github.com/containerd/containerd/snapshotter_default_linux.go +++ b/components/engine/vendor/github.com/containerd/containerd/snapshotter_default_linux.go @@ -1,3 +1,19 @@ +/* + 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 const ( diff --git a/components/engine/vendor/github.com/containerd/containerd/snapshotter_default_unix.go b/components/engine/vendor/github.com/containerd/containerd/snapshotter_default_unix.go index cb8b08ac19..abd8f86947 100644 --- a/components/engine/vendor/github.com/containerd/containerd/snapshotter_default_unix.go +++ b/components/engine/vendor/github.com/containerd/containerd/snapshotter_default_unix.go @@ -1,5 +1,21 @@ // +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 const ( diff --git a/components/engine/vendor/github.com/containerd/containerd/snapshotter_default_windows.go b/components/engine/vendor/github.com/containerd/containerd/snapshotter_default_windows.go index 3b73582187..320211a4a5 100644 --- a/components/engine/vendor/github.com/containerd/containerd/snapshotter_default_windows.go +++ b/components/engine/vendor/github.com/containerd/containerd/snapshotter_default_windows.go @@ -1,3 +1,19 @@ +/* + 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 const ( diff --git a/components/engine/vendor/github.com/containerd/containerd/sys/epoll.go b/components/engine/vendor/github.com/containerd/containerd/sys/epoll.go index 3a4d97cfa8..683f38eea8 100644 --- a/components/engine/vendor/github.com/containerd/containerd/sys/epoll.go +++ b/components/engine/vendor/github.com/containerd/containerd/sys/epoll.go @@ -1,5 +1,21 @@ // +build linux +/* + 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 sys import "golang.org/x/sys/unix" diff --git a/components/engine/vendor/github.com/containerd/containerd/sys/fds.go b/components/engine/vendor/github.com/containerd/containerd/sys/fds.go index 3c1ec67e5a..db3cf702f4 100644 --- a/components/engine/vendor/github.com/containerd/containerd/sys/fds.go +++ b/components/engine/vendor/github.com/containerd/containerd/sys/fds.go @@ -1,5 +1,21 @@ // +build !windows,!darwin +/* + 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 sys import ( diff --git a/components/engine/vendor/github.com/containerd/containerd/sys/filesys_unix.go b/components/engine/vendor/github.com/containerd/containerd/sys/filesys_unix.go new file mode 100644 index 0000000000..700f44efa9 --- /dev/null +++ b/components/engine/vendor/github.com/containerd/containerd/sys/filesys_unix.go @@ -0,0 +1,26 @@ +// +build !windows + +/* + 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 sys + +import "os" + +// ForceRemoveAll on unix is just a wrapper for os.RemoveAll +func ForceRemoveAll(path string) error { + return os.RemoveAll(path) +} diff --git a/components/engine/vendor/github.com/containerd/containerd/sys/filesys_windows.go b/components/engine/vendor/github.com/containerd/containerd/sys/filesys_windows.go index b5ce13579d..dc880c3427 100644 --- a/components/engine/vendor/github.com/containerd/containerd/sys/filesys_windows.go +++ b/components/engine/vendor/github.com/containerd/containerd/sys/filesys_windows.go @@ -1,5 +1,21 @@ // +build windows +/* + 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 sys import ( @@ -11,6 +27,7 @@ import ( "unsafe" winio "github.com/Microsoft/go-winio" + "github.com/Microsoft/hcsshim" ) // MkdirAllWithACL is a wrapper for MkdirAll that creates a directory @@ -234,3 +251,13 @@ func syscallOpenSequential(path string, mode int, _ uint32) (fd syscall.Handle, h, e := syscall.CreateFile(pathp, access, sharemode, sa, createmode, fileFlagSequentialScan, 0) return h, e } + +// ForceRemoveAll is the same as os.RemoveAll, but uses hcsshim.DestroyLayer in order +// to delete container layers. +func ForceRemoveAll(path string) error { + info := hcsshim.DriverInfo{ + HomeDir: filepath.Dir(path), + } + + return hcsshim.DestroyLayer(info, filepath.Base(path)) +} diff --git a/components/engine/vendor/github.com/containerd/containerd/sys/oom_unix.go b/components/engine/vendor/github.com/containerd/containerd/sys/oom_unix.go index 23fcc94371..1abe7485b6 100644 --- a/components/engine/vendor/github.com/containerd/containerd/sys/oom_unix.go +++ b/components/engine/vendor/github.com/containerd/containerd/sys/oom_unix.go @@ -1,5 +1,21 @@ // +build !windows +/* + 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 sys import ( diff --git a/components/engine/vendor/github.com/containerd/containerd/sys/oom_windows.go b/components/engine/vendor/github.com/containerd/containerd/sys/oom_windows.go index 6e42ddce8e..f44bcebd1e 100644 --- a/components/engine/vendor/github.com/containerd/containerd/sys/oom_windows.go +++ b/components/engine/vendor/github.com/containerd/containerd/sys/oom_windows.go @@ -1,3 +1,19 @@ +/* + 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 sys // SetOOMScore sets the oom score for the process diff --git a/components/engine/vendor/github.com/containerd/containerd/sys/prctl.go b/components/engine/vendor/github.com/containerd/containerd/sys/prctl.go deleted file mode 100644 index aa1a4ad38a..0000000000 --- a/components/engine/vendor/github.com/containerd/containerd/sys/prctl.go +++ /dev/null @@ -1,41 +0,0 @@ -// +build linux - -// Package sys provides access to the Get Child and Set Child prctl flags. -// See http://man7.org/linux/man-pages/man2/prctl.2.html -package sys - -import ( - "unsafe" - - "golang.org/x/sys/unix" -) - -// GetSubreaper returns the subreaper setting for the calling process -func GetSubreaper() (int, error) { - var i uintptr - // PR_GET_CHILD_SUBREAPER allows retrieving the current child - // subreaper. - // Returns the "child subreaper" setting of the caller, in the - // location pointed to by (int *) arg2. - if err := unix.Prctl(unix.PR_GET_CHILD_SUBREAPER, uintptr(unsafe.Pointer(&i)), 0, 0, 0); err != nil { - return -1, err - } - return int(i), nil -} - -// SetSubreaper sets the value i as the subreaper setting for the calling process -func SetSubreaper(i int) error { - // PR_SET_CHILD_SUBREAPER allows setting the child subreaper. - // If arg2 is nonzero, set the "child subreaper" attribute of the - // calling process; if arg2 is zero, unset the attribute. When a - // process is marked as a child subreaper, all of the children - // that it creates, and their descendants, will be marked as - // having a subreaper. In effect, a subreaper fulfills the role - // of init(1) for its descendant processes. Upon termination of - // a process that is orphaned (i.e., its immediate parent has - // already terminated) and marked as having a subreaper, the - // nearest still living ancestor subreaper will receive a SIGCHLD - // signal and be able to wait(2) on the process to discover its - // termination status. - return unix.Prctl(unix.PR_SET_CHILD_SUBREAPER, uintptr(i), 0, 0, 0) -} diff --git a/components/engine/vendor/github.com/containerd/containerd/sys/proc.go b/components/engine/vendor/github.com/containerd/containerd/sys/proc.go index fbe7b51905..496eb1fea1 100644 --- a/components/engine/vendor/github.com/containerd/containerd/sys/proc.go +++ b/components/engine/vendor/github.com/containerd/containerd/sys/proc.go @@ -1,5 +1,21 @@ // +build linux +/* + 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 sys import ( diff --git a/components/engine/vendor/github.com/containerd/containerd/sys/reaper.go b/components/engine/vendor/github.com/containerd/containerd/sys/reaper.go index bbc5a1e868..23cb040b80 100644 --- a/components/engine/vendor/github.com/containerd/containerd/sys/reaper.go +++ b/components/engine/vendor/github.com/containerd/containerd/sys/reaper.go @@ -1,5 +1,21 @@ // +build !windows +/* + 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 sys import "golang.org/x/sys/unix" diff --git a/components/engine/vendor/github.com/containerd/containerd/sys/socket_unix.go b/components/engine/vendor/github.com/containerd/containerd/sys/socket_unix.go index 0d5f049aa8..4d71c709ad 100644 --- a/components/engine/vendor/github.com/containerd/containerd/sys/socket_unix.go +++ b/components/engine/vendor/github.com/containerd/containerd/sys/socket_unix.go @@ -1,5 +1,21 @@ // +build !windows +/* + 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 sys import ( diff --git a/components/engine/vendor/github.com/containerd/containerd/sys/socket_windows.go b/components/engine/vendor/github.com/containerd/containerd/sys/socket_windows.go index de25c08601..3ee7679b49 100644 --- a/components/engine/vendor/github.com/containerd/containerd/sys/socket_windows.go +++ b/components/engine/vendor/github.com/containerd/containerd/sys/socket_windows.go @@ -1,5 +1,21 @@ // +build windows +/* + 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 sys import ( diff --git a/components/engine/vendor/github.com/containerd/containerd/sys/stat_bsd.go b/components/engine/vendor/github.com/containerd/containerd/sys/stat_bsd.go index e043ae52bf..b9c95d90d7 100644 --- a/components/engine/vendor/github.com/containerd/containerd/sys/stat_bsd.go +++ b/components/engine/vendor/github.com/containerd/containerd/sys/stat_bsd.go @@ -1,9 +1,26 @@ // +build darwin freebsd +/* + 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 sys import ( "syscall" + "time" ) // StatAtime returns the access time from a stat struct @@ -20,3 +37,8 @@ func StatCtime(st *syscall.Stat_t) syscall.Timespec { func StatMtime(st *syscall.Stat_t) syscall.Timespec { return st.Mtimespec } + +// StatATimeAsTime returns the access time as a time.Time +func StatATimeAsTime(st *syscall.Stat_t) time.Time { + return time.Unix(int64(st.Atimespec.Sec), int64(st.Atimespec.Nsec)) // nolint: unconvert +} diff --git a/components/engine/vendor/github.com/containerd/containerd/sys/stat_unix.go b/components/engine/vendor/github.com/containerd/containerd/sys/stat_unix.go index 1f983a98db..21a666dff8 100644 --- a/components/engine/vendor/github.com/containerd/containerd/sys/stat_unix.go +++ b/components/engine/vendor/github.com/containerd/containerd/sys/stat_unix.go @@ -1,9 +1,26 @@ // +build linux 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 sys import ( "syscall" + "time" ) // StatAtime returns the Atim @@ -20,3 +37,8 @@ func StatCtime(st *syscall.Stat_t) syscall.Timespec { func StatMtime(st *syscall.Stat_t) syscall.Timespec { return st.Mtim } + +// StatATimeAsTime returns st.Atim as a time.Time +func StatATimeAsTime(st *syscall.Stat_t) time.Time { + return time.Unix(int64(st.Atim.Sec), int64(st.Atim.Nsec)) // nolint: unconvert +} diff --git a/components/engine/vendor/github.com/containerd/containerd/task.go b/components/engine/vendor/github.com/containerd/containerd/task.go index 121da9af5b..f801d493d6 100644 --- a/components/engine/vendor/github.com/containerd/containerd/task.go +++ b/components/engine/vendor/github.com/containerd/containerd/task.go @@ -1,3 +1,19 @@ +/* + 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 ( @@ -267,7 +283,6 @@ func (t *task) Delete(ctx context.Context, opts ...ProcessDeleteOpts) (*ExitStat if t.io != nil { t.io.Cancel() t.io.Wait() - t.io.Close() } r, err := t.client.TaskService().Delete(ctx, &tasks.DeleteTaskRequest{ ContainerID: t.id, @@ -275,6 +290,10 @@ func (t *task) Delete(ctx context.Context, opts ...ProcessDeleteOpts) (*ExitStat if err != nil { return nil, errdefs.FromGRPC(err) } + // Only cleanup the IO after a successful Delete + if t.io != nil { + t.io.Close() + } return &ExitStatus{code: r.ExitStatus, exitedAt: r.ExitedAt}, nil } @@ -536,7 +555,7 @@ func (t *task) checkpointRWSnapshot(ctx context.Context, index *v1.Index, snapsh opts := []diff.Opt{ diff.WithReference(fmt.Sprintf("checkpoint-rw-%s", id)), } - rw, err := rootfs.Diff(ctx, id, t.client.SnapshotService(snapshotterName), t.client.DiffService(), opts...) + rw, err := rootfs.CreateDiff(ctx, id, t.client.SnapshotService(snapshotterName), t.client.DiffService(), opts...) if err != nil { return err } @@ -572,7 +591,7 @@ func (t *task) writeIndex(ctx context.Context, index *v1.Index) (d v1.Descriptor return writeContent(ctx, t.client.ContentStore(), v1.MediaTypeImageIndex, t.id, buf, content.WithLabels(labels)) } -func writeContent(ctx context.Context, store content.Store, mediaType, ref string, r io.Reader, opts ...content.Opt) (d v1.Descriptor, err error) { +func writeContent(ctx context.Context, store content.Ingester, mediaType, ref string, r io.Reader, opts ...content.Opt) (d v1.Descriptor, err error) { writer, err := store.Writer(ctx, ref, 0, "") if err != nil { return d, err diff --git a/components/engine/vendor/github.com/containerd/containerd/task_opts.go b/components/engine/vendor/github.com/containerd/containerd/task_opts.go index a387adb6ed..495d4225b9 100644 --- a/components/engine/vendor/github.com/containerd/containerd/task_opts.go +++ b/components/engine/vendor/github.com/containerd/containerd/task_opts.go @@ -1,3 +1,19 @@ +/* + 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 ( diff --git a/components/engine/vendor/github.com/containerd/containerd/task_opts_linux.go b/components/engine/vendor/github.com/containerd/containerd/task_opts_linux.go index 5b91cb5485..63136fd6ae 100644 --- a/components/engine/vendor/github.com/containerd/containerd/task_opts_linux.go +++ b/components/engine/vendor/github.com/containerd/containerd/task_opts_linux.go @@ -1,3 +1,19 @@ +/* + 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 ( diff --git a/components/engine/vendor/github.com/containerd/containerd/task_opts_windows.go b/components/engine/vendor/github.com/containerd/containerd/task_opts_windows.go index d77402c675..60836bc8fa 100644 --- a/components/engine/vendor/github.com/containerd/containerd/task_opts_windows.go +++ b/components/engine/vendor/github.com/containerd/containerd/task_opts_windows.go @@ -1,3 +1,19 @@ +/* + 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 ( diff --git a/components/engine/vendor/github.com/containerd/containerd/vendor.conf b/components/engine/vendor/github.com/containerd/containerd/vendor.conf index 030c77349b..0639c6399c 100644 --- a/components/engine/vendor/github.com/containerd/containerd/vendor.conf +++ b/components/engine/vendor/github.com/containerd/containerd/vendor.conf @@ -1,26 +1,24 @@ github.com/coreos/go-systemd 48702e0da86bd25e76cfef347e2adeb434a0d0a6 -github.com/containerd/go-runc ed1cbe1fc31f5fb2359d3a54b6330d1a097858b7 +github.com/containerd/go-runc 4f6e87ae043f859a38255247b49c9abc262d002f github.com/containerd/console 84eeaae905fa414d03e07bcd6c8d3f19e7cf180e -github.com/containerd/cgroups 29da22c6171a4316169f9205ab6c49f59b5b852f +github.com/containerd/cgroups c0710c92e8b3a44681d1321dcfd1360fc5c6c089 github.com/containerd/typeurl f6943554a7e7e88b3c14aad190bf05932da84788 -github.com/docker/go-metrics 8fd5772bf1584597834c6f7961a530f06cbfbb87 +github.com/docker/go-metrics 4ea375f7759c82740c893fc030bc37088d2ec098 github.com/docker/go-events 9461782956ad83b30282bf90e31fa6a70c255ba9 github.com/godbus/dbus c7fdd8b5cd55e87b4e1f4e372cdb1db61dd6c66f -github.com/prometheus/client_golang v0.8.0 -github.com/prometheus/client_model fa8ad6fec33561be4280a8f0514318c79d7f6cb6 -github.com/prometheus/common 195bde7883f7c39ea62b0d92ab7359b5327065cb -github.com/prometheus/procfs fcdb11ccb4389efb1b210b7ffb623ab71c5fdd60 +github.com/prometheus/client_golang f4fb1b73fb099f396a7f0036bf86aa8def4ed823 +github.com/prometheus/client_model 99fa1f4be8e564e8a6b613da7fa6f46c9edafc6c +github.com/prometheus/common 89604d197083d4781071d3c65855d24ecfb0a563 +github.com/prometheus/procfs cb4147076ac75738c9a7d279075a253c0cc5acbd github.com/beorn7/perks 4c0e84591b9aa9e6dcfdf3e020114cd81f89d5f9 github.com/matttproud/golang_protobuf_extensions v1.0.0 github.com/docker/go-units v0.3.1 github.com/gogo/protobuf v0.5 github.com/golang/protobuf 1643683e1b54a9e88ad26d98f81400c8c9d9f4f9 github.com/opencontainers/runtime-spec v1.0.1 -github.com/opencontainers/runc 7f24b40cc5423969b4554ef04ba0b00e2b4ba010 +github.com/opencontainers/runc a618ab5a0186905949ee463dbb762c3d23e12a80 github.com/sirupsen/logrus v1.0.0 github.com/containerd/btrfs cc52c4dea2ce11a44e6639e561bb5c2af9ada9e3 -github.com/stretchr/testify v1.1.4 -github.com/davecgh/go-spew v1.1.0 github.com/pmezard/go-difflib v1.0.0 github.com/containerd/fifo fbfb6a11ec671efbe94ad1c12c2e98773f19e1e6 github.com/urfave/cli 7bc6a0acffa589f415f88aca16cc1de5ffd66f9c @@ -30,14 +28,49 @@ github.com/pkg/errors v0.8.0 github.com/opencontainers/go-digest 21dfd564fd89c944783d00d069f33e3e7123c448 golang.org/x/sys 314a259e304ff91bd6985da2a7149bbf91237993 https://github.com/golang/sys github.com/opencontainers/image-spec v1.0.1 -github.com/containerd/continuity cf279e6ac893682272b4479d4c67fd3abf878b4e +github.com/containerd/continuity d8fb8589b0e8e85b8c8bbaa8840226d0dfeb7371 golang.org/x/sync 450f422ab23cf9881c94e2db30cac0eb1b7cf80c -github.com/BurntSushi/toml v0.2.0-21-g9906417 +github.com/BurntSushi/toml a368813c5e648fee92e5f6c30e3944ff9d5e8895 github.com/grpc-ecosystem/go-grpc-prometheus 6b7015e65d366bf3f19b2b2a000a831940f0f7e0 -github.com/Microsoft/go-winio v0.4.4 +github.com/Microsoft/go-winio v0.4.5 github.com/Microsoft/hcsshim v0.6.7 github.com/boltdb/bolt e9cf4fae01b5a8ff89d0ec6b32f0d9c9f79aefdd google.golang.org/genproto d80a6e20e776b0b17a324d0ba1ab50a39c8e8944 golang.org/x/text 19e51611da83d6be54ddafce4a4af510cb3e9ea4 github.com/dmcgowan/go-tar go1.10 -github.com/stevvooe/ttrpc 76e68349ad9ab4d03d764c713826d31216715e4f +github.com/stevvooe/ttrpc d4528379866b0ce7e9d71f3eb96f0582fc374577 +github.com/syndtr/gocapability db04d3cc01c8b54962a58ec7e491717d06cfcc16 +github.com/gotestyourself/gotestyourself 44dbf532bbf5767611f6f2a61bded572e337010a +github.com/google/go-cmp v0.1.0 +# cri dependencies +github.com/containerd/cri-containerd c9081b2ec0eefc799f0f1caabbea29d516c72c44 +github.com/blang/semver v3.1.0 +github.com/containernetworking/cni v0.6.0 +github.com/containernetworking/plugins v0.6.0 +github.com/cri-o/ocicni 9b451e26eb7c694d564991fbf44f77d0afb9b03c +github.com/davecgh/go-spew v1.1.0 +github.com/docker/distribution b38e5838b7b2f2ad48e06ec4b500011976080621 +github.com/docker/docker 86f080cff0914e9694068ed78d503701667c4c00 +github.com/docker/spdystream 449fdfce4d962303d702fec724ef0ad181c92528 +github.com/emicklei/go-restful ff4f55a206334ef123e4f79bbf348980da81ca46 +github.com/fsnotify/fsnotify 7d7316ed6e1ed2de075aab8dfc76de5d158d66e1 +github.com/ghodss/yaml 73d445a93680fa1a78ae23a5839bad48f32ba1ee +github.com/golang/glog 44145f04b68cf362d9c4df2182967c2275eaefed +github.com/google/gofuzz 44d81051d367757e1c7c6a5a86423ece9afcf63c +github.com/hashicorp/errwrap 7554cd9344cec97297fa6649b055a8c98c2a1e55 +github.com/hashicorp/go-multierror ed905158d87462226a13fe39ddf685ea65f1c11f +github.com/json-iterator/go 1.0.4 +github.com/opencontainers/runtime-tools 6073aff4ac61897f75895123f7e24135204a404d +github.com/opencontainers/selinux 4a2974bf1ee960774ffd517717f1f45325af0206 +github.com/seccomp/libseccomp-golang 32f571b70023028bd57d9288c20efbcb237f3ce0 +github.com/spf13/pflag v1.0.0 +github.com/tchap/go-patricia 5ad6cdb7538b0097d5598c7e57f0a24072adf7dc +golang.org/x/time f51c12702a4d776e4c1fa9b0fabab841babae631 +gopkg.in/inf.v0 3887ee99ecf07df5b447e9b00d9c0b2adaa9f3e4 +gopkg.in/yaml.v2 53feefa2559fb8dfa8d81baad31be332c97d6c77 +k8s.io/api a1d6dce6736a6c75929bb75111e89077e35a5856 +k8s.io/apimachinery 8259d997cf059cd83dc47e5f8074b7a7d7967c09 +k8s.io/apiserver 8e45eac9dff86447a5c2effe6a3d2cba70121ebf +k8s.io/client-go 33bd23f75b6de861994706a322b0afab824b2171 +k8s.io/kubernetes 05944b1d2ca7f60b09762a330425108f48f6b603 +k8s.io/utils 258e2a2fa64568210fbd6267cf1d8fd87c3cb86e diff --git a/components/engine/vendor/github.com/containerd/containerd/windows/hcsshimtypes/doc.go b/components/engine/vendor/github.com/containerd/containerd/windows/hcsshimtypes/doc.go index 4b1b4b3414..9fe5cd0a4d 100644 --- a/components/engine/vendor/github.com/containerd/containerd/windows/hcsshimtypes/doc.go +++ b/components/engine/vendor/github.com/containerd/containerd/windows/hcsshimtypes/doc.go @@ -1,2 +1,18 @@ +/* + 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 hcsshimtypes holds the windows runtime specific types package hcsshimtypes