vendor: containerd/containerd ed261720c8
full diff: 0131015594...ed261720c8
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
parent
c784772ba4
commit
ee3548dee8
@ -10,7 +10,7 @@ github.com/BurntSushi/toml 3012a1dbe2e4bd1391d42b32f057
|
||||
github.com/cespare/xxhash/v2 d7df74196a9e781ede915320c11c378c1b2f3a1f # v2.1.1
|
||||
github.com/containerd/cgroups b4448137398923af7f4918b8b2ad8249172ca7a6
|
||||
github.com/containerd/console 8375c3424e4d7b114e8a90a4a40c8e1b40d1d4e6 # v1.0.0
|
||||
github.com/containerd/containerd 01310155947cb6eec37dcae29742a165e56acb4a
|
||||
github.com/containerd/containerd ed261720c86d1e700cd5d39175128322baac6dda
|
||||
github.com/containerd/continuity 0ec596719c75bfd42908850990acea594b7593ac
|
||||
github.com/containerd/fifo bda0ff6ed73c67bfb5e62bc9c697f146b7fd7f13
|
||||
github.com/containerd/go-runc a5c2862aed5e6358b305b0e16bfce58e0549b1cd
|
||||
@ -27,6 +27,8 @@ github.com/gogo/protobuf 5628607bb4c51c3157aacc3a50f0
|
||||
github.com/golang/protobuf d23c5127dc24889085f8ccea5c9d560a57a879d8 # v1.3.3
|
||||
github.com/google/uuid 0cd6bf5da1e1c83f8b45653022c74f71af0538a4 # v1.1.1
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus c225b8c3b01faf2899099b768856a9e916e5087b # v1.2.0
|
||||
github.com/hashicorp/errwrap 8a6fb523712970c966eefc6b39ed2c5e74880354 # v1.0.0
|
||||
github.com/hashicorp/go-multierror 886a7fbe3eb1c874d46f623bfa70af45f425b3d1 # v1.0.0
|
||||
github.com/hashicorp/golang-lru 7f827b33c0f158ec5dfbba01bb0b14a4541fd81d # v0.5.3
|
||||
github.com/imdario/mergo 7c29201646fa3de8506f701213473dd407f19646 # v0.3.7
|
||||
github.com/konsorten/go-windows-terminal-sequences edb144dfd453055e1e49a3d8b410a660b5a87613 # v1.0.3
|
||||
|
4
vendor/github.com/containerd/containerd/README.md
generated
vendored
4
vendor/github.com/containerd/containerd/README.md
generated
vendored
@ -1,9 +1,9 @@
|
||||

|
||||
|
||||
[](https://godoc.org/github.com/containerd/containerd)
|
||||
[](https://travis-ci.org/containerd/containerd)
|
||||
[](https://github.com/containerd/containerd/actions?query=workflow%3ACI)
|
||||
[](https://ci.appveyor.com/project/mlaventure/containerd-3g73f?branch=master)
|
||||

|
||||
[](https://github.com/containerd/containerd/actions?query=workflow%3ANightly)
|
||||
[](https://app.fossa.io/projects/git%2Bhttps%3A%2F%2Fgithub.com%2Fcontainerd%2Fcontainerd?ref=badge_shield)
|
||||
[](https://goreportcard.com/report/github.com/containerd/containerd)
|
||||
[](https://bestpractices.coreinfrastructure.org/projects/1271)
|
||||
|
17
vendor/github.com/containerd/containerd/archive/tar_unix.go
generated
vendored
17
vendor/github.com/containerd/containerd/archive/tar_unix.go
generated
vendored
@ -22,12 +22,11 @@ import (
|
||||
"archive/tar"
|
||||
"os"
|
||||
"strings"
|
||||
"sync"
|
||||
"syscall"
|
||||
|
||||
"github.com/containerd/containerd/sys"
|
||||
"github.com/containerd/continuity/fs"
|
||||
"github.com/containerd/continuity/sysx"
|
||||
"github.com/opencontainers/runc/libcontainer/system"
|
||||
"github.com/pkg/errors"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
@ -84,21 +83,11 @@ func mkdir(path string, perm os.FileMode) error {
|
||||
return os.Chmod(path, perm)
|
||||
}
|
||||
|
||||
var (
|
||||
inUserNS bool
|
||||
nsOnce sync.Once
|
||||
)
|
||||
|
||||
func setInUserNS() {
|
||||
inUserNS = system.RunningInUserNS()
|
||||
}
|
||||
|
||||
func skipFile(hdr *tar.Header) bool {
|
||||
switch hdr.Typeflag {
|
||||
case tar.TypeBlock, tar.TypeChar:
|
||||
// cannot create a device if running in user namespace
|
||||
nsOnce.Do(setInUserNS)
|
||||
return inUserNS
|
||||
return sys.RunningInUserNS()
|
||||
default:
|
||||
return false
|
||||
}
|
||||
@ -125,7 +114,7 @@ func handleTarTypeBlockCharFifo(hdr *tar.Header, path string) error {
|
||||
func handleLChmod(hdr *tar.Header, path string, hdrInfo os.FileInfo) error {
|
||||
if hdr.Typeflag == tar.TypeLink {
|
||||
if fi, err := os.Lstat(hdr.Linkname); err == nil && (fi.Mode()&os.ModeSymlink == 0) {
|
||||
if err := os.Chmod(path, hdrInfo.Mode()); err != nil {
|
||||
if err := os.Chmod(path, hdrInfo.Mode()); err != nil && !os.IsNotExist(err) {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
6
vendor/github.com/containerd/containerd/client.go
generated
vendored
6
vendor/github.com/containerd/containerd/client.go
generated
vendored
@ -58,7 +58,6 @@ import (
|
||||
"github.com/containerd/containerd/snapshots"
|
||||
snproxy "github.com/containerd/containerd/snapshots/proxy"
|
||||
"github.com/containerd/typeurl"
|
||||
"github.com/gogo/protobuf/types"
|
||||
ptypes "github.com/gogo/protobuf/types"
|
||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
specs "github.com/opencontainers/runtime-spec/specs-go"
|
||||
@ -319,6 +318,9 @@ type RemoteContext struct {
|
||||
// Snapshotter used for unpacking
|
||||
Snapshotter string
|
||||
|
||||
// SnapshotterOpts are additional options to be passed to a snapshotter during pull
|
||||
SnapshotterOpts []snapshots.Opt
|
||||
|
||||
// Labels to be applied to the created image
|
||||
Labels map[string]string
|
||||
|
||||
@ -720,7 +722,7 @@ func (c *Client) Server(ctx context.Context) (ServerInfo, error) {
|
||||
}
|
||||
c.connMu.Unlock()
|
||||
|
||||
response, err := c.IntrospectionService().Server(ctx, &types.Empty{})
|
||||
response, err := c.IntrospectionService().Server(ctx, &ptypes.Empty{})
|
||||
if err != nil {
|
||||
return ServerInfo{}, err
|
||||
}
|
||||
|
7
vendor/github.com/containerd/containerd/client_opts.go
generated
vendored
7
vendor/github.com/containerd/containerd/client_opts.go
generated
vendored
@ -22,6 +22,8 @@ import (
|
||||
"github.com/containerd/containerd/images"
|
||||
"github.com/containerd/containerd/platforms"
|
||||
"github.com/containerd/containerd/remotes"
|
||||
"github.com/containerd/containerd/snapshots"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
)
|
||||
|
||||
@ -138,10 +140,11 @@ func WithUnpackOpts(opts []UnpackOpt) RemoteOpt {
|
||||
}
|
||||
}
|
||||
|
||||
// WithPullSnapshotter specifies snapshotter name used for unpacking
|
||||
func WithPullSnapshotter(snapshotterName string) RemoteOpt {
|
||||
// WithPullSnapshotter specifies snapshotter name used for unpacking.
|
||||
func WithPullSnapshotter(snapshotterName string, opts ...snapshots.Opt) RemoteOpt {
|
||||
return func(_ *Client, c *RemoteContext) error {
|
||||
c.Snapshotter = snapshotterName
|
||||
c.SnapshotterOpts = opts
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
4
vendor/github.com/containerd/containerd/cmd/containerd/command/main.go
generated
vendored
4
vendor/github.com/containerd/containerd/cmd/containerd/command/main.go
generated
vendored
@ -227,6 +227,10 @@ can be used and modified as necessary as a custom configuration.`
|
||||
}
|
||||
serve(ctx, l, server.ServeGRPC)
|
||||
|
||||
if err := notifyReady(ctx); err != nil {
|
||||
log.G(ctx).WithError(err).Warn("notify ready failed")
|
||||
}
|
||||
|
||||
log.G(ctx).Infof("containerd successfully booted in %fs", time.Since(start).Seconds())
|
||||
<-done
|
||||
return nil
|
||||
|
4
vendor/github.com/containerd/containerd/cmd/containerd/command/main_unix.go
generated
vendored
4
vendor/github.com/containerd/containerd/cmd/containerd/command/main_unix.go
generated
vendored
@ -52,6 +52,10 @@ func handleSignals(ctx context.Context, signals chan os.Signal, serverC chan *se
|
||||
case unix.SIGPIPE:
|
||||
continue
|
||||
default:
|
||||
if err := notifyStopping(ctx); err != nil {
|
||||
log.G(ctx).WithError(err).Error("notify stopping failed")
|
||||
}
|
||||
|
||||
if server == nil {
|
||||
close(done)
|
||||
return
|
||||
|
5
vendor/github.com/containerd/containerd/cmd/containerd/command/main_windows.go
generated
vendored
5
vendor/github.com/containerd/containerd/cmd/containerd/command/main_windows.go
generated
vendored
@ -50,6 +50,11 @@ func handleSignals(ctx context.Context, signals chan os.Signal, serverC chan *se
|
||||
server = s
|
||||
case s := <-signals:
|
||||
log.G(ctx).WithField("signal", s).Debug("received signal")
|
||||
|
||||
if err := notifyStopping(ctx); err != nil {
|
||||
log.G(ctx).WithError(err).Error("notify stopping failed")
|
||||
}
|
||||
|
||||
if server == nil {
|
||||
close(done)
|
||||
return
|
||||
|
47
vendor/github.com/containerd/containerd/cmd/containerd/command/notify_linux.go
generated
vendored
Normal file
47
vendor/github.com/containerd/containerd/cmd/containerd/command/notify_linux.go
generated
vendored
Normal file
@ -0,0 +1,47 @@
|
||||
// +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 command
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
sd "github.com/coreos/go-systemd/v22/daemon"
|
||||
|
||||
"github.com/containerd/containerd/log"
|
||||
)
|
||||
|
||||
// notifyReady notifies systemd that the daemon is ready to serve requests
|
||||
func notifyReady(ctx context.Context) error {
|
||||
return sdNotify(ctx, sd.SdNotifyReady)
|
||||
}
|
||||
|
||||
// notifyStopping notifies systemd that the daemon is about to be stopped
|
||||
func notifyStopping(ctx context.Context) error {
|
||||
return sdNotify(ctx, sd.SdNotifyStopping)
|
||||
}
|
||||
|
||||
func sdNotify(ctx context.Context, state string) error {
|
||||
notified, err := sd.SdNotify(false, state)
|
||||
log.G(ctx).
|
||||
WithError(err).
|
||||
WithField("notified", notified).
|
||||
WithField("state", state).
|
||||
Debug("sd notification")
|
||||
return err
|
||||
}
|
31
vendor/github.com/containerd/containerd/cmd/containerd/command/notify_unsupported.go
generated
vendored
Normal file
31
vendor/github.com/containerd/containerd/cmd/containerd/command/notify_unsupported.go
generated
vendored
Normal file
@ -0,0 +1,31 @@
|
||||
// +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 command
|
||||
|
||||
import (
|
||||
"context"
|
||||
)
|
||||
|
||||
func notifyReady(ctx context.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func notifyStopping(ctx context.Context) error {
|
||||
return nil
|
||||
}
|
3
vendor/github.com/containerd/containerd/cmd/containerd/command/service_windows.go
generated
vendored
3
vendor/github.com/containerd/containerd/cmd/containerd/command/service_windows.go
generated
vendored
@ -49,8 +49,6 @@ var (
|
||||
allocConsole = kernel32.NewProc("AllocConsole")
|
||||
oldStderr windows.Handle
|
||||
panicFile *os.File
|
||||
|
||||
service *handler
|
||||
)
|
||||
|
||||
const defaultServiceName = "containerd"
|
||||
@ -282,7 +280,6 @@ func launchService(s *server.Server, done chan struct{}) error {
|
||||
return err
|
||||
}
|
||||
|
||||
service = h
|
||||
go func() {
|
||||
if interactive {
|
||||
err = debug.Run(serviceNameFlag, h)
|
||||
|
39
vendor/github.com/containerd/containerd/container.go
generated
vendored
39
vendor/github.com/containerd/containerd/container.go
generated
vendored
@ -32,6 +32,7 @@ import (
|
||||
"github.com/containerd/containerd/images"
|
||||
"github.com/containerd/containerd/oci"
|
||||
"github.com/containerd/containerd/runtime/v2/runc/options"
|
||||
"github.com/containerd/containerd/sys"
|
||||
"github.com/containerd/typeurl"
|
||||
prototypes "github.com/gogo/protobuf/types"
|
||||
ver "github.com/opencontainers/image-spec/specs-go"
|
||||
@ -422,14 +423,33 @@ func attachExistingIO(response *tasks.GetResponse, ioAttach cio.Attach) (cio.IO,
|
||||
|
||||
// loadFifos loads the containers fifos
|
||||
func loadFifos(response *tasks.GetResponse) *cio.FIFOSet {
|
||||
path := getFifoDir([]string{
|
||||
fifos := []string{
|
||||
response.Process.Stdin,
|
||||
response.Process.Stdout,
|
||||
response.Process.Stderr,
|
||||
})
|
||||
closer := func() error {
|
||||
return os.RemoveAll(path)
|
||||
}
|
||||
closer := func() error {
|
||||
var (
|
||||
err error
|
||||
dirs = map[string]struct{}{}
|
||||
)
|
||||
for _, fifo := range fifos {
|
||||
if isFifo, _ := sys.IsFifo(fifo); isFifo {
|
||||
if rerr := os.Remove(fifo); err == nil {
|
||||
err = rerr
|
||||
}
|
||||
dirs[filepath.Dir(fifo)] = struct{}{}
|
||||
}
|
||||
}
|
||||
for dir := range dirs {
|
||||
// we ignore errors here because we don't
|
||||
// want to remove the directory if it isn't
|
||||
// empty
|
||||
os.Remove(dir)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
return cio.NewFIFOSet(cio.Config{
|
||||
Stdin: response.Process.Stdin,
|
||||
Stdout: response.Process.Stdout,
|
||||
@ -437,14 +457,3 @@ func loadFifos(response *tasks.GetResponse) *cio.FIFOSet {
|
||||
Terminal: response.Process.Terminal,
|
||||
}, closer)
|
||||
}
|
||||
|
||||
// getFifoDir looks for any non-empty path for a stdio fifo
|
||||
// and returns the dir for where it is located
|
||||
func getFifoDir(paths []string) string {
|
||||
for _, p := range paths {
|
||||
if p != "" {
|
||||
return filepath.Dir(p)
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
39
vendor/github.com/containerd/containerd/content/local/store.go
generated
vendored
39
vendor/github.com/containerd/containerd/content/local/store.go
generated
vendored
@ -92,7 +92,11 @@ func NewLabeledStore(root string, ls LabelStore) (content.Store, error) {
|
||||
}
|
||||
|
||||
func (s *store) Info(ctx context.Context, dgst digest.Digest) (content.Info, error) {
|
||||
p := s.blobPath(dgst)
|
||||
p, err := s.blobPath(dgst)
|
||||
if err != nil {
|
||||
return content.Info{}, errors.Wrapf(err, "calculating blob info path")
|
||||
}
|
||||
|
||||
fi, err := os.Stat(p)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
@ -123,7 +127,10 @@ func (s *store) info(dgst digest.Digest, fi os.FileInfo, labels map[string]strin
|
||||
|
||||
// ReaderAt returns an io.ReaderAt for the blob.
|
||||
func (s *store) ReaderAt(ctx context.Context, desc ocispec.Descriptor) (content.ReaderAt, error) {
|
||||
p := s.blobPath(desc.Digest)
|
||||
p, err := s.blobPath(desc.Digest)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "calculating blob path for ReaderAt")
|
||||
}
|
||||
fi, err := os.Stat(p)
|
||||
if err != nil {
|
||||
if !os.IsNotExist(err) {
|
||||
@ -150,7 +157,12 @@ func (s *store) ReaderAt(ctx context.Context, desc ocispec.Descriptor) (content.
|
||||
// While this is safe to do concurrently, safe exist-removal logic must hold
|
||||
// some global lock on the store.
|
||||
func (s *store) Delete(ctx context.Context, dgst digest.Digest) error {
|
||||
if err := os.RemoveAll(s.blobPath(dgst)); err != nil {
|
||||
bp, err := s.blobPath(dgst)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "calculating blob path for delete")
|
||||
}
|
||||
|
||||
if err := os.RemoveAll(bp); err != nil {
|
||||
if !os.IsNotExist(err) {
|
||||
return err
|
||||
}
|
||||
@ -166,7 +178,11 @@ func (s *store) Update(ctx context.Context, info content.Info, fieldpaths ...str
|
||||
return content.Info{}, errors.Wrapf(errdefs.ErrFailedPrecondition, "update not supported on immutable content store")
|
||||
}
|
||||
|
||||
p := s.blobPath(info.Digest)
|
||||
p, err := s.blobPath(info.Digest)
|
||||
if err != nil {
|
||||
return content.Info{}, errors.Wrapf(err, "calculating blob path for update")
|
||||
}
|
||||
|
||||
fi, err := os.Stat(p)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
@ -512,7 +528,10 @@ func (s *store) writer(ctx context.Context, ref string, total int64, expected di
|
||||
// TODO(stevvooe): Need to actually store expected here. We have
|
||||
// code in the service that shouldn't be dealing with this.
|
||||
if expected != "" {
|
||||
p := s.blobPath(expected)
|
||||
p, err := s.blobPath(expected)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "calculating expected blob path for writer")
|
||||
}
|
||||
if _, err := os.Stat(p); err == nil {
|
||||
return nil, errors.Wrapf(errdefs.ErrAlreadyExists, "content %v", expected)
|
||||
}
|
||||
@ -607,11 +626,17 @@ func (s *store) Abort(ctx context.Context, ref string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *store) blobPath(dgst digest.Digest) string {
|
||||
return filepath.Join(s.root, "blobs", dgst.Algorithm().String(), dgst.Hex())
|
||||
func (s *store) blobPath(dgst digest.Digest) (string, error) {
|
||||
if err := dgst.Validate(); err != nil {
|
||||
return "", errors.Wrapf(errdefs.ErrInvalidArgument, "cannot calculate blob path from invalid digest: %v", err)
|
||||
}
|
||||
|
||||
return filepath.Join(s.root, "blobs", dgst.Algorithm().String(), dgst.Hex()), nil
|
||||
}
|
||||
|
||||
func (s *store) ingestRoot(ref string) string {
|
||||
// we take a digest of the ref to keep the ingest paths constant length.
|
||||
// Note that this is not the current or potential digest of incoming content.
|
||||
dgst := digest.FromString(ref)
|
||||
return filepath.Join(s.root, "ingest", dgst.Hex())
|
||||
}
|
||||
|
4
vendor/github.com/containerd/containerd/content/local/writer.go
generated
vendored
4
vendor/github.com/containerd/containerd/content/local/writer.go
generated
vendored
@ -115,8 +115,8 @@ func (w *writer) Commit(ctx context.Context, size int64, expected digest.Digest,
|
||||
}
|
||||
|
||||
var (
|
||||
ingest = filepath.Join(w.path, "data")
|
||||
target = w.s.blobPath(dgst)
|
||||
ingest = filepath.Join(w.path, "data")
|
||||
target, _ = w.s.blobPath(dgst) // ignore error because we calculated this dgst
|
||||
)
|
||||
|
||||
// make sure parent directories of blob exist
|
||||
|
25
vendor/github.com/containerd/containerd/contrib/seccomp/seccomp_default.go
generated
vendored
25
vendor/github.com/containerd/containerd/contrib/seccomp/seccomp_default.go
generated
vendored
@ -56,7 +56,6 @@ func DefaultProfile(sp *specs.Spec) *specs.LinuxSeccomp {
|
||||
"accept4",
|
||||
"access",
|
||||
"alarm",
|
||||
"alarm",
|
||||
"bind",
|
||||
"brk",
|
||||
"capget",
|
||||
@ -66,8 +65,11 @@ func DefaultProfile(sp *specs.Spec) *specs.LinuxSeccomp {
|
||||
"chown",
|
||||
"chown32",
|
||||
"clock_getres",
|
||||
"clock_getres_time64",
|
||||
"clock_gettime",
|
||||
"clock_gettime64",
|
||||
"clock_nanosleep",
|
||||
"clock_nanosleep_time64",
|
||||
"close",
|
||||
"connect",
|
||||
"copy_file_range",
|
||||
@ -117,6 +119,7 @@ func DefaultProfile(sp *specs.Spec) *specs.LinuxSeccomp {
|
||||
"ftruncate",
|
||||
"ftruncate64",
|
||||
"futex",
|
||||
"futex_time64",
|
||||
"futimesat",
|
||||
"getcpu",
|
||||
"getcwd",
|
||||
@ -163,6 +166,7 @@ func DefaultProfile(sp *specs.Spec) *specs.LinuxSeccomp {
|
||||
"io_destroy",
|
||||
"io_getevents",
|
||||
"io_pgetevents",
|
||||
"io_pgetevents_time64",
|
||||
"ioprio_get",
|
||||
"ioprio_set",
|
||||
"io_setup",
|
||||
@ -200,7 +204,9 @@ func DefaultProfile(sp *specs.Spec) *specs.LinuxSeccomp {
|
||||
"mq_notify",
|
||||
"mq_open",
|
||||
"mq_timedreceive",
|
||||
"mq_timedreceive_time64",
|
||||
"mq_timedsend",
|
||||
"mq_timedsend_time64",
|
||||
"mq_unlink",
|
||||
"mremap",
|
||||
"msgctl",
|
||||
@ -221,11 +227,13 @@ func DefaultProfile(sp *specs.Spec) *specs.LinuxSeccomp {
|
||||
"pipe2",
|
||||
"poll",
|
||||
"ppoll",
|
||||
"ppoll_time64",
|
||||
"prctl",
|
||||
"pread64",
|
||||
"preadv",
|
||||
"prlimit64",
|
||||
"pselect6",
|
||||
"pselect6_time64",
|
||||
"pwrite64",
|
||||
"pwritev",
|
||||
"read",
|
||||
@ -236,6 +244,7 @@ func DefaultProfile(sp *specs.Spec) *specs.LinuxSeccomp {
|
||||
"recv",
|
||||
"recvfrom",
|
||||
"recvmmsg",
|
||||
"recvmmsg_time64",
|
||||
"recvmsg",
|
||||
"remap_file_pages",
|
||||
"removexattr",
|
||||
@ -251,6 +260,7 @@ func DefaultProfile(sp *specs.Spec) *specs.LinuxSeccomp {
|
||||
"rt_sigreturn",
|
||||
"rt_sigsuspend",
|
||||
"rt_sigtimedwait",
|
||||
"rt_sigtimedwait_time64",
|
||||
"rt_tgsigqueueinfo",
|
||||
"sched_getaffinity",
|
||||
"sched_getattr",
|
||||
@ -259,6 +269,7 @@ func DefaultProfile(sp *specs.Spec) *specs.LinuxSeccomp {
|
||||
"sched_get_priority_min",
|
||||
"sched_getscheduler",
|
||||
"sched_rr_get_interval",
|
||||
"sched_rr_get_interval_time64",
|
||||
"sched_setaffinity",
|
||||
"sched_setattr",
|
||||
"sched_setparam",
|
||||
@ -270,6 +281,7 @@ func DefaultProfile(sp *specs.Spec) *specs.LinuxSeccomp {
|
||||
"semget",
|
||||
"semop",
|
||||
"semtimedop",
|
||||
"semtimedop_time64",
|
||||
"send",
|
||||
"sendfile",
|
||||
"sendfile64",
|
||||
@ -335,12 +347,16 @@ func DefaultProfile(sp *specs.Spec) *specs.LinuxSeccomp {
|
||||
"time",
|
||||
"timer_create",
|
||||
"timer_delete",
|
||||
"timerfd_create",
|
||||
"timerfd_gettime",
|
||||
"timerfd_settime",
|
||||
"timer_getoverrun",
|
||||
"timer_gettime",
|
||||
"timer_gettime64",
|
||||
"timer_settime",
|
||||
"timer_settime64",
|
||||
"timerfd_create",
|
||||
"timerfd_gettime",
|
||||
"timerfd_gettime64",
|
||||
"timerfd_settime",
|
||||
"timerfd_settime64",
|
||||
"times",
|
||||
"tkill",
|
||||
"truncate",
|
||||
@ -352,6 +368,7 @@ func DefaultProfile(sp *specs.Spec) *specs.LinuxSeccomp {
|
||||
"unlinkat",
|
||||
"utime",
|
||||
"utimensat",
|
||||
"utimensat_time64",
|
||||
"utimes",
|
||||
"vfork",
|
||||
"vmsplice",
|
||||
|
4
vendor/github.com/containerd/containerd/diff/apply/apply_linux.go
generated
vendored
4
vendor/github.com/containerd/containerd/diff/apply/apply_linux.go
generated
vendored
@ -26,7 +26,7 @@ import (
|
||||
"github.com/containerd/containerd/archive"
|
||||
"github.com/containerd/containerd/errdefs"
|
||||
"github.com/containerd/containerd/mount"
|
||||
"github.com/opencontainers/runc/libcontainer/system"
|
||||
"github.com/containerd/containerd/sys"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
@ -35,7 +35,7 @@ func apply(ctx context.Context, mounts []mount.Mount, r io.Reader) error {
|
||||
case len(mounts) == 1 && mounts[0].Type == "overlay":
|
||||
// OverlayConvertWhiteout (mknod c 0 0) doesn't work in userns.
|
||||
// https://github.com/containerd/containerd/issues/3762
|
||||
if system.RunningInUserNS() {
|
||||
if sys.RunningInUserNS() {
|
||||
break
|
||||
}
|
||||
path, parents, err := getOverlayPath(mounts[0].Options)
|
||||
|
8
vendor/github.com/containerd/containerd/lease.go
generated
vendored
8
vendor/github.com/containerd/containerd/lease.go
generated
vendored
@ -25,11 +25,11 @@ import (
|
||||
|
||||
// WithLease attaches a lease on the context
|
||||
func (c *Client) WithLease(ctx context.Context, opts ...leases.Opt) (context.Context, func(context.Context) error, error) {
|
||||
nop := func(context.Context) error { return nil }
|
||||
|
||||
_, ok := leases.FromContext(ctx)
|
||||
if ok {
|
||||
return ctx, func(context.Context) error {
|
||||
return nil
|
||||
}, nil
|
||||
return ctx, nop, nil
|
||||
}
|
||||
|
||||
ls := c.LeasesService()
|
||||
@ -44,7 +44,7 @@ func (c *Client) WithLease(ctx context.Context, opts ...leases.Opt) (context.Con
|
||||
|
||||
l, err := ls.Create(ctx, opts...)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
return ctx, nop, err
|
||||
}
|
||||
|
||||
ctx = leases.WithLease(ctx, l.ID)
|
||||
|
4
vendor/github.com/containerd/containerd/metrics/cgroups/v1/cgroups.go
generated
vendored
4
vendor/github.com/containerd/containerd/metrics/cgroups/v1/cgroups.go
generated
vendored
@ -35,7 +35,7 @@ import (
|
||||
|
||||
// NewTaskMonitor returns a new cgroups monitor
|
||||
func NewTaskMonitor(ctx context.Context, publisher events.Publisher, ns *metrics.Namespace) (runtime.TaskMonitor, error) {
|
||||
collector := newCollector(ns)
|
||||
collector := NewCollector(ns)
|
||||
oom, err := newOOMCollector(ns)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -49,7 +49,7 @@ func NewTaskMonitor(ctx context.Context, publisher events.Publisher, ns *metrics
|
||||
}
|
||||
|
||||
type cgroupsMonitor struct {
|
||||
collector *collector
|
||||
collector *Collector
|
||||
oom *oomCollector
|
||||
context context.Context
|
||||
publisher events.Publisher
|
||||
|
5
vendor/github.com/containerd/containerd/metrics/cgroups/v1/metric.go
generated
vendored
5
vendor/github.com/containerd/containerd/metrics/cgroups/v1/metric.go
generated
vendored
@ -24,6 +24,9 @@ import (
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
// IDName is the name that is used to identify the id being collected in the metric
|
||||
var IDName = "container_id"
|
||||
|
||||
type value struct {
|
||||
v float64
|
||||
l []string
|
||||
@ -41,7 +44,7 @@ type metric struct {
|
||||
|
||||
func (m *metric) desc(ns *metrics.Namespace) *prometheus.Desc {
|
||||
// the namespace label is for containerd namespaces
|
||||
return ns.NewDesc(m.name, m.help, m.unit, append([]string{"container_id", "namespace"}, m.labels...)...)
|
||||
return ns.NewDesc(m.name, m.help, m.unit, append([]string{IDName, "namespace"}, m.labels...)...)
|
||||
}
|
||||
|
||||
func (m *metric) collect(id, namespace string, stats *v1.Metrics, ns *metrics.Namespace, ch chan<- prometheus.Metric, block bool) {
|
||||
|
49
vendor/github.com/containerd/containerd/metrics/cgroups/v1/metrics.go
generated
vendored
49
vendor/github.com/containerd/containerd/metrics/cgroups/v1/metrics.go
generated
vendored
@ -27,26 +27,33 @@ import (
|
||||
"github.com/containerd/containerd/log"
|
||||
v1 "github.com/containerd/containerd/metrics/types/v1"
|
||||
"github.com/containerd/containerd/namespaces"
|
||||
"github.com/containerd/containerd/runtime"
|
||||
"github.com/containerd/typeurl"
|
||||
metrics "github.com/docker/go-metrics"
|
||||
"github.com/gogo/protobuf/types"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
// Statable type that returns cgroup metrics
|
||||
type Statable interface {
|
||||
ID() string
|
||||
Namespace() string
|
||||
Stats(context.Context) (*types.Any, error)
|
||||
}
|
||||
|
||||
// Trigger will be called when an event happens and provides the cgroup
|
||||
// where the event originated from
|
||||
type Trigger func(string, string, cgroups.Cgroup)
|
||||
|
||||
// newCollector registers the collector with the provided namespace and returns it so
|
||||
// NewCollector registers the collector with the provided namespace and returns it so
|
||||
// that cgroups can be added for collection
|
||||
func newCollector(ns *metrics.Namespace) *collector {
|
||||
func NewCollector(ns *metrics.Namespace) *Collector {
|
||||
if ns == nil {
|
||||
return &collector{}
|
||||
return &Collector{}
|
||||
}
|
||||
// add machine cpus and memory info
|
||||
c := &collector{
|
||||
c := &Collector{
|
||||
ns: ns,
|
||||
tasks: make(map[string]runtime.Task),
|
||||
tasks: make(map[string]Statable),
|
||||
}
|
||||
c.metrics = append(c.metrics, pidMetrics...)
|
||||
c.metrics = append(c.metrics, cpuMetrics...)
|
||||
@ -62,24 +69,26 @@ func taskID(id, namespace string) string {
|
||||
return fmt.Sprintf("%s-%s", id, namespace)
|
||||
}
|
||||
|
||||
// collector provides the ability to collect container stats and export
|
||||
// Collector provides the ability to collect container stats and export
|
||||
// them in the prometheus format
|
||||
type collector struct {
|
||||
type Collector struct {
|
||||
mu sync.RWMutex
|
||||
|
||||
tasks map[string]runtime.Task
|
||||
tasks map[string]Statable
|
||||
ns *metrics.Namespace
|
||||
metrics []*metric
|
||||
storedMetrics chan prometheus.Metric
|
||||
}
|
||||
|
||||
func (c *collector) Describe(ch chan<- *prometheus.Desc) {
|
||||
// Describe prometheus metrics
|
||||
func (c *Collector) Describe(ch chan<- *prometheus.Desc) {
|
||||
for _, m := range c.metrics {
|
||||
ch <- m.desc(c.ns)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *collector) Collect(ch chan<- prometheus.Metric) {
|
||||
// Collect prometheus metrics
|
||||
func (c *Collector) Collect(ch chan<- prometheus.Metric) {
|
||||
c.mu.RLock()
|
||||
wg := &sync.WaitGroup{}
|
||||
for _, t := range c.tasks {
|
||||
@ -100,7 +109,7 @@ storedLoop:
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
func (c *collector) collect(t runtime.Task, ch chan<- prometheus.Metric, block bool, wg *sync.WaitGroup) {
|
||||
func (c *Collector) collect(t Statable, ch chan<- prometheus.Metric, block bool, wg *sync.WaitGroup) {
|
||||
if wg != nil {
|
||||
defer wg.Done()
|
||||
}
|
||||
@ -126,7 +135,7 @@ func (c *collector) collect(t runtime.Task, ch chan<- prometheus.Metric, block b
|
||||
}
|
||||
|
||||
// Add adds the provided cgroup and id so that metrics are collected and exported
|
||||
func (c *collector) Add(t runtime.Task) error {
|
||||
func (c *Collector) Add(t Statable) error {
|
||||
if c.ns == nil {
|
||||
return nil
|
||||
}
|
||||
@ -141,11 +150,21 @@ func (c *collector) Add(t runtime.Task) error {
|
||||
}
|
||||
|
||||
// Remove removes the provided cgroup by id from the collector
|
||||
func (c *collector) Remove(t runtime.Task) {
|
||||
func (c *Collector) Remove(t Statable) {
|
||||
if c.ns == nil {
|
||||
return
|
||||
}
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
delete(c.tasks, taskID(t.ID(), t.Namespace()))
|
||||
c.mu.Unlock()
|
||||
}
|
||||
|
||||
// RemoveAll statable items from the collector
|
||||
func (c *Collector) RemoveAll() {
|
||||
if c.ns == nil {
|
||||
return
|
||||
}
|
||||
c.mu.Lock()
|
||||
c.tasks = make(map[string]Statable)
|
||||
c.mu.Unlock()
|
||||
}
|
||||
|
4
vendor/github.com/containerd/containerd/metrics/cgroups/v2/cgroups.go
generated
vendored
4
vendor/github.com/containerd/containerd/metrics/cgroups/v2/cgroups.go
generated
vendored
@ -30,7 +30,7 @@ import (
|
||||
|
||||
// NewTaskMonitor returns a new cgroups monitor
|
||||
func NewTaskMonitor(ctx context.Context, publisher events.Publisher, ns *metrics.Namespace) (runtime.TaskMonitor, error) {
|
||||
collector := newCollector(ns)
|
||||
collector := NewCollector(ns)
|
||||
return &cgroupsMonitor{
|
||||
collector: collector,
|
||||
context: ctx,
|
||||
@ -39,7 +39,7 @@ func NewTaskMonitor(ctx context.Context, publisher events.Publisher, ns *metrics
|
||||
}
|
||||
|
||||
type cgroupsMonitor struct {
|
||||
collector *collector
|
||||
collector *Collector
|
||||
context context.Context
|
||||
publisher events.Publisher
|
||||
}
|
||||
|
5
vendor/github.com/containerd/containerd/metrics/cgroups/v2/metric.go
generated
vendored
5
vendor/github.com/containerd/containerd/metrics/cgroups/v2/metric.go
generated
vendored
@ -24,6 +24,9 @@ import (
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
// IDName is the name that is used to identify the id being collected in the metric
|
||||
var IDName = "container_id"
|
||||
|
||||
type value struct {
|
||||
v float64
|
||||
l []string
|
||||
@ -41,7 +44,7 @@ type metric struct {
|
||||
|
||||
func (m *metric) desc(ns *metrics.Namespace) *prometheus.Desc {
|
||||
// the namespace label is for containerd namespaces
|
||||
return ns.NewDesc(m.name, m.help, m.unit, append([]string{"container_id", "namespace"}, m.labels...)...)
|
||||
return ns.NewDesc(m.name, m.help, m.unit, append([]string{IDName, "namespace"}, m.labels...)...)
|
||||
}
|
||||
|
||||
func (m *metric) collect(id, namespace string, stats *v2.Metrics, ns *metrics.Namespace, ch chan<- prometheus.Metric, block bool) {
|
||||
|
47
vendor/github.com/containerd/containerd/metrics/cgroups/v2/metrics.go
generated
vendored
47
vendor/github.com/containerd/containerd/metrics/cgroups/v2/metrics.go
generated
vendored
@ -26,21 +26,28 @@ import (
|
||||
"github.com/containerd/containerd/log"
|
||||
v2 "github.com/containerd/containerd/metrics/types/v2"
|
||||
"github.com/containerd/containerd/namespaces"
|
||||
"github.com/containerd/containerd/runtime"
|
||||
"github.com/containerd/typeurl"
|
||||
metrics "github.com/docker/go-metrics"
|
||||
"github.com/gogo/protobuf/types"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
// newCollector registers the collector with the provided namespace and returns it so
|
||||
// Statable type that returns cgroup metrics
|
||||
type Statable interface {
|
||||
ID() string
|
||||
Namespace() string
|
||||
Stats(context.Context) (*types.Any, error)
|
||||
}
|
||||
|
||||
// NewCollector registers the collector with the provided namespace and returns it so
|
||||
// that cgroups can be added for collection
|
||||
func newCollector(ns *metrics.Namespace) *collector {
|
||||
func NewCollector(ns *metrics.Namespace) *Collector {
|
||||
if ns == nil {
|
||||
return &collector{}
|
||||
return &Collector{}
|
||||
}
|
||||
c := &collector{
|
||||
c := &Collector{
|
||||
ns: ns,
|
||||
tasks: make(map[string]runtime.Task),
|
||||
tasks: make(map[string]Statable),
|
||||
}
|
||||
c.metrics = append(c.metrics, pidMetrics...)
|
||||
c.metrics = append(c.metrics, cpuMetrics...)
|
||||
@ -55,24 +62,26 @@ func taskID(id, namespace string) string {
|
||||
return fmt.Sprintf("%s-%s", id, namespace)
|
||||
}
|
||||
|
||||
// collector provides the ability to collect container stats and export
|
||||
// Collector provides the ability to collect container stats and export
|
||||
// them in the prometheus format
|
||||
type collector struct {
|
||||
type Collector struct {
|
||||
mu sync.RWMutex
|
||||
|
||||
tasks map[string]runtime.Task
|
||||
tasks map[string]Statable
|
||||
ns *metrics.Namespace
|
||||
metrics []*metric
|
||||
storedMetrics chan prometheus.Metric
|
||||
}
|
||||
|
||||
func (c *collector) Describe(ch chan<- *prometheus.Desc) {
|
||||
// Describe prometheus metrics
|
||||
func (c *Collector) Describe(ch chan<- *prometheus.Desc) {
|
||||
for _, m := range c.metrics {
|
||||
ch <- m.desc(c.ns)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *collector) Collect(ch chan<- prometheus.Metric) {
|
||||
// Collect prometheus metrics
|
||||
func (c *Collector) Collect(ch chan<- prometheus.Metric) {
|
||||
c.mu.RLock()
|
||||
wg := &sync.WaitGroup{}
|
||||
for _, t := range c.tasks {
|
||||
@ -93,7 +102,7 @@ storedLoop:
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
func (c *collector) collect(t runtime.Task, ch chan<- prometheus.Metric, block bool, wg *sync.WaitGroup) {
|
||||
func (c *Collector) collect(t Statable, ch chan<- prometheus.Metric, block bool, wg *sync.WaitGroup) {
|
||||
if wg != nil {
|
||||
defer wg.Done()
|
||||
}
|
||||
@ -119,7 +128,7 @@ func (c *collector) collect(t runtime.Task, ch chan<- prometheus.Metric, block b
|
||||
}
|
||||
|
||||
// Add adds the provided cgroup and id so that metrics are collected and exported
|
||||
func (c *collector) Add(t runtime.Task) error {
|
||||
func (c *Collector) Add(t Statable) error {
|
||||
if c.ns == nil {
|
||||
return nil
|
||||
}
|
||||
@ -134,7 +143,7 @@ func (c *collector) Add(t runtime.Task) error {
|
||||
}
|
||||
|
||||
// Remove removes the provided cgroup by id from the collector
|
||||
func (c *collector) Remove(t runtime.Task) {
|
||||
func (c *Collector) Remove(t Statable) {
|
||||
if c.ns == nil {
|
||||
return
|
||||
}
|
||||
@ -142,3 +151,13 @@ func (c *collector) Remove(t runtime.Task) {
|
||||
defer c.mu.Unlock()
|
||||
delete(c.tasks, taskID(t.ID(), t.Namespace()))
|
||||
}
|
||||
|
||||
// RemoveAll statable items from the collector
|
||||
func (c *Collector) RemoveAll() {
|
||||
if c.ns == nil {
|
||||
return
|
||||
}
|
||||
c.mu.Lock()
|
||||
c.tasks = make(map[string]Statable)
|
||||
c.mu.Unlock()
|
||||
}
|
||||
|
8
vendor/github.com/containerd/containerd/mount/mountinfo_linux.go
generated
vendored
8
vendor/github.com/containerd/containerd/mount/mountinfo_linux.go
generated
vendored
@ -45,10 +45,6 @@ func parseInfoFile(r io.Reader) ([]Info, error) {
|
||||
out := []Info{}
|
||||
var err error
|
||||
for s.Scan() {
|
||||
if err = s.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
/*
|
||||
See http://man7.org/linux/man-pages/man5/proc.5.html
|
||||
|
||||
@ -128,6 +124,10 @@ func parseInfoFile(r io.Reader) ([]Info, error) {
|
||||
|
||||
out = append(out, p)
|
||||
}
|
||||
if err = s.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
|
6
vendor/github.com/containerd/containerd/oci/spec_opts.go
generated
vendored
6
vendor/github.com/containerd/containerd/oci/spec_opts.go
generated
vendored
@ -1238,11 +1238,11 @@ func WithEnvFile(path string) SpecOpts {
|
||||
|
||||
sc := bufio.NewScanner(f)
|
||||
for sc.Scan() {
|
||||
if sc.Err() != nil {
|
||||
return sc.Err()
|
||||
}
|
||||
vars = append(vars, sc.Text())
|
||||
}
|
||||
if err = sc.Err(); err != nil {
|
||||
return err
|
||||
}
|
||||
return WithEnv(vars)(nil, nil, nil, s)
|
||||
}
|
||||
}
|
||||
|
190
vendor/github.com/containerd/containerd/pkg/process/io.go
generated
vendored
190
vendor/github.com/containerd/containerd/pkg/process/io.go
generated
vendored
@ -29,15 +29,20 @@ import (
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/containerd/containerd/log"
|
||||
"github.com/containerd/containerd/namespaces"
|
||||
"github.com/containerd/containerd/pkg/stdio"
|
||||
"github.com/containerd/containerd/sys"
|
||||
"github.com/containerd/fifo"
|
||||
runc "github.com/containerd/go-runc"
|
||||
"github.com/hashicorp/go-multierror"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
const binaryIOProcTermTimeout = 12 * time.Second // Give logger process solid 10 seconds for cleanup
|
||||
|
||||
var bufPool = sync.Pool{
|
||||
New: func() interface{} {
|
||||
// setting to 4096 to align with PIPE_BUF
|
||||
@ -174,7 +179,7 @@ func copyPipes(ctx context.Context, rio runc.IO, stdin, stdout, stderr string, w
|
||||
},
|
||||
},
|
||||
} {
|
||||
ok, err := isFifo(i.name)
|
||||
ok, err := sys.IsFifo(i.name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -240,28 +245,13 @@ func (c *countingWriteCloser) Close() error {
|
||||
return c.WriteCloser.Close()
|
||||
}
|
||||
|
||||
// isFifo checks if a file is a fifo
|
||||
// if the file does not exist then it returns false
|
||||
func isFifo(path string) (bool, error) {
|
||||
stat, err := os.Stat(path)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return false, nil
|
||||
}
|
||||
return false, err
|
||||
}
|
||||
if stat.Mode()&os.ModeNamedPipe == os.ModeNamedPipe {
|
||||
return true, nil
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// NewBinaryIO runs a custom binary process for pluggable shim logging
|
||||
func NewBinaryIO(ctx context.Context, id string, uri *url.URL) (runc.IO, error) {
|
||||
func NewBinaryIO(ctx context.Context, id string, uri *url.URL) (_ runc.IO, err error) {
|
||||
ns, err := namespaces.NamespaceRequired(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var args []string
|
||||
for k, vs := range uri.Query() {
|
||||
args = append(args, k)
|
||||
@ -269,86 +259,146 @@ func NewBinaryIO(ctx context.Context, id string, uri *url.URL) (runc.IO, error)
|
||||
args = append(args, vs[0])
|
||||
}
|
||||
}
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
cmd := exec.CommandContext(ctx, uri.Path, args...)
|
||||
|
||||
var closers []func() error
|
||||
defer func() {
|
||||
if err == nil {
|
||||
return
|
||||
}
|
||||
result := multierror.Append(err)
|
||||
for _, fn := range closers {
|
||||
result = multierror.Append(result, fn())
|
||||
}
|
||||
err = multierror.Flatten(result)
|
||||
}()
|
||||
|
||||
out, err := newPipe()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to create stdout pipes")
|
||||
}
|
||||
closers = append(closers, out.Close)
|
||||
|
||||
serr, err := newPipe()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to create stderr pipes")
|
||||
}
|
||||
closers = append(closers, serr.Close)
|
||||
|
||||
r, w, err := os.Pipe()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
closers = append(closers, r.Close, w.Close)
|
||||
|
||||
cmd := exec.Command(uri.Path, args...)
|
||||
cmd.Env = append(cmd.Env,
|
||||
"CONTAINER_ID="+id,
|
||||
"CONTAINER_NAMESPACE="+ns,
|
||||
)
|
||||
out, err := newPipe()
|
||||
if err != nil {
|
||||
cancel()
|
||||
return nil, err
|
||||
}
|
||||
serr, err := newPipe()
|
||||
if err != nil {
|
||||
cancel()
|
||||
return nil, err
|
||||
}
|
||||
r, w, err := os.Pipe()
|
||||
if err != nil {
|
||||
cancel()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cmd.ExtraFiles = append(cmd.ExtraFiles, out.r, serr.r, w)
|
||||
// don't need to register this with the reaper or wait when
|
||||
// running inside a shim
|
||||
if err := cmd.Start(); err != nil {
|
||||
cancel()
|
||||
return nil, err
|
||||
return nil, errors.Wrap(err, "failed to start binary process")
|
||||
}
|
||||
closers = append(closers, func() error { return cmd.Process.Kill() })
|
||||
|
||||
// close our side of the pipe after start
|
||||
if err := w.Close(); err != nil {
|
||||
cancel()
|
||||
return nil, err
|
||||
return nil, errors.Wrap(err, "failed to close write pipe after start")
|
||||
}
|
||||
|
||||
// wait for the logging binary to be ready
|
||||
b := make([]byte, 1)
|
||||
if _, err := r.Read(b); err != nil && err != io.EOF {
|
||||
cancel()
|
||||
return nil, err
|
||||
return nil, errors.Wrap(err, "failed to read from logging binary")
|
||||
}
|
||||
|
||||
return &binaryIO{
|
||||
cmd: cmd,
|
||||
cancel: cancel,
|
||||
out: out,
|
||||
err: serr,
|
||||
cmd: cmd,
|
||||
out: out,
|
||||
err: serr,
|
||||
}, nil
|
||||
}
|
||||
|
||||
type binaryIO struct {
|
||||
cmd *exec.Cmd
|
||||
cancel func()
|
||||
out, err *pipe
|
||||
}
|
||||
|
||||
func (b *binaryIO) CloseAfterStart() (err error) {
|
||||
for _, v := range []*pipe{
|
||||
b.out,
|
||||
b.err,
|
||||
} {
|
||||
func (b *binaryIO) CloseAfterStart() error {
|
||||
var (
|
||||
result *multierror.Error
|
||||
)
|
||||
|
||||
for _, v := range []*pipe{b.out, b.err} {
|
||||
if v != nil {
|
||||
if cerr := v.r.Close(); err == nil {
|
||||
err = cerr
|
||||
if err := v.r.Close(); err != nil {
|
||||
result = multierror.Append(result, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
return err
|
||||
|
||||
return result.ErrorOrNil()
|
||||
}
|
||||
|
||||
func (b *binaryIO) Close() (err error) {
|
||||
b.cancel()
|
||||
for _, v := range []*pipe{
|
||||
b.out,
|
||||
b.err,
|
||||
} {
|
||||
func (b *binaryIO) Close() error {
|
||||
var (
|
||||
result *multierror.Error
|
||||
)
|
||||
|
||||
for _, v := range []*pipe{b.out, b.err} {
|
||||
if v != nil {
|
||||
if cerr := v.Close(); err == nil {
|
||||
err = cerr
|
||||
if err := v.Close(); err != nil {
|
||||
result = multierror.Append(result, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
return err
|
||||
|
||||
if err := b.cancel(); err != nil {
|
||||
result = multierror.Append(result, err)
|
||||
}
|
||||
|
||||
return result.ErrorOrNil()
|
||||
}
|
||||
|
||||
func (b *binaryIO) cancel() error {
|
||||
if b.cmd == nil || b.cmd.Process == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Send SIGTERM first, so logger process has a chance to flush and exit properly
|
||||
if err := b.cmd.Process.Signal(syscall.SIGTERM); err != nil {
|
||||
result := multierror.Append(errors.Wrap(err, "failed to send SIGTERM"))
|
||||
|
||||
log.L.WithError(err).Warn("failed to send SIGTERM signal, killing logging shim")
|
||||
|
||||
if err := b.cmd.Process.Kill(); err != nil {
|
||||
result = multierror.Append(result, errors.Wrap(err, "failed to kill process after faulty SIGTERM"))
|
||||
}
|
||||
|
||||
return result.ErrorOrNil()
|
||||
}
|
||||
|
||||
done := make(chan error)
|
||||
go func() {
|
||||
done <- b.cmd.Wait()
|
||||
}()
|
||||
|
||||
select {
|
||||
case err := <-done:
|
||||
return err
|
||||
case <-time.After(binaryIOProcTermTimeout):
|
||||
log.L.Warn("failed to wait for shim logger process to exit, killing")
|
||||
|
||||
err := b.cmd.Process.Kill()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to kill shim logger process")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func (b *binaryIO) Stdin() io.WriteCloser {
|
||||
@ -389,9 +439,15 @@ type pipe struct {
|
||||
}
|
||||
|
||||
func (p *pipe) Close() error {
|
||||
err := p.w.Close()
|
||||
if rerr := p.r.Close(); err == nil {
|
||||
err = rerr
|
||||
var result *multierror.Error
|
||||
|
||||
if err := p.w.Close(); err != nil {
|
||||
result = multierror.Append(result, errors.Wrap(err, "failed to close write pipe"))
|
||||
}
|
||||
return err
|
||||
|
||||
if err := p.r.Close(); err != nil {
|
||||
result = multierror.Append(result, errors.Wrap(err, "failed to close read pipe"))
|
||||
}
|
||||
|
||||
return multierror.Prefix(result.ErrorOrNil(), "pipe:")
|
||||
}
|
||||
|
37
vendor/github.com/containerd/containerd/pkg/ttrpcutil/client.go
generated
vendored
37
vendor/github.com/containerd/containerd/pkg/ttrpcutil/client.go
generated
vendored
@ -50,14 +50,8 @@ func NewClient(address string, opts ...ttrpc.ClientOpts) (*Client, error) {
|
||||
return client, nil
|
||||
}
|
||||
|
||||
client, err := connector()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &Client{
|
||||
connector: connector,
|
||||
client: client,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@ -74,6 +68,12 @@ func (c *Client) Reconnect() error {
|
||||
return errors.New("client is closed")
|
||||
}
|
||||
|
||||
if c.client != nil {
|
||||
if err := c.client.Close(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
client, err := c.connector()
|
||||
if err != nil {
|
||||
return err
|
||||
@ -84,16 +84,26 @@ func (c *Client) Reconnect() error {
|
||||
}
|
||||
|
||||
// EventsService creates an EventsService client
|
||||
func (c *Client) EventsService() v1.EventsService {
|
||||
return v1.NewEventsClient(c.Client())
|
||||
func (c *Client) EventsService() (v1.EventsService, error) {
|
||||
client, err := c.Client()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return v1.NewEventsClient(client), nil
|
||||
}
|
||||
|
||||
// Client returns the underlying TTRPC client object
|
||||
func (c *Client) Client() *ttrpc.Client {
|
||||
func (c *Client) Client() (*ttrpc.Client, error) {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
|
||||
return c.client
|
||||
if c.client == nil {
|
||||
client, err := c.connector()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
c.client = client
|
||||
}
|
||||
return c.client, nil
|
||||
}
|
||||
|
||||
// Close closes the clients TTRPC connection to containerd
|
||||
@ -102,5 +112,8 @@ func (c *Client) Close() error {
|
||||
defer c.mu.Unlock()
|
||||
|
||||
c.closed = true
|
||||
return c.client.Close()
|
||||
if c.client != nil {
|
||||
return c.client.Close()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
2
vendor/github.com/containerd/containerd/pull.go
generated
vendored
2
vendor/github.com/containerd/containerd/pull.go
generated
vendored
@ -72,7 +72,7 @@ func (c *Client) Pull(ctx context.Context, ref string, opts ...RemoteOpt) (_ Ima
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "create unpacker")
|
||||
}
|
||||
unpackWrapper, unpackEg = u.handlerWrapper(ctx, &unpacks)
|
||||
unpackWrapper, unpackEg = u.handlerWrapper(ctx, pullCtx, &unpacks)
|
||||
defer func() {
|
||||
if err := unpackEg.Wait(); err != nil {
|
||||
if retErr == nil {
|
||||
|
2
vendor/github.com/containerd/containerd/rootfs/apply.go
generated
vendored
2
vendor/github.com/containerd/containerd/rootfs/apply.go
generated
vendored
@ -129,7 +129,7 @@ func applyLayers(ctx context.Context, layers []Layer, chain []digest.Digest, sn
|
||||
mounts, err = sn.Prepare(ctx, key, parent.String(), opts...)
|
||||
if err != nil {
|
||||
if errdefs.IsNotFound(err) && len(layers) > 1 {
|
||||
if err := applyLayers(ctx, layers[:len(layers)-1], chain[:len(chain)-1], sn, a, nil, applyOpts); err != nil {
|
||||
if err := applyLayers(ctx, layers[:len(layers)-1], chain[:len(chain)-1], sn, a, opts, applyOpts); err != nil {
|
||||
if !errdefs.IsAlreadyExists(err) {
|
||||
return err
|
||||
}
|
||||
|
57
vendor/github.com/containerd/containerd/runtime/v1/shim/service.go
generated
vendored
57
vendor/github.com/containerd/containerd/runtime/v1/shim/service.go
generated
vendored
@ -503,42 +503,37 @@ func (s *Service) processExits() {
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Service) allProcesses() []process.Process {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
|
||||
res := make([]process.Process, 0, len(s.processes))
|
||||
for _, p := range s.processes {
|
||||
res = append(res, p)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func (s *Service) checkProcesses(e runc.Exit) {
|
||||
for _, p := range s.allProcesses() {
|
||||
if p.Pid() != e.Pid {
|
||||
continue
|
||||
var p process.Process
|
||||
s.mu.Lock()
|
||||
for _, proc := range s.processes {
|
||||
if proc.Pid() == e.Pid {
|
||||
p = proc
|
||||
break
|
||||
}
|
||||
|
||||
if ip, ok := p.(*process.Init); ok {
|
||||
// Ensure all children are killed
|
||||
if shouldKillAllOnExit(s.context, s.bundle) {
|
||||
if err := ip.KillAll(s.context); err != nil {
|
||||
log.G(s.context).WithError(err).WithField("id", ip.ID()).
|
||||
Error("failed to kill init's children")
|
||||
}
|
||||
}
|
||||
s.mu.Unlock()
|
||||
if p == nil {
|
||||
log.G(s.context).Infof("process with id:%d wasn't found", e.Pid)
|
||||
return
|
||||
}
|
||||
if ip, ok := p.(*process.Init); ok {
|
||||
// Ensure all children are killed
|
||||
if shouldKillAllOnExit(s.context, s.bundle) {
|
||||
if err := ip.KillAll(s.context); err != nil {
|
||||
log.G(s.context).WithError(err).WithField("id", ip.ID()).
|
||||
Error("failed to kill init's children")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
p.SetExited(e.Status)
|
||||
s.events <- &eventstypes.TaskExit{
|
||||
ContainerID: s.id,
|
||||
ID: p.ID(),
|
||||
Pid: uint32(e.Pid),
|
||||
ExitStatus: uint32(e.Status),
|
||||
ExitedAt: p.ExitedAt(),
|
||||
}
|
||||
return
|
||||
p.SetExited(e.Status)
|
||||
s.events <- &eventstypes.TaskExit{
|
||||
ContainerID: s.id,
|
||||
ID: p.ID(),
|
||||
Pid: uint32(e.Pid),
|
||||
ExitStatus: uint32(e.Status),
|
||||
ExitedAt: p.ExitedAt(),
|
||||
}
|
||||
}
|
||||
|
||||
|
3
vendor/github.com/containerd/containerd/runtime/v2/README.md
generated
vendored
3
vendor/github.com/containerd/containerd/runtime/v2/README.md
generated
vendored
@ -227,9 +227,6 @@ func copy(wg *sync.WaitGroup, r io.Reader, pri journal.Priority, vars map[string
|
||||
defer wg.Done()
|
||||
s := bufio.NewScanner(r)
|
||||
for s.Scan() {
|
||||
if s.Err() != nil {
|
||||
return
|
||||
}
|
||||
journal.Send(s.Text(), pri, vars)
|
||||
}
|
||||
}
|
||||
|
9
vendor/github.com/containerd/containerd/runtime/v2/shim.go
generated
vendored
9
vendor/github.com/containerd/containerd/runtime/v2/shim.go
generated
vendored
@ -226,9 +226,12 @@ func (s *shim) Delete(ctx context.Context) (*runtime.Exit, error) {
|
||||
ID: s.ID(),
|
||||
})
|
||||
if shimErr != nil {
|
||||
shimErr = errdefs.FromGRPC(shimErr)
|
||||
if !errdefs.IsNotFound(shimErr) {
|
||||
return nil, shimErr
|
||||
log.G(ctx).WithField("id", s.ID()).WithError(shimErr).Debug("failed to delete task")
|
||||
if errors.Cause(shimErr) != ttrpc.ErrClosed {
|
||||
shimErr = errdefs.FromGRPC(shimErr)
|
||||
if !errdefs.IsNotFound(shimErr) {
|
||||
return nil, shimErr
|
||||
}
|
||||
}
|
||||
}
|
||||
// remove self from the runtime task list
|
||||
|
15
vendor/github.com/containerd/containerd/runtime/v2/shim/publisher.go
generated
vendored
15
vendor/github.com/containerd/containerd/runtime/v2/shim/publisher.go
generated
vendored
@ -128,9 +128,12 @@ func (l *RemoteEventsPublisher) Publish(ctx context.Context, topic string, event
|
||||
}
|
||||
|
||||
func (l *RemoteEventsPublisher) forwardRequest(ctx context.Context, req *v1.ForwardRequest) error {
|
||||
_, err := l.client.EventsService().Forward(ctx, req)
|
||||
service, err := l.client.EventsService()
|
||||
if err == nil {
|
||||
return nil
|
||||
_, err = service.Forward(ctx, req)
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
if err != ttrpc.ErrClosed {
|
||||
@ -138,11 +141,15 @@ func (l *RemoteEventsPublisher) forwardRequest(ctx context.Context, req *v1.Forw
|
||||
}
|
||||
|
||||
// Reconnect and retry request
|
||||
if err := l.client.Reconnect(); err != nil {
|
||||
if err = l.client.Reconnect(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err := l.client.EventsService().Forward(ctx, req); err != nil {
|
||||
service, err = l.client.EventsService()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err = service.Forward(ctx, req); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
12
vendor/github.com/containerd/containerd/runtime/v2/shim/shim.go
generated
vendored
12
vendor/github.com/containerd/containerd/runtime/v2/shim/shim.go
generated
vendored
@ -31,6 +31,7 @@ import (
|
||||
"github.com/containerd/containerd/log"
|
||||
"github.com/containerd/containerd/namespaces"
|
||||
shimapi "github.com/containerd/containerd/runtime/v2/task"
|
||||
"github.com/containerd/containerd/version"
|
||||
"github.com/containerd/ttrpc"
|
||||
"github.com/gogo/protobuf/proto"
|
||||
"github.com/pkg/errors"
|
||||
@ -84,6 +85,7 @@ type Config struct {
|
||||
|
||||
var (
|
||||
debugFlag bool
|
||||
versionFlag bool
|
||||
idFlag string
|
||||
namespaceFlag string
|
||||
socketFlag string
|
||||
@ -99,6 +101,7 @@ const (
|
||||
|
||||
func parseFlags() {
|
||||
flag.BoolVar(&debugFlag, "debug", false, "enable debug output in logs")
|
||||
flag.BoolVar(&versionFlag, "v", false, "show the shim version and exit")
|
||||
flag.StringVar(&namespaceFlag, "namespace", "", "namespace that owns the shim")
|
||||
flag.StringVar(&idFlag, "id", "", "id of the task")
|
||||
flag.StringVar(&socketFlag, "socket", "", "abstract socket path to serve")
|
||||
@ -155,6 +158,15 @@ func Run(id string, initFunc Init, opts ...BinaryOpts) {
|
||||
|
||||
func run(id string, initFunc Init, config Config) error {
|
||||
parseFlags()
|
||||
if versionFlag {
|
||||
fmt.Printf("%s:\n", os.Args[0])
|
||||
fmt.Println(" Version: ", version.Version)
|
||||
fmt.Println(" Revision:", version.Revision)
|
||||
fmt.Println(" Go version:", version.GoVersion)
|
||||
fmt.Println("")
|
||||
return nil
|
||||
}
|
||||
|
||||
setRuntime()
|
||||
|
||||
signals, err := setupSignals(config)
|
||||
|
4
vendor/github.com/containerd/containerd/runtime/v2/shim/shim_linux.go
generated
vendored
4
vendor/github.com/containerd/containerd/runtime/v2/shim/shim_linux.go
generated
vendored
@ -17,7 +17,7 @@
|
||||
package shim
|
||||
|
||||
import (
|
||||
"github.com/containerd/containerd/sys"
|
||||
"github.com/containerd/containerd/sys/reaper"
|
||||
"github.com/containerd/ttrpc"
|
||||
)
|
||||
|
||||
@ -26,5 +26,5 @@ func newServer() (*ttrpc.Server, error) {
|
||||
}
|
||||
|
||||
func subreaper() error {
|
||||
return sys.SetSubreaper(1)
|
||||
return reaper.SetSubreaper(1)
|
||||
}
|
||||
|
6
vendor/github.com/containerd/containerd/signals_unix.go
generated
vendored
6
vendor/github.com/containerd/containerd/signals_unix.go
generated
vendored
@ -33,11 +33,7 @@ import (
|
||||
func ParseSignal(rawSignal string) (syscall.Signal, error) {
|
||||
s, err := strconv.Atoi(rawSignal)
|
||||
if err == nil {
|
||||
signal := syscall.Signal(s)
|
||||
if unix.SignalName(signal) != "" {
|
||||
return signal, nil
|
||||
}
|
||||
return -1, fmt.Errorf("unknown signal %q", rawSignal)
|
||||
return syscall.Signal(s), nil
|
||||
}
|
||||
signal := unix.SignalNum(strings.ToUpper(rawSignal))
|
||||
if signal == 0 {
|
||||
|
11
vendor/github.com/containerd/containerd/snapshots/snapshotter.go
generated
vendored
11
vendor/github.com/containerd/containerd/snapshots/snapshotter.go
generated
vendored
@ -355,10 +355,17 @@ type Cleaner interface {
|
||||
// Opt allows setting mutable snapshot properties on creation
|
||||
type Opt func(info *Info) error
|
||||
|
||||
// WithLabels adds labels to a created snapshot
|
||||
// WithLabels appends labels to a created snapshot
|
||||
func WithLabels(labels map[string]string) Opt {
|
||||
return func(info *Info) error {
|
||||
info.Labels = labels
|
||||
if info.Labels == nil {
|
||||
info.Labels = make(map[string]string)
|
||||
}
|
||||
|
||||
for k, v := range labels {
|
||||
info.Labels[k] = v
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
21
vendor/github.com/containerd/containerd/sys/epoll.go
generated
vendored
21
vendor/github.com/containerd/containerd/sys/epoll.go
generated
vendored
@ -20,17 +20,14 @@ package sys
|
||||
|
||||
import "golang.org/x/sys/unix"
|
||||
|
||||
// EpollCreate1 directly calls unix.EpollCreate1
|
||||
func EpollCreate1(flag int) (int, error) {
|
||||
return unix.EpollCreate1(flag)
|
||||
}
|
||||
// EpollCreate1 is an alias for unix.EpollCreate1
|
||||
// Deprecated: use golang.org/x/sys/unix.EpollCreate1
|
||||
var EpollCreate1 = unix.EpollCreate1
|
||||
|
||||
// EpollCtl directly calls unix.EpollCtl
|
||||
func EpollCtl(epfd int, op int, fd int, event *unix.EpollEvent) error {
|
||||
return unix.EpollCtl(epfd, op, fd, event)
|
||||
}
|
||||
// EpollCtl is an alias for unix.EpollCtl
|
||||
// Deprecated: use golang.org/x/sys/unix.EpollCtl
|
||||
var EpollCtl = unix.EpollCtl
|
||||
|
||||
// EpollWait directly calls unix.EpollWait
|
||||
func EpollWait(epfd int, events []unix.EpollEvent, msec int) (int, error) {
|
||||
return unix.EpollWait(epfd, events, msec)
|
||||
}
|
||||
// EpollWait is an alias for unix.EpollWait
|
||||
// Deprecated: use golang.org/x/sys/unix.EpollWait
|
||||
var EpollWait = unix.EpollWait
|
||||
|
35
vendor/github.com/containerd/containerd/sys/filesys.go
generated
vendored
Normal file
35
vendor/github.com/containerd/containerd/sys/filesys.go
generated
vendored
Normal file
@ -0,0 +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 sys
|
||||
|
||||
import "os"
|
||||
|
||||
// IsFifo checks if a file is a (named pipe) fifo
|
||||
// if the file does not exist then it returns false
|
||||
func IsFifo(path string) (bool, error) {
|
||||
stat, err := os.Stat(path)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return false, nil
|
||||
}
|
||||
return false, err
|
||||
}
|
||||
if stat.Mode()&os.ModeNamedPipe == os.ModeNamedPipe {
|
||||
return true, nil
|
||||
}
|
||||
return false, nil
|
||||
}
|
89
vendor/github.com/containerd/containerd/sys/filesys_windows.go
generated
vendored
89
vendor/github.com/containerd/containerd/sys/filesys_windows.go
generated
vendored
@ -26,8 +26,8 @@ import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
winio "github.com/Microsoft/go-winio"
|
||||
"github.com/Microsoft/hcsshim"
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -41,7 +41,8 @@ func MkdirAllWithACL(path string, perm os.FileMode) error {
|
||||
return mkdirall(path, true)
|
||||
}
|
||||
|
||||
// MkdirAll implementation that is volume path aware for Windows.
|
||||
// MkdirAll implementation that is volume path aware for Windows. It can be used
|
||||
// as a drop-in replacement for os.MkdirAll()
|
||||
func MkdirAll(path string, _ os.FileMode) error {
|
||||
return mkdirall(path, false)
|
||||
}
|
||||
@ -111,26 +112,26 @@ func mkdirall(path string, adminAndLocalSystem bool) error {
|
||||
// mkdirWithACL creates a new directory. If there is an error, it will be of
|
||||
// type *PathError. .
|
||||
//
|
||||
// This is a modified and combined version of os.Mkdir and syscall.Mkdir
|
||||
// This is a modified and combined version of os.Mkdir and windows.Mkdir
|
||||
// in golang to cater for creating a directory am ACL permitting full
|
||||
// access, with inheritance, to any subfolder/file for Built-in Administrators
|
||||
// and Local System.
|
||||
func mkdirWithACL(name string) error {
|
||||
sa := syscall.SecurityAttributes{Length: 0}
|
||||
sd, err := winio.SddlToSecurityDescriptor(SddlAdministratorsLocalSystem)
|
||||
sa := windows.SecurityAttributes{Length: 0}
|
||||
sd, err := windows.SecurityDescriptorFromString(SddlAdministratorsLocalSystem)
|
||||
if err != nil {
|
||||
return &os.PathError{Op: "mkdir", Path: name, Err: err}
|
||||
}
|
||||
sa.Length = uint32(unsafe.Sizeof(sa))
|
||||
sa.InheritHandle = 1
|
||||
sa.SecurityDescriptor = uintptr(unsafe.Pointer(&sd[0]))
|
||||
sa.SecurityDescriptor = sd
|
||||
|
||||
namep, err := syscall.UTF16PtrFromString(name)
|
||||
namep, err := windows.UTF16PtrFromString(name)
|
||||
if err != nil {
|
||||
return &os.PathError{Op: "mkdir", Path: name, Err: err}
|
||||
}
|
||||
|
||||
e := syscall.CreateDirectory(namep, &sa)
|
||||
e := windows.CreateDirectory(namep, &sa)
|
||||
if e != nil {
|
||||
return &os.PathError{Op: "mkdir", Path: name, Err: e}
|
||||
}
|
||||
@ -153,7 +154,7 @@ func IsAbs(path string) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// The origin of the functions below here are the golang OS and syscall packages,
|
||||
// The origin of the functions below here are the golang OS and windows packages,
|
||||
// slightly modified to only cope with files, not directories due to the
|
||||
// specific use case.
|
||||
//
|
||||
@ -185,74 +186,74 @@ func OpenFileSequential(name string, flag int, _ os.FileMode) (*os.File, error)
|
||||
if name == "" {
|
||||
return nil, &os.PathError{Op: "open", Path: name, Err: syscall.ENOENT}
|
||||
}
|
||||
r, errf := syscallOpenFileSequential(name, flag, 0)
|
||||
r, errf := windowsOpenFileSequential(name, flag, 0)
|
||||
if errf == nil {
|
||||
return r, nil
|
||||
}
|
||||
return nil, &os.PathError{Op: "open", Path: name, Err: errf}
|
||||
}
|
||||
|
||||
func syscallOpenFileSequential(name string, flag int, _ os.FileMode) (file *os.File, err error) {
|
||||
r, e := syscallOpenSequential(name, flag|syscall.O_CLOEXEC, 0)
|
||||
func windowsOpenFileSequential(name string, flag int, _ os.FileMode) (file *os.File, err error) {
|
||||
r, e := windowsOpenSequential(name, flag|windows.O_CLOEXEC, 0)
|
||||
if e != nil {
|
||||
return nil, e
|
||||
}
|
||||
return os.NewFile(uintptr(r), name), nil
|
||||
}
|
||||
|
||||
func makeInheritSa() *syscall.SecurityAttributes {
|
||||
var sa syscall.SecurityAttributes
|
||||
func makeInheritSa() *windows.SecurityAttributes {
|
||||
var sa windows.SecurityAttributes
|
||||
sa.Length = uint32(unsafe.Sizeof(sa))
|
||||
sa.InheritHandle = 1
|
||||
return &sa
|
||||
}
|
||||
|
||||
func syscallOpenSequential(path string, mode int, _ uint32) (fd syscall.Handle, err error) {
|
||||
func windowsOpenSequential(path string, mode int, _ uint32) (fd windows.Handle, err error) {
|
||||
if len(path) == 0 {
|
||||
return syscall.InvalidHandle, syscall.ERROR_FILE_NOT_FOUND
|
||||
return windows.InvalidHandle, windows.ERROR_FILE_NOT_FOUND
|
||||
}
|
||||
pathp, err := syscall.UTF16PtrFromString(path)
|
||||
pathp, err := windows.UTF16PtrFromString(path)
|
||||
if err != nil {
|
||||
return syscall.InvalidHandle, err
|
||||
return windows.InvalidHandle, err
|
||||
}
|
||||
var access uint32
|
||||
switch mode & (syscall.O_RDONLY | syscall.O_WRONLY | syscall.O_RDWR) {
|
||||
case syscall.O_RDONLY:
|
||||
access = syscall.GENERIC_READ
|
||||
case syscall.O_WRONLY:
|
||||
access = syscall.GENERIC_WRITE
|
||||
case syscall.O_RDWR:
|
||||
access = syscall.GENERIC_READ | syscall.GENERIC_WRITE
|
||||
switch mode & (windows.O_RDONLY | windows.O_WRONLY | windows.O_RDWR) {
|
||||
case windows.O_RDONLY:
|
||||
access = windows.GENERIC_READ
|
||||
case windows.O_WRONLY:
|
||||
access = windows.GENERIC_WRITE
|
||||
case windows.O_RDWR:
|
||||
access = windows.GENERIC_READ | windows.GENERIC_WRITE
|
||||
}
|
||||
if mode&syscall.O_CREAT != 0 {
|
||||
access |= syscall.GENERIC_WRITE
|
||||
if mode&windows.O_CREAT != 0 {
|
||||
access |= windows.GENERIC_WRITE
|
||||
}
|
||||
if mode&syscall.O_APPEND != 0 {
|
||||
access &^= syscall.GENERIC_WRITE
|
||||
access |= syscall.FILE_APPEND_DATA
|
||||
if mode&windows.O_APPEND != 0 {
|
||||
access &^= windows.GENERIC_WRITE
|
||||
access |= windows.FILE_APPEND_DATA
|
||||
}
|
||||
sharemode := uint32(syscall.FILE_SHARE_READ | syscall.FILE_SHARE_WRITE)
|
||||
var sa *syscall.SecurityAttributes
|
||||
if mode&syscall.O_CLOEXEC == 0 {
|
||||
sharemode := uint32(windows.FILE_SHARE_READ | windows.FILE_SHARE_WRITE)
|
||||
var sa *windows.SecurityAttributes
|
||||
if mode&windows.O_CLOEXEC == 0 {
|
||||
sa = makeInheritSa()
|
||||
}
|
||||
var createmode uint32
|
||||
switch {
|
||||
case mode&(syscall.O_CREAT|syscall.O_EXCL) == (syscall.O_CREAT | syscall.O_EXCL):
|
||||
createmode = syscall.CREATE_NEW
|
||||
case mode&(syscall.O_CREAT|syscall.O_TRUNC) == (syscall.O_CREAT | syscall.O_TRUNC):
|
||||
createmode = syscall.CREATE_ALWAYS
|
||||
case mode&syscall.O_CREAT == syscall.O_CREAT:
|
||||
createmode = syscall.OPEN_ALWAYS
|
||||
case mode&syscall.O_TRUNC == syscall.O_TRUNC:
|
||||
createmode = syscall.TRUNCATE_EXISTING
|
||||
case mode&(windows.O_CREAT|windows.O_EXCL) == (windows.O_CREAT | windows.O_EXCL):
|
||||
createmode = windows.CREATE_NEW
|
||||
case mode&(windows.O_CREAT|windows.O_TRUNC) == (windows.O_CREAT | windows.O_TRUNC):
|
||||
createmode = windows.CREATE_ALWAYS
|
||||
case mode&windows.O_CREAT == windows.O_CREAT:
|
||||
createmode = windows.OPEN_ALWAYS
|
||||
case mode&windows.O_TRUNC == windows.O_TRUNC:
|
||||
createmode = windows.TRUNCATE_EXISTING
|
||||
default:
|
||||
createmode = syscall.OPEN_EXISTING
|
||||
createmode = windows.OPEN_EXISTING
|
||||
}
|
||||
// Use FILE_FLAG_SEQUENTIAL_SCAN rather than FILE_ATTRIBUTE_NORMAL as implemented in golang.
|
||||
//https://msdn.microsoft.com/en-us/library/windows/desktop/aa363858(v=vs.85).aspx
|
||||
// https://msdn.microsoft.com/en-us/library/windows/desktop/aa363858(v=vs.85).aspx
|
||||
const fileFlagSequentialScan = 0x08000000 // FILE_FLAG_SEQUENTIAL_SCAN
|
||||
h, e := syscall.CreateFile(pathp, access, sharemode, sa, createmode, fileFlagSequentialScan, 0)
|
||||
h, e := windows.CreateFile(pathp, access, sharemode, sa, createmode, fileFlagSequentialScan, 0)
|
||||
return h, e
|
||||
}
|
||||
|
||||
|
52
vendor/github.com/containerd/containerd/sys/mount_linux.go
generated
vendored
52
vendor/github.com/containerd/containerd/sys/mount_linux.go
generated
vendored
@ -21,6 +21,7 @@ import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"github.com/containerd/containerd/log"
|
||||
"github.com/pkg/errors"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
@ -30,9 +31,8 @@ func FMountat(dirfd uintptr, source, target, fstype string, flags uintptr, data
|
||||
var (
|
||||
sourceP, targetP, fstypeP, dataP *byte
|
||||
pid uintptr
|
||||
ws unix.WaitStatus
|
||||
err error
|
||||
errno syscall.Errno
|
||||
errno, status syscall.Errno
|
||||
)
|
||||
|
||||
sourceP, err = syscall.BytePtrFromString(source)
|
||||
@ -60,37 +60,62 @@ func FMountat(dirfd uintptr, source, target, fstype string, flags uintptr, data
|
||||
runtime.LockOSThread()
|
||||
defer runtime.UnlockOSThread()
|
||||
|
||||
var pipefds [2]int
|
||||
if err := syscall.Pipe2(pipefds[:], syscall.O_CLOEXEC); err != nil {
|
||||
return errors.Wrap(err, "failed to open pipe")
|
||||
}
|
||||
|
||||
defer func() {
|
||||
// close both ends of the pipe in a deferred function, since open file
|
||||
// descriptor table is shared with child
|
||||
syscall.Close(pipefds[0])
|
||||
syscall.Close(pipefds[1])
|
||||
}()
|
||||
|
||||
pid, errno = forkAndMountat(dirfd,
|
||||
uintptr(unsafe.Pointer(sourceP)),
|
||||
uintptr(unsafe.Pointer(targetP)),
|
||||
uintptr(unsafe.Pointer(fstypeP)),
|
||||
flags,
|
||||
uintptr(unsafe.Pointer(dataP)))
|
||||
uintptr(unsafe.Pointer(dataP)),
|
||||
pipefds[1],
|
||||
)
|
||||
|
||||
if errno != 0 {
|
||||
return errors.Wrap(errno, "failed to fork thread")
|
||||
}
|
||||
|
||||
_, err = unix.Wait4(int(pid), &ws, 0, nil)
|
||||
for err == syscall.EINTR {
|
||||
_, err = unix.Wait4(int(pid), &ws, 0, nil)
|
||||
}
|
||||
defer func() {
|
||||
_, err := unix.Wait4(int(pid), nil, 0, nil)
|
||||
for err == syscall.EINTR {
|
||||
_, err = unix.Wait4(int(pid), nil, 0, nil)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to find pid=%d process", pid)
|
||||
}
|
||||
if err != nil {
|
||||
log.L.WithError(err).Debugf("failed to find pid=%d process", pid)
|
||||
}
|
||||
}()
|
||||
|
||||
errno = syscall.Errno(ws.ExitStatus())
|
||||
_, _, errno = syscall.RawSyscall(syscall.SYS_READ,
|
||||
uintptr(pipefds[0]),
|
||||
uintptr(unsafe.Pointer(&status)),
|
||||
unsafe.Sizeof(status))
|
||||
if errno != 0 {
|
||||
return errors.Wrap(errno, "failed to mount")
|
||||
return errors.Wrap(errno, "failed to read pipe")
|
||||
}
|
||||
|
||||
if status != 0 {
|
||||
return errors.Wrap(status, "failed to mount")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// forkAndMountat will fork thread, change working dir and mount.
|
||||
//
|
||||
// precondition: the runtime OS thread must be locked.
|
||||
func forkAndMountat(dirfd uintptr, source, target, fstype, flags, data uintptr) (pid uintptr, errno syscall.Errno) {
|
||||
func forkAndMountat(dirfd uintptr, source, target, fstype, flags, data uintptr, pipefd int) (pid uintptr, errno syscall.Errno) {
|
||||
|
||||
// block signal during clone
|
||||
beforeFork()
|
||||
|
||||
@ -114,6 +139,7 @@ func forkAndMountat(dirfd uintptr, source, target, fstype, flags, data uintptr)
|
||||
_, _, errno = syscall.RawSyscall6(syscall.SYS_MOUNT, source, target, fstype, flags, data, 0)
|
||||
|
||||
childerr:
|
||||
_, _, errno = syscall.RawSyscall(syscall.SYS_WRITE, uintptr(pipefd), uintptr(unsafe.Pointer(&errno)), unsafe.Sizeof(errno))
|
||||
syscall.RawSyscall(syscall.SYS_EXIT, uintptr(errno), 0, 0)
|
||||
panic("unreachable")
|
||||
}
|
||||
|
4
vendor/github.com/containerd/containerd/sys/oom_unix.go
generated
vendored
4
vendor/github.com/containerd/containerd/sys/oom_unix.go
generated
vendored
@ -24,8 +24,6 @@ import (
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/opencontainers/runc/libcontainer/system"
|
||||
)
|
||||
|
||||
// OOMScoreMaxKillable is the maximum score keeping the process killable by the oom killer
|
||||
@ -40,7 +38,7 @@ func SetOOMScore(pid, score int) error {
|
||||
}
|
||||
defer f.Close()
|
||||
if _, err = f.WriteString(strconv.Itoa(score)); err != nil {
|
||||
if os.IsPermission(err) && (system.RunningInUserNS() || RunningUnprivileged()) {
|
||||
if os.IsPermission(err) && (RunningInUserNS() || RunningUnprivileged()) {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
|
80
vendor/github.com/containerd/containerd/sys/proc.go
generated
vendored
80
vendor/github.com/containerd/containerd/sys/proc.go
generated
vendored
@ -1,80 +0,0 @@
|
||||
// +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 (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/opencontainers/runc/libcontainer/system"
|
||||
)
|
||||
|
||||
const nanoSecondsPerSecond = 1e9
|
||||
|
||||
var clockTicksPerSecond = uint64(system.GetClockTicks())
|
||||
|
||||
// GetSystemCPUUsage returns the host system's cpu usage in
|
||||
// nanoseconds. An error is returned if the format of the underlying
|
||||
// file does not match.
|
||||
//
|
||||
// Uses /proc/stat defined by POSIX. Looks for the cpu
|
||||
// statistics line and then sums up the first seven fields
|
||||
// provided. See `man 5 proc` for details on specific field
|
||||
// information.
|
||||
func GetSystemCPUUsage() (uint64, error) {
|
||||
var line string
|
||||
f, err := os.Open("/proc/stat")
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
bufReader := bufio.NewReaderSize(nil, 128)
|
||||
defer func() {
|
||||
bufReader.Reset(nil)
|
||||
f.Close()
|
||||
}()
|
||||
bufReader.Reset(f)
|
||||
err = nil
|
||||
for err == nil {
|
||||
line, err = bufReader.ReadString('\n')
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
parts := strings.Fields(line)
|
||||
switch parts[0] {
|
||||
case "cpu":
|
||||
if len(parts) < 8 {
|
||||
return 0, fmt.Errorf("bad format of cpu stats")
|
||||
}
|
||||
var totalClockTicks uint64
|
||||
for _, i := range parts[1:8] {
|
||||
v, err := strconv.ParseUint(i, 10, 64)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("error parsing cpu stats")
|
||||
}
|
||||
totalClockTicks += v
|
||||
}
|
||||
return (totalClockTicks * nanoSecondsPerSecond) /
|
||||
clockTicksPerSecond, nil
|
||||
}
|
||||
}
|
||||
return 0, fmt.Errorf("bad stats format")
|
||||
}
|
69
vendor/github.com/containerd/containerd/sys/reaper.go
generated
vendored
69
vendor/github.com/containerd/containerd/sys/reaper.go
generated
vendored
@ -1,69 +0,0 @@
|
||||
// +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"
|
||||
)
|
||||
|
||||
// Exit is the wait4 information from an exited process
|
||||
type Exit struct {
|
||||
Pid int
|
||||
Status int
|
||||
}
|
||||
|
||||
// Reap reaps all child processes for the calling process and returns their
|
||||
// exit information
|
||||
func Reap(wait bool) (exits []Exit, err error) {
|
||||
var (
|
||||
ws unix.WaitStatus
|
||||
rus unix.Rusage
|
||||
)
|
||||
flag := unix.WNOHANG
|
||||
if wait {
|
||||
flag = 0
|
||||
}
|
||||
for {
|
||||
pid, err := unix.Wait4(-1, &ws, flag, &rus)
|
||||
if err != nil {
|
||||
if err == unix.ECHILD {
|
||||
return exits, nil
|
||||
}
|
||||
return exits, err
|
||||
}
|
||||
if pid <= 0 {
|
||||
return exits, nil
|
||||
}
|
||||
exits = append(exits, Exit{
|
||||
Pid: pid,
|
||||
Status: exitStatus(ws),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const exitSignalOffset = 128
|
||||
|
||||
// exitStatus returns the correct exit status for a process based on if it
|
||||
// was signaled or exited cleanly
|
||||
func exitStatus(status unix.WaitStatus) int {
|
||||
if status.Signaled() {
|
||||
return exitSignalOffset + int(status.Signal())
|
||||
}
|
||||
return status.ExitStatus()
|
||||
}
|
50
vendor/github.com/containerd/containerd/sys/reaper/reaper_unix.go
generated
vendored
50
vendor/github.com/containerd/containerd/sys/reaper/reaper_unix.go
generated
vendored
@ -23,9 +23,9 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/containerd/containerd/sys"
|
||||
runc "github.com/containerd/go-runc"
|
||||
"github.com/pkg/errors"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
// ErrNoSuchProcess is returned when the process no longer exists
|
||||
@ -60,7 +60,7 @@ func (s *subscriber) do(fn func()) {
|
||||
// all exited processes and close their wait channels
|
||||
func Reap() error {
|
||||
now := time.Now()
|
||||
exits, err := sys.Reap(false)
|
||||
exits, err := reap(false)
|
||||
for _, e := range exits {
|
||||
done := Default.notify(runc.Exit{
|
||||
Timestamp: now,
|
||||
@ -200,3 +200,49 @@ func stop(timer *time.Timer, recv bool) {
|
||||
<-timer.C
|
||||
}
|
||||
}
|
||||
|
||||
// exit is the wait4 information from an exited process
|
||||
type exit struct {
|
||||
Pid int
|
||||
Status int
|
||||
}
|
||||
|
||||
// reap reaps all child processes for the calling process and returns their
|
||||
// exit information
|
||||
func reap(wait bool) (exits []exit, err error) {
|
||||
var (
|
||||
ws unix.WaitStatus
|
||||
rus unix.Rusage
|
||||
)
|
||||
flag := unix.WNOHANG
|
||||
if wait {
|
||||
flag = 0
|
||||
}
|
||||
for {
|
||||
pid, err := unix.Wait4(-1, &ws, flag, &rus)
|
||||
if err != nil {
|
||||
if err == unix.ECHILD {
|
||||
return exits, nil
|
||||
}
|
||||
return exits, err
|
||||
}
|
||||
if pid <= 0 {
|
||||
return exits, nil
|
||||
}
|
||||
exits = append(exits, exit{
|
||||
Pid: pid,
|
||||
Status: exitStatus(ws),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const exitSignalOffset = 128
|
||||
|
||||
// exitStatus returns the correct exit status for a process based on if it
|
||||
// was signaled or exited cleanly
|
||||
func exitStatus(status unix.WaitStatus) int {
|
||||
if status.Signaled() {
|
||||
return exitSignalOffset + int(status.Signal())
|
||||
}
|
||||
return status.ExitStatus()
|
||||
}
|
||||
|
@ -14,7 +14,7 @@
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package sys
|
||||
package reaper
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
@ -22,22 +22,9 @@ import (
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
// 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.
|
||||
const setChildSubreaper = 36
|
||||
|
||||
// SetSubreaper sets the value i as the subreaper setting for the calling process
|
||||
func SetSubreaper(i int) error {
|
||||
return unix.Prctl(setChildSubreaper, uintptr(i), 0, 0, 0)
|
||||
return unix.Prctl(unix.PR_SET_CHILD_SUBREAPER, uintptr(i), 0, 0, 0)
|
||||
}
|
||||
|
||||
// GetSubreaper returns the subreaper setting for the calling process
|
62
vendor/github.com/containerd/containerd/sys/userns_linux.go
generated
vendored
Normal file
62
vendor/github.com/containerd/containerd/sys/userns_linux.go
generated
vendored
Normal file
@ -0,0 +1,62 @@
|
||||
/*
|
||||
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 (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"os"
|
||||
"sync"
|
||||
)
|
||||
|
||||
var (
|
||||
inUserNS bool
|
||||
nsOnce sync.Once
|
||||
)
|
||||
|
||||
// RunningInUserNS detects whether we are currently running in a user namespace.
|
||||
// Originally copied from github.com/lxc/lxd/shared/util.go
|
||||
func RunningInUserNS() bool {
|
||||
nsOnce.Do(func() {
|
||||
file, err := os.Open("/proc/self/uid_map")
|
||||
if err != nil {
|
||||
// This kernel-provided file only exists if user namespaces are supported
|
||||
return
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
buf := bufio.NewReader(file)
|
||||
l, _, err := buf.ReadLine()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
line := string(l)
|
||||
var a, b, c int64
|
||||
fmt.Sscanf(line, "%d %d %d", &a, &b, &c)
|
||||
|
||||
/*
|
||||
* We assume we are in the initial user namespace if we have a full
|
||||
* range - 4294967295 uids starting at uid 0.
|
||||
*/
|
||||
if a == 0 && b == 0 && c == 4294967295 {
|
||||
return
|
||||
}
|
||||
inUserNS = true
|
||||
})
|
||||
return inUserNS
|
||||
}
|
25
vendor/github.com/containerd/containerd/sys/userns_unsupported.go
generated
vendored
Normal file
25
vendor/github.com/containerd/containerd/sys/userns_unsupported.go
generated
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
// +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
|
||||
|
||||
// RunningInUserNS is a stub for non-Linux systems
|
||||
// Always returns false
|
||||
func RunningInUserNS() bool {
|
||||
return false
|
||||
}
|
22
vendor/github.com/containerd/containerd/unpacker.go
generated
vendored
22
vendor/github.com/containerd/containerd/unpacker.go
generated
vendored
@ -72,7 +72,13 @@ func (c *Client) newUnpacker(ctx context.Context, rCtx *RemoteContext) (*unpacke
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (u *unpacker) unpack(ctx context.Context, h images.Handler, config ocispec.Descriptor, layers []ocispec.Descriptor) error {
|
||||
func (u *unpacker) unpack(
|
||||
ctx context.Context,
|
||||
rCtx *RemoteContext,
|
||||
h images.Handler,
|
||||
config ocispec.Descriptor,
|
||||
layers []ocispec.Descriptor,
|
||||
) error {
|
||||
p, err := content.ReadBlob(ctx, u.c.ContentStore(), config)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -123,17 +129,17 @@ EachLayer:
|
||||
labels = make(map[string]string)
|
||||
}
|
||||
labels[labelSnapshotRef] = chainID
|
||||
labelOpt := snapshots.WithLabels(labels)
|
||||
|
||||
var (
|
||||
key string
|
||||
mounts []mount.Mount
|
||||
opts = append(rCtx.SnapshotterOpts, snapshots.WithLabels(labels))
|
||||
)
|
||||
|
||||
for try := 1; try <= 3; try++ {
|
||||
// Prepare snapshot with from parent, label as root
|
||||
key = fmt.Sprintf("extract-%s %s", uniquePart(), chainID)
|
||||
mounts, err = sn.Prepare(ctx, key, parent.String(), labelOpt)
|
||||
mounts, err = sn.Prepare(ctx, key, parent.String(), opts...)
|
||||
if err != nil {
|
||||
if errdefs.IsAlreadyExists(err) {
|
||||
if _, err := sn.Stat(ctx, chainID); err != nil {
|
||||
@ -201,7 +207,7 @@ EachLayer:
|
||||
return errors.Errorf("wrong diff id calculated on extraction %q", diffIDs[i])
|
||||
}
|
||||
|
||||
if err = sn.Commit(ctx, chainID, key, labelOpt); err != nil {
|
||||
if err = sn.Commit(ctx, chainID, key, opts...); err != nil {
|
||||
abort()
|
||||
if errdefs.IsAlreadyExists(err) {
|
||||
continue
|
||||
@ -271,7 +277,11 @@ func (u *unpacker) fetch(ctx context.Context, h images.Handler, layers []ocispec
|
||||
return eg.Wait()
|
||||
}
|
||||
|
||||
func (u *unpacker) handlerWrapper(uctx context.Context, unpacks *int32) (func(images.Handler) images.Handler, *errgroup.Group) {
|
||||
func (u *unpacker) handlerWrapper(
|
||||
uctx context.Context,
|
||||
rCtx *RemoteContext,
|
||||
unpacks *int32,
|
||||
) (func(images.Handler) images.Handler, *errgroup.Group) {
|
||||
eg, uctx := errgroup.WithContext(uctx)
|
||||
return func(f images.Handler) images.Handler {
|
||||
var (
|
||||
@ -313,7 +323,7 @@ func (u *unpacker) handlerWrapper(uctx context.Context, unpacks *int32) (func(im
|
||||
if len(l) > 0 {
|
||||
atomic.AddInt32(unpacks, 1)
|
||||
eg.Go(func() error {
|
||||
return u.unpack(uctx, f, desc, l)
|
||||
return u.unpack(uctx, rCtx, f, desc, l)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
70
vendor/github.com/containerd/containerd/vendor.conf
generated
vendored
70
vendor/github.com/containerd/containerd/vendor.conf
generated
vendored
@ -2,16 +2,16 @@ github.com/beorn7/perks 37c8de3658fcb183f997c4e13e83
|
||||
github.com/BurntSushi/toml 3012a1dbe2e4bd1391d42b32f0577cb7bbc7f005 # v0.3.1
|
||||
github.com/cespare/xxhash/v2 d7df74196a9e781ede915320c11c378c1b2f3a1f # v2.1.1
|
||||
github.com/containerd/btrfs 153935315f4ab9be5bf03650a1341454b05efa5d
|
||||
github.com/containerd/cgroups 7347743e5d1e8500d9f27c8e748e689ed991d92b
|
||||
github.com/containerd/console 8375c3424e4d7b114e8a90a4a40c8e1b40d1d4e6
|
||||
github.com/containerd/cgroups b4448137398923af7f4918b8b2ad8249172ca7a6
|
||||
github.com/containerd/console 8375c3424e4d7b114e8a90a4a40c8e1b40d1d4e6 # v1.0.0
|
||||
github.com/containerd/continuity 0ec596719c75bfd42908850990acea594b7593ac
|
||||
github.com/containerd/fifo bda0ff6ed73c67bfb5e62bc9c697f146b7fd7f13
|
||||
github.com/containerd/go-runc a5c2862aed5e6358b305b0e16bfce58e0549b1cd
|
||||
github.com/containerd/ttrpc 92c8520ef9f86600c650dd540266a007bf03670f
|
||||
github.com/containerd/typeurl a93fcdb778cd272c6e9b3028b2f42d813e785d40
|
||||
github.com/containerd/ttrpc 72bb1b21c5b0a4a107f59dd85f6ab58e564b68d6 # v1.0.1
|
||||
github.com/containerd/typeurl cd3ce7159eae562a4f60ceff37dada11a939d247 # v1.0.1
|
||||
github.com/coreos/go-systemd/v22 2d78030078ef61b3cae27f42ad6d0e46db51b339 # v22.0.0
|
||||
github.com/cpuguy83/go-md2man 7762f7e404f8416dfa1d9bb6a8c192aa9acb4d19 # v1.0.10
|
||||
github.com/docker/go-events 9461782956ad83b30282bf90e31fa6a70c255ba9
|
||||
github.com/docker/go-events e31b211e4f1cd09aa76fe4ac244571fab96ae47f
|
||||
github.com/docker/go-metrics b619b3592b65de4f087d9f16863a7e6ff905973c # v0.0.1
|
||||
github.com/docker/go-units 519db1ee28dcc9fd2474ae59fca29a810482bfb1 # v0.4.0
|
||||
github.com/godbus/dbus/v5 37bf87eef99d69c4f1d3528bd66e3a87dc201472 # v5.0.3
|
||||
@ -25,65 +25,78 @@ github.com/hashicorp/errwrap 8a6fb523712970c966eefc6b39ed
|
||||
github.com/hashicorp/go-multierror 886a7fbe3eb1c874d46f623bfa70af45f425b3d1 # v1.0.0
|
||||
github.com/hashicorp/golang-lru 7f827b33c0f158ec5dfbba01bb0b14a4541fd81d # v0.5.3
|
||||
github.com/imdario/mergo 7c29201646fa3de8506f701213473dd407f19646 # v0.3.7
|
||||
github.com/konsorten/go-windows-terminal-sequences 5c8c8bd35d3832f5d134ae1e1e375b69a4d25242 # v1.0.1
|
||||
github.com/konsorten/go-windows-terminal-sequences edb144dfd453055e1e49a3d8b410a660b5a87613 # v1.0.3
|
||||
github.com/matttproud/golang_protobuf_extensions c12348ce28de40eed0136aa2b644d0ee0650e56c # v1.0.1
|
||||
github.com/Microsoft/go-winio 6c72808b55902eae4c5943626030429ff20f3b63 # v0.4.14
|
||||
github.com/Microsoft/hcsshim 0b571ac85d7c5842b26d2571de4868634a4c39d7 # v0.8.7-24-g0b571ac8
|
||||
github.com/Microsoft/hcsshim 5bc557dd210ff2caf615e6e22d398123de77fc11 # v0.8.9
|
||||
github.com/opencontainers/go-digest c9281466c8b2f606084ac71339773efd177436e7
|
||||
github.com/opencontainers/image-spec d60099175f88c47cd379c4738d158884749ed235 # v1.0.1
|
||||
github.com/opencontainers/runc dc9208a3303feef5b3839f4323d9beb36df0a9dd # v1.0.0-rc10
|
||||
github.com/opencontainers/runtime-spec 29686dbc5559d93fb1ef402eeda3e35c38d75af4 # v1.0.1-59-g29686db
|
||||
github.com/pkg/errors ba968bfe8b2f7e042a574c888954fccecfa385b4 # v0.8.1
|
||||
github.com/opencontainers/runtime-spec c4ee7d12c742ffe806cd9350b6af3b4b19faed6f # v1.0.2
|
||||
github.com/pkg/errors 614d223910a179a466c1767a985424175c39b465 # v0.9.1
|
||||
github.com/prometheus/client_golang c42bebe5a5cddfc6b28cd639103369d8a75dfa89 # v1.3.0
|
||||
github.com/prometheus/client_model d1d2010b5beead3fa1c5f271a5cf626e40b3ad6e # v0.1.0
|
||||
github.com/prometheus/common 287d3e634a1e550c9e463dd7e5a75a422c614505 # v0.7.0
|
||||
github.com/prometheus/procfs 6d489fc7f1d9cd890a250f3ea3431b1744b9623f # v0.0.8
|
||||
github.com/russross/blackfriday 05f3235734ad95d0016f6a23902f06461fcf567a # v1.5.2
|
||||
github.com/sirupsen/logrus 8bdbc7bcc01dcbb8ec23dc8a28e332258d25251f # v1.4.1
|
||||
github.com/sirupsen/logrus 60c74ad9be0d874af0ab0daef6ab07c5c5911f0d # v1.6.0
|
||||
github.com/syndtr/gocapability d98352740cb2c55f81556b63d4a1ec64c5a319c2
|
||||
github.com/urfave/cli bfe2e925cfb6d44b40ad3a779165ea7e8aff9212 # v1.22.0
|
||||
go.etcd.io/bbolt a0458a2b35708eef59eb5f620ceb3cd1c01a824d # v1.3.3
|
||||
go.opencensus.io 9c377598961b706d1542bd2d84d538b5094d596e # v0.22.0
|
||||
golang.org/x/net f3200d17e092c607f615320ecaad13d87ad9a2b3
|
||||
golang.org/x/sync 42b317875d0fa942474b76e1b46a6060d720ae6e
|
||||
golang.org/x/sys c990c680b611ac1aeb7d8f2af94a825f98d69720 https://github.com/golang/sys
|
||||
golang.org/x/sys 5c8b2ff67527cb88b770f693cebf3799036d8bc0
|
||||
golang.org/x/text 19e51611da83d6be54ddafce4a4af510cb3e9ea4
|
||||
google.golang.org/genproto e50cd9704f63023d62cd06a1994b98227fc4d21a
|
||||
google.golang.org/grpc f495f5b15ae7ccda3b38c53a1bfcde4c1a58a2bc # v1.27.1
|
||||
gotest.tools/v3 bb0d8a963040ea5048dcef1a14d8f8b58a33d4b3 # v3.0.2
|
||||
|
||||
# cgroups dependencies
|
||||
github.com/cilium/ebpf 4032b1d8aae306b7bb94a2a11002932caf88c644
|
||||
|
||||
# cri dependencies
|
||||
github.com/containerd/cri c0294ebfe0b4342db85c0faf7727ceb8d8c3afce # master
|
||||
github.com/containerd/go-cni 0d360c50b10b350b6bb23863fd4dfb1c232b01c9
|
||||
github.com/containernetworking/cni 4cfb7b568922a3c79a23e438dc52fe537fc9687e # v0.7.1
|
||||
github.com/containernetworking/plugins 9f96827c7cabb03f21d86326000c00f61e181f6a # v0.7.6
|
||||
github.com/containerd/cri 65830369b6b2b4edc454bf5cebbd9b76c1c1ac66 # master
|
||||
github.com/davecgh/go-spew 8991bc29aa16c548c550c7ff78260e27b9ab7c73 # v1.1.1
|
||||
github.com/docker/distribution 0d3efadf0154c2b8a4e7b6621fff9809655cc580
|
||||
github.com/docker/docker d1d5f6476656c6aad457e2a91d3436e66b6f2251
|
||||
github.com/docker/docker 4634ce647cf2ce2c6031129ccd109e557244986f
|
||||
github.com/docker/spdystream 449fdfce4d962303d702fec724ef0ad181c92528
|
||||
github.com/emicklei/go-restful b993709ae1a4f6dd19cfa475232614441b11c9d5 # v2.9.5
|
||||
github.com/google/gofuzz f140a6486e521aad38f5917de355cbf147cc0496 # v1.0.0
|
||||
github.com/google/gofuzz db92cf7ae75e4a7a28abc005addab2b394362888 # v1.1.0
|
||||
github.com/json-iterator/go 03217c3e97663914aec3faafde50d081f197a0a2 # v1.1.8
|
||||
github.com/modern-go/concurrent bacd9c7ef1dd9b15be4a9909b8ac7a4e313eec94 # 1.0.3
|
||||
github.com/modern-go/reflect2 4b7aa43c6742a2c18fdef89dd197aaae7dac7ccd # 1.0.1
|
||||
github.com/opencontainers/selinux 31f70552238c5e017d78c3f1ba65e85f593f48e0 # 1.3.3
|
||||
github.com/opencontainers/selinux 0d49ba2a6aae052c614dfe5de62a158711a6c461 # 1.5.1
|
||||
github.com/seccomp/libseccomp-golang 689e3c1541a84461afc49c1c87352a6cedf72e9c # v0.9.1
|
||||
github.com/stretchr/testify 221dbe5ed46703ee255b1da0dec05086f5035f62 # v1.4.0
|
||||
github.com/tchap/go-patricia 666120de432aea38ab06bd5c818f04f4129882c9 # v2.2.6
|
||||
golang.org/x/crypto 1d94cc7ab1c630336ab82ccb9c9cda72a875c382
|
||||
golang.org/x/crypto bac4c82f69751a6dd76e702d54b3ceb88adab236
|
||||
golang.org/x/oauth2 0f29369cfe4552d0e4bcddc57cc75f4d7e672a33
|
||||
golang.org/x/time 9d24e82272b4f38b78bc8cff74fa936d31ccd8ef
|
||||
gopkg.in/inf.v0 d2d2541c53f18d2a059457998ce2876cc8e67cbf # v0.9.1
|
||||
gopkg.in/yaml.v2 53403b58ad1b561927d19068c655246f2db79d48 # v2.2.8
|
||||
k8s.io/api 7643814f1c97f24ccfb38c2b85a7bb3c7f494346 # kubernetes-1.17.1
|
||||
k8s.io/apimachinery 79c2a76c473a20cdc4ce59cae4b72529b5d9d16b # kubernetes-1.17.1
|
||||
k8s.io/apiserver 5381f05fcb881d39af12eeecab5645364229300c # kubernetes-1.17.1
|
||||
k8s.io/client-go 69012f50f4b0243bccdb82c24402a10224a91f51 # kubernetes-1.17.1
|
||||
k8s.io/cri-api 775aa3c1cf7380ba8b7362f5a52f1e6d2e130bb9 # kubernetes-1.17.1
|
||||
k8s.io/api d2dce8e1788e4be2be3a62b6439b3eaa087df0df # v0.18.0
|
||||
k8s.io/apimachinery 105e0c6d63f10531ed07f3b5a2195771a0fa444b # v0.18.0
|
||||
k8s.io/apiserver 5c8e895629a454efd75a453d1dea5b8142db0013 # v0.18.0
|
||||
k8s.io/client-go 0b19784585bd0a0ee5509855829ead81feaa2bdc # v0.18.0
|
||||
k8s.io/cri-api 3d1680d8d202aa12c5dc5689170c3c03a488d35b # v0.18.0
|
||||
k8s.io/klog 2ca9ad30301bf30a8a6e0fa2110db6b8df699a91 # v1.0.0
|
||||
k8s.io/kubernetes d224476cd0730baca2b6e357d144171ed74192d6 # v1.17.1
|
||||
k8s.io/utils e782cd3c129fc98ee807f3c889c0f26eb7c9daf5
|
||||
sigs.k8s.io/yaml fd68e9863619f6ec2fdd8625fe1f02e7c877e480 # v1.1.0
|
||||
k8s.io/kubernetes 9e991415386e4cf155a24b1da15becaa390438d8 # v1.18.0
|
||||
k8s.io/utils a9aa75ae1b89e1b992c33383f48e942d97e52dae
|
||||
sigs.k8s.io/structured-merge-diff/v3 877aee05330847a873a1a8998b40e12a1e0fde25 # v3.0.0
|
||||
sigs.k8s.io/yaml 9fc95527decd95bb9d28cc2eab08179b2d0f6971 # v1.2.0
|
||||
|
||||
# cni dependencies
|
||||
github.com/containerd/go-cni 0d360c50b10b350b6bb23863fd4dfb1c232b01c9
|
||||
github.com/containernetworking/cni 4cfb7b568922a3c79a23e438dc52fe537fc9687e # v0.7.1
|
||||
github.com/containernetworking/plugins 9f96827c7cabb03f21d86326000c00f61e181f6a # v0.7.6
|
||||
github.com/fsnotify/fsnotify 4bf2d1fec78374803a39307bfb8d340688f4f28e # v1.4.8
|
||||
|
||||
# image decrypt depedencies
|
||||
github.com/containerd/imgcrypt 9e761ccd6069fb707ec9493435f31475b5524b38 # v1.0.1
|
||||
github.com/containers/ocicrypt 0343cc6053fd65069df55bce6838096e09b4033a # v1.0.1 from containerd/imgcrypt
|
||||
github.com/fullsailor/pkcs7 8306686428a5fe132eac8cb7c4848af725098bd4 # from containers/ocicrypt
|
||||
gopkg.in/square/go-jose.v2 730df5f748271903322feb182be83b43ebbbe27d # v2.3.1 from containers/ocicrypt
|
||||
|
||||
# zfs dependencies
|
||||
github.com/containerd/zfs 9abf673ca6ff9ab8d9bd776a4ceff8f6dc699c3d
|
||||
@ -91,6 +104,3 @@ github.com/mistifyio/go-zfs f784269be439d704d3dfa1906f45
|
||||
|
||||
# aufs dependencies
|
||||
github.com/containerd/aufs 371312c1e31c210a21e49bf3dfd3f31729ed9f2f
|
||||
|
||||
# cgroups dependencies
|
||||
github.com/cilium/ebpf 60c3aa43f488292fe2ee50fb8b833b383ca8ebbb
|
||||
|
84
vendor/github.com/coreos/go-systemd/v22/daemon/sdnotify.go
generated
vendored
Normal file
84
vendor/github.com/coreos/go-systemd/v22/daemon/sdnotify.go
generated
vendored
Normal file
@ -0,0 +1,84 @@
|
||||
// Copyright 2014 Docker, Inc.
|
||||
// Copyright 2015-2018 CoreOS, Inc.
|
||||
//
|
||||
// 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 daemon provides a Go implementation of the sd_notify protocol.
|
||||
// It can be used to inform systemd of service start-up completion, watchdog
|
||||
// events, and other status changes.
|
||||
//
|
||||
// https://www.freedesktop.org/software/systemd/man/sd_notify.html#Description
|
||||
package daemon
|
||||
|
||||
import (
|
||||
"net"
|
||||
"os"
|
||||
)
|
||||
|
||||
const (
|
||||
// SdNotifyReady tells the service manager that service startup is finished
|
||||
// or the service finished loading its configuration.
|
||||
SdNotifyReady = "READY=1"
|
||||
|
||||
// SdNotifyStopping tells the service manager that the service is beginning
|
||||
// its shutdown.
|
||||
SdNotifyStopping = "STOPPING=1"
|
||||
|
||||
// SdNotifyReloading tells the service manager that this service is
|
||||
// reloading its configuration. Note that you must call SdNotifyReady when
|
||||
// it completed reloading.
|
||||
SdNotifyReloading = "RELOADING=1"
|
||||
|
||||
// SdNotifyWatchdog tells the service manager to update the watchdog
|
||||
// timestamp for the service.
|
||||
SdNotifyWatchdog = "WATCHDOG=1"
|
||||
)
|
||||
|
||||
// SdNotify sends a message to the init daemon. It is common to ignore the error.
|
||||
// If `unsetEnvironment` is true, the environment variable `NOTIFY_SOCKET`
|
||||
// will be unconditionally unset.
|
||||
//
|
||||
// It returns one of the following:
|
||||
// (false, nil) - notification not supported (i.e. NOTIFY_SOCKET is unset)
|
||||
// (false, err) - notification supported, but failure happened (e.g. error connecting to NOTIFY_SOCKET or while sending data)
|
||||
// (true, nil) - notification supported, data has been sent
|
||||
func SdNotify(unsetEnvironment bool, state string) (bool, error) {
|
||||
socketAddr := &net.UnixAddr{
|
||||
Name: os.Getenv("NOTIFY_SOCKET"),
|
||||
Net: "unixgram",
|
||||
}
|
||||
|
||||
// NOTIFY_SOCKET not set
|
||||
if socketAddr.Name == "" {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
if unsetEnvironment {
|
||||
if err := os.Unsetenv("NOTIFY_SOCKET"); err != nil {
|
||||
return false, err
|
||||
}
|
||||
}
|
||||
|
||||
conn, err := net.DialUnix(socketAddr.Net, nil, socketAddr)
|
||||
// Error connecting to NOTIFY_SOCKET
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
defer conn.Close()
|
||||
|
||||
if _, err = conn.Write([]byte(state)); err != nil {
|
||||
return false, err
|
||||
}
|
||||
return true, nil
|
||||
}
|
73
vendor/github.com/coreos/go-systemd/v22/daemon/watchdog.go
generated
vendored
Normal file
73
vendor/github.com/coreos/go-systemd/v22/daemon/watchdog.go
generated
vendored
Normal file
@ -0,0 +1,73 @@
|
||||
// Copyright 2016 CoreOS, Inc.
|
||||
//
|
||||
// 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 daemon
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
// SdWatchdogEnabled returns watchdog information for a service.
|
||||
// Processes should call daemon.SdNotify(false, daemon.SdNotifyWatchdog) every
|
||||
// time / 2.
|
||||
// If `unsetEnvironment` is true, the environment variables `WATCHDOG_USEC` and
|
||||
// `WATCHDOG_PID` will be unconditionally unset.
|
||||
//
|
||||
// It returns one of the following:
|
||||
// (0, nil) - watchdog isn't enabled or we aren't the watched PID.
|
||||
// (0, err) - an error happened (e.g. error converting time).
|
||||
// (time, nil) - watchdog is enabled and we can send ping.
|
||||
// time is delay before inactive service will be killed.
|
||||
func SdWatchdogEnabled(unsetEnvironment bool) (time.Duration, error) {
|
||||
wusec := os.Getenv("WATCHDOG_USEC")
|
||||
wpid := os.Getenv("WATCHDOG_PID")
|
||||
if unsetEnvironment {
|
||||
wusecErr := os.Unsetenv("WATCHDOG_USEC")
|
||||
wpidErr := os.Unsetenv("WATCHDOG_PID")
|
||||
if wusecErr != nil {
|
||||
return 0, wusecErr
|
||||
}
|
||||
if wpidErr != nil {
|
||||
return 0, wpidErr
|
||||
}
|
||||
}
|
||||
|
||||
if wusec == "" {
|
||||
return 0, nil
|
||||
}
|
||||
s, err := strconv.Atoi(wusec)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("error converting WATCHDOG_USEC: %s", err)
|
||||
}
|
||||
if s <= 0 {
|
||||
return 0, fmt.Errorf("error WATCHDOG_USEC must be a positive number")
|
||||
}
|
||||
interval := time.Duration(s) * time.Microsecond
|
||||
|
||||
if wpid == "" {
|
||||
return interval, nil
|
||||
}
|
||||
p, err := strconv.Atoi(wpid)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("error converting WATCHDOG_PID: %s", err)
|
||||
}
|
||||
if os.Getpid() != p {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
return interval, nil
|
||||
}
|
354
vendor/github.com/hashicorp/errwrap/LICENSE
generated
vendored
Normal file
354
vendor/github.com/hashicorp/errwrap/LICENSE
generated
vendored
Normal file
@ -0,0 +1,354 @@
|
||||
Mozilla Public License, version 2.0
|
||||
|
||||
1. Definitions
|
||||
|
||||
1.1. “Contributor”
|
||||
|
||||
means each individual or legal entity that creates, contributes to the
|
||||
creation of, or owns Covered Software.
|
||||
|
||||
1.2. “Contributor Version”
|
||||
|
||||
means the combination of the Contributions of others (if any) used by a
|
||||
Contributor and that particular Contributor’s Contribution.
|
||||
|
||||
1.3. “Contribution”
|
||||
|
||||
means Covered Software of a particular Contributor.
|
||||
|
||||
1.4. “Covered Software”
|
||||
|
||||
means Source Code Form to which the initial Contributor has attached the
|
||||
notice in Exhibit A, the Executable Form of such Source Code Form, and
|
||||
Modifications of such Source Code Form, in each case including portions
|
||||
thereof.
|
||||
|
||||
1.5. “Incompatible With Secondary Licenses”
|
||||
means
|
||||
|
||||
a. that the initial Contributor has attached the notice described in
|
||||
Exhibit B to the Covered Software; or
|
||||
|
||||
b. that the Covered Software was made available under the terms of version
|
||||
1.1 or earlier of the License, but not also under the terms of a
|
||||
Secondary License.
|
||||
|
||||
1.6. “Executable Form”
|
||||
|
||||
means any form of the work other than Source Code Form.
|
||||
|
||||
1.7. “Larger Work”
|
||||
|
||||
means a work that combines Covered Software with other material, in a separate
|
||||
file or files, that is not Covered Software.
|
||||
|
||||
1.8. “License”
|
||||
|
||||
means this document.
|
||||
|
||||
1.9. “Licensable”
|
||||
|
||||
means having the right to grant, to the maximum extent possible, whether at the
|
||||
time of the initial grant or subsequently, any and all of the rights conveyed by
|
||||
this License.
|
||||
|
||||
1.10. “Modifications”
|
||||
|
||||
means any of the following:
|
||||
|
||||
a. any file in Source Code Form that results from an addition to, deletion
|
||||
from, or modification of the contents of Covered Software; or
|
||||
|
||||
b. any new file in Source Code Form that contains any Covered Software.
|
||||
|
||||
1.11. “Patent Claims” of a Contributor
|
||||
|
||||
means any patent claim(s), including without limitation, method, process,
|
||||
and apparatus claims, in any patent Licensable by such Contributor that
|
||||
would be infringed, but for the grant of the License, by the making,
|
||||
using, selling, offering for sale, having made, import, or transfer of
|
||||
either its Contributions or its Contributor Version.
|
||||
|
||||
1.12. “Secondary License”
|
||||
|
||||
means either the GNU General Public License, Version 2.0, the GNU Lesser
|
||||
General Public License, Version 2.1, the GNU Affero General Public
|
||||
License, Version 3.0, or any later versions of those licenses.
|
||||
|
||||
1.13. “Source Code Form”
|
||||
|
||||
means the form of the work preferred for making modifications.
|
||||
|
||||
1.14. “You” (or “Your”)
|
||||
|
||||
means an individual or a legal entity exercising rights under this
|
||||
License. For legal entities, “You” includes any entity that controls, is
|
||||
controlled by, or is under common control with You. For purposes of this
|
||||
definition, “control” means (a) the power, direct or indirect, to cause
|
||||
the direction or management of such entity, whether by contract or
|
||||
otherwise, or (b) ownership of more than fifty percent (50%) of the
|
||||
outstanding shares or beneficial ownership of such entity.
|
||||
|
||||
|
||||
2. License Grants and Conditions
|
||||
|
||||
2.1. Grants
|
||||
|
||||
Each Contributor hereby grants You a world-wide, royalty-free,
|
||||
non-exclusive license:
|
||||
|
||||
a. under intellectual property rights (other than patent or trademark)
|
||||
Licensable by such Contributor to use, reproduce, make available,
|
||||
modify, display, perform, distribute, and otherwise exploit its
|
||||
Contributions, either on an unmodified basis, with Modifications, or as
|
||||
part of a Larger Work; and
|
||||
|
||||
b. under Patent Claims of such Contributor to make, use, sell, offer for
|
||||
sale, have made, import, and otherwise transfer either its Contributions
|
||||
or its Contributor Version.
|
||||
|
||||
2.2. Effective Date
|
||||
|
||||
The licenses granted in Section 2.1 with respect to any Contribution become
|
||||
effective for each Contribution on the date the Contributor first distributes
|
||||
such Contribution.
|
||||
|
||||
2.3. Limitations on Grant Scope
|
||||
|
||||
The licenses granted in this Section 2 are the only rights granted under this
|
||||
License. No additional rights or licenses will be implied from the distribution
|
||||
or licensing of Covered Software under this License. Notwithstanding Section
|
||||
2.1(b) above, no patent license is granted by a Contributor:
|
||||
|
||||
a. for any code that a Contributor has removed from Covered Software; or
|
||||
|
||||
b. for infringements caused by: (i) Your and any other third party’s
|
||||
modifications of Covered Software, or (ii) the combination of its
|
||||
Contributions with other software (except as part of its Contributor
|
||||
Version); or
|
||||
|
||||
c. under Patent Claims infringed by Covered Software in the absence of its
|
||||
Contributions.
|
||||
|
||||
This License does not grant any rights in the trademarks, service marks, or
|
||||
logos of any Contributor (except as may be necessary to comply with the
|
||||
notice requirements in Section 3.4).
|
||||
|
||||
2.4. Subsequent Licenses
|
||||
|
||||
No Contributor makes additional grants as a result of Your choice to
|
||||
distribute the Covered Software under a subsequent version of this License
|
||||
(see Section 10.2) or under the terms of a Secondary License (if permitted
|
||||
under the terms of Section 3.3).
|
||||
|
||||
2.5. Representation
|
||||
|
||||
Each Contributor represents that the Contributor believes its Contributions
|
||||
are its original creation(s) or it has sufficient rights to grant the
|
||||
rights to its Contributions conveyed by this License.
|
||||
|
||||
2.6. Fair Use
|
||||
|
||||
This License is not intended to limit any rights You have under applicable
|
||||
copyright doctrines of fair use, fair dealing, or other equivalents.
|
||||
|
||||
2.7. Conditions
|
||||
|
||||
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in
|
||||
Section 2.1.
|
||||
|
||||
|
||||
3. Responsibilities
|
||||
|
||||
3.1. Distribution of Source Form
|
||||
|
||||
All distribution of Covered Software in Source Code Form, including any
|
||||
Modifications that You create or to which You contribute, must be under the
|
||||
terms of this License. You must inform recipients that the Source Code Form
|
||||
of the Covered Software is governed by the terms of this License, and how
|
||||
they can obtain a copy of this License. You may not attempt to alter or
|
||||
restrict the recipients’ rights in the Source Code Form.
|
||||
|
||||
3.2. Distribution of Executable Form
|
||||
|
||||
If You distribute Covered Software in Executable Form then:
|
||||
|
||||
a. such Covered Software must also be made available in Source Code Form,
|
||||
as described in Section 3.1, and You must inform recipients of the
|
||||
Executable Form how they can obtain a copy of such Source Code Form by
|
||||
reasonable means in a timely manner, at a charge no more than the cost
|
||||
of distribution to the recipient; and
|
||||
|
||||
b. You may distribute such Executable Form under the terms of this License,
|
||||
or sublicense it under different terms, provided that the license for
|
||||
the Executable Form does not attempt to limit or alter the recipients’
|
||||
rights in the Source Code Form under this License.
|
||||
|
||||
3.3. Distribution of a Larger Work
|
||||
|
||||
You may create and distribute a Larger Work under terms of Your choice,
|
||||
provided that You also comply with the requirements of this License for the
|
||||
Covered Software. If the Larger Work is a combination of Covered Software
|
||||
with a work governed by one or more Secondary Licenses, and the Covered
|
||||
Software is not Incompatible With Secondary Licenses, this License permits
|
||||
You to additionally distribute such Covered Software under the terms of
|
||||
such Secondary License(s), so that the recipient of the Larger Work may, at
|
||||
their option, further distribute the Covered Software under the terms of
|
||||
either this License or such Secondary License(s).
|
||||
|
||||
3.4. Notices
|
||||
|
||||
You may not remove or alter the substance of any license notices (including
|
||||
copyright notices, patent notices, disclaimers of warranty, or limitations
|
||||
of liability) contained within the Source Code Form of the Covered
|
||||
Software, except that You may alter any license notices to the extent
|
||||
required to remedy known factual inaccuracies.
|
||||
|
||||
3.5. Application of Additional Terms
|
||||
|
||||
You may choose to offer, and to charge a fee for, warranty, support,
|
||||
indemnity or liability obligations to one or more recipients of Covered
|
||||
Software. However, You may do so only on Your own behalf, and not on behalf
|
||||
of any Contributor. You must make it absolutely clear that any such
|
||||
warranty, support, indemnity, or liability obligation is offered by You
|
||||
alone, and You hereby agree to indemnify every Contributor for any
|
||||
liability incurred by such Contributor as a result of warranty, support,
|
||||
indemnity or liability terms You offer. You may include additional
|
||||
disclaimers of warranty and limitations of liability specific to any
|
||||
jurisdiction.
|
||||
|
||||
4. Inability to Comply Due to Statute or Regulation
|
||||
|
||||
If it is impossible for You to comply with any of the terms of this License
|
||||
with respect to some or all of the Covered Software due to statute, judicial
|
||||
order, or regulation then You must: (a) comply with the terms of this License
|
||||
to the maximum extent possible; and (b) describe the limitations and the code
|
||||
they affect. Such description must be placed in a text file included with all
|
||||
distributions of the Covered Software under this License. Except to the
|
||||
extent prohibited by statute or regulation, such description must be
|
||||
sufficiently detailed for a recipient of ordinary skill to be able to
|
||||
understand it.
|
||||
|
||||
5. Termination
|
||||
|
||||
5.1. The rights granted under this License will terminate automatically if You
|
||||
fail to comply with any of its terms. However, if You become compliant,
|
||||
then the rights granted under this License from a particular Contributor
|
||||
are reinstated (a) provisionally, unless and until such Contributor
|
||||
explicitly and finally terminates Your grants, and (b) on an ongoing basis,
|
||||
if such Contributor fails to notify You of the non-compliance by some
|
||||
reasonable means prior to 60 days after You have come back into compliance.
|
||||
Moreover, Your grants from a particular Contributor are reinstated on an
|
||||
ongoing basis if such Contributor notifies You of the non-compliance by
|
||||
some reasonable means, this is the first time You have received notice of
|
||||
non-compliance with this License from such Contributor, and You become
|
||||
compliant prior to 30 days after Your receipt of the notice.
|
||||
|
||||
5.2. If You initiate litigation against any entity by asserting a patent
|
||||
infringement claim (excluding declaratory judgment actions, counter-claims,
|
||||
and cross-claims) alleging that a Contributor Version directly or
|
||||
indirectly infringes any patent, then the rights granted to You by any and
|
||||
all Contributors for the Covered Software under Section 2.1 of this License
|
||||
shall terminate.
|
||||
|
||||
5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user
|
||||
license agreements (excluding distributors and resellers) which have been
|
||||
validly granted by You or Your distributors under this License prior to
|
||||
termination shall survive termination.
|
||||
|
||||
6. Disclaimer of Warranty
|
||||
|
||||
Covered Software is provided under this License on an “as is” basis, without
|
||||
warranty of any kind, either expressed, implied, or statutory, including,
|
||||
without limitation, warranties that the Covered Software is free of defects,
|
||||
merchantable, fit for a particular purpose or non-infringing. The entire
|
||||
risk as to the quality and performance of the Covered Software is with You.
|
||||
Should any Covered Software prove defective in any respect, You (not any
|
||||
Contributor) assume the cost of any necessary servicing, repair, or
|
||||
correction. This disclaimer of warranty constitutes an essential part of this
|
||||
License. No use of any Covered Software is authorized under this License
|
||||
except under this disclaimer.
|
||||
|
||||
7. Limitation of Liability
|
||||
|
||||
Under no circumstances and under no legal theory, whether tort (including
|
||||
negligence), contract, or otherwise, shall any Contributor, or anyone who
|
||||
distributes Covered Software as permitted above, be liable to You for any
|
||||
direct, indirect, special, incidental, or consequential damages of any
|
||||
character including, without limitation, damages for lost profits, loss of
|
||||
goodwill, work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses, even if such party shall have been
|
||||
informed of the possibility of such damages. This limitation of liability
|
||||
shall not apply to liability for death or personal injury resulting from such
|
||||
party’s negligence to the extent applicable law prohibits such limitation.
|
||||
Some jurisdictions do not allow the exclusion or limitation of incidental or
|
||||
consequential damages, so this exclusion and limitation may not apply to You.
|
||||
|
||||
8. Litigation
|
||||
|
||||
Any litigation relating to this License may be brought only in the courts of
|
||||
a jurisdiction where the defendant maintains its principal place of business
|
||||
and such litigation shall be governed by laws of that jurisdiction, without
|
||||
reference to its conflict-of-law provisions. Nothing in this Section shall
|
||||
prevent a party’s ability to bring cross-claims or counter-claims.
|
||||
|
||||
9. Miscellaneous
|
||||
|
||||
This License represents the complete agreement concerning the subject matter
|
||||
hereof. If any provision of this License is held to be unenforceable, such
|
||||
provision shall be reformed only to the extent necessary to make it
|
||||
enforceable. Any law or regulation which provides that the language of a
|
||||
contract shall be construed against the drafter shall not be used to construe
|
||||
this License against a Contributor.
|
||||
|
||||
|
||||
10. Versions of the License
|
||||
|
||||
10.1. New Versions
|
||||
|
||||
Mozilla Foundation is the license steward. Except as provided in Section
|
||||
10.3, no one other than the license steward has the right to modify or
|
||||
publish new versions of this License. Each version will be given a
|
||||
distinguishing version number.
|
||||
|
||||
10.2. Effect of New Versions
|
||||
|
||||
You may distribute the Covered Software under the terms of the version of
|
||||
the License under which You originally received the Covered Software, or
|
||||
under the terms of any subsequent version published by the license
|
||||
steward.
|
||||
|
||||
10.3. Modified Versions
|
||||
|
||||
If you create software not governed by this License, and you want to
|
||||
create a new license for such software, you may create and use a modified
|
||||
version of this License if you rename the license and remove any
|
||||
references to the name of the license steward (except to note that such
|
||||
modified license differs from this License).
|
||||
|
||||
10.4. Distributing Source Code Form that is Incompatible With Secondary Licenses
|
||||
If You choose to distribute Source Code Form that is Incompatible With
|
||||
Secondary Licenses under the terms of this version of the License, the
|
||||
notice described in Exhibit B of this License must be attached.
|
||||
|
||||
Exhibit A - Source Code Form License Notice
|
||||
|
||||
This Source Code Form is subject to the
|
||||
terms of the Mozilla Public License, v.
|
||||
2.0. If a copy of the MPL was not
|
||||
distributed with this file, You can
|
||||
obtain one at
|
||||
http://mozilla.org/MPL/2.0/.
|
||||
|
||||
If it is not possible or desirable to put the notice in a particular file, then
|
||||
You may include the notice in a location (such as a LICENSE file in a relevant
|
||||
directory) where a recipient would be likely to look for such a notice.
|
||||
|
||||
You may add additional accurate notices of copyright ownership.
|
||||
|
||||
Exhibit B - “Incompatible With Secondary Licenses” Notice
|
||||
|
||||
This Source Code Form is “Incompatible
|
||||
With Secondary Licenses”, as defined by
|
||||
the Mozilla Public License, v. 2.0.
|
||||
|
89
vendor/github.com/hashicorp/errwrap/README.md
generated
vendored
Normal file
89
vendor/github.com/hashicorp/errwrap/README.md
generated
vendored
Normal file
@ -0,0 +1,89 @@
|
||||
# errwrap
|
||||
|
||||
`errwrap` is a package for Go that formalizes the pattern of wrapping errors
|
||||
and checking if an error contains another error.
|
||||
|
||||
There is a common pattern in Go of taking a returned `error` value and
|
||||
then wrapping it (such as with `fmt.Errorf`) before returning it. The problem
|
||||
with this pattern is that you completely lose the original `error` structure.
|
||||
|
||||
Arguably the _correct_ approach is that you should make a custom structure
|
||||
implementing the `error` interface, and have the original error as a field
|
||||
on that structure, such [as this example](http://golang.org/pkg/os/#PathError).
|
||||
This is a good approach, but you have to know the entire chain of possible
|
||||
rewrapping that happens, when you might just care about one.
|
||||
|
||||
`errwrap` formalizes this pattern (it doesn't matter what approach you use
|
||||
above) by giving a single interface for wrapping errors, checking if a specific
|
||||
error is wrapped, and extracting that error.
|
||||
|
||||
## Installation and Docs
|
||||
|
||||
Install using `go get github.com/hashicorp/errwrap`.
|
||||
|
||||
Full documentation is available at
|
||||
http://godoc.org/github.com/hashicorp/errwrap
|
||||
|
||||
## Usage
|
||||
|
||||
#### Basic Usage
|
||||
|
||||
Below is a very basic example of its usage:
|
||||
|
||||
```go
|
||||
// A function that always returns an error, but wraps it, like a real
|
||||
// function might.
|
||||
func tryOpen() error {
|
||||
_, err := os.Open("/i/dont/exist")
|
||||
if err != nil {
|
||||
return errwrap.Wrapf("Doesn't exist: {{err}}", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func main() {
|
||||
err := tryOpen()
|
||||
|
||||
// We can use the Contains helpers to check if an error contains
|
||||
// another error. It is safe to do this with a nil error, or with
|
||||
// an error that doesn't even use the errwrap package.
|
||||
if errwrap.Contains(err, "does not exist") {
|
||||
// Do something
|
||||
}
|
||||
if errwrap.ContainsType(err, new(os.PathError)) {
|
||||
// Do something
|
||||
}
|
||||
|
||||
// Or we can use the associated `Get` functions to just extract
|
||||
// a specific error. This would return nil if that specific error doesn't
|
||||
// exist.
|
||||
perr := errwrap.GetType(err, new(os.PathError))
|
||||
}
|
||||
```
|
||||
|
||||
#### Custom Types
|
||||
|
||||
If you're already making custom types that properly wrap errors, then
|
||||
you can get all the functionality of `errwraps.Contains` and such by
|
||||
implementing the `Wrapper` interface with just one function. Example:
|
||||
|
||||
```go
|
||||
type AppError {
|
||||
Code ErrorCode
|
||||
Err error
|
||||
}
|
||||
|
||||
func (e *AppError) WrappedErrors() []error {
|
||||
return []error{e.Err}
|
||||
}
|
||||
```
|
||||
|
||||
Now this works:
|
||||
|
||||
```go
|
||||
err := &AppError{Err: fmt.Errorf("an error")}
|
||||
if errwrap.ContainsType(err, fmt.Errorf("")) {
|
||||
// This will work!
|
||||
}
|
||||
```
|
169
vendor/github.com/hashicorp/errwrap/errwrap.go
generated
vendored
Normal file
169
vendor/github.com/hashicorp/errwrap/errwrap.go
generated
vendored
Normal file
@ -0,0 +1,169 @@
|
||||
// Package errwrap implements methods to formalize error wrapping in Go.
|
||||
//
|
||||
// All of the top-level functions that take an `error` are built to be able
|
||||
// to take any error, not just wrapped errors. This allows you to use errwrap
|
||||
// without having to type-check and type-cast everywhere.
|
||||
package errwrap
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"reflect"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// WalkFunc is the callback called for Walk.
|
||||
type WalkFunc func(error)
|
||||
|
||||
// Wrapper is an interface that can be implemented by custom types to
|
||||
// have all the Contains, Get, etc. functions in errwrap work.
|
||||
//
|
||||
// When Walk reaches a Wrapper, it will call the callback for every
|
||||
// wrapped error in addition to the wrapper itself. Since all the top-level
|
||||
// functions in errwrap use Walk, this means that all those functions work
|
||||
// with your custom type.
|
||||
type Wrapper interface {
|
||||
WrappedErrors() []error
|
||||
}
|
||||
|
||||
// Wrap defines that outer wraps inner, returning an error type that
|
||||
// can be cleanly used with the other methods in this package, such as
|
||||
// Contains, GetAll, etc.
|
||||
//
|
||||
// This function won't modify the error message at all (the outer message
|
||||
// will be used).
|
||||
func Wrap(outer, inner error) error {
|
||||
return &wrappedError{
|
||||
Outer: outer,
|
||||
Inner: inner,
|
||||
}
|
||||
}
|
||||
|
||||
// Wrapf wraps an error with a formatting message. This is similar to using
|
||||
// `fmt.Errorf` to wrap an error. If you're using `fmt.Errorf` to wrap
|
||||
// errors, you should replace it with this.
|
||||
//
|
||||
// format is the format of the error message. The string '{{err}}' will
|
||||
// be replaced with the original error message.
|
||||
func Wrapf(format string, err error) error {
|
||||
outerMsg := "<nil>"
|
||||
if err != nil {
|
||||
outerMsg = err.Error()
|
||||
}
|
||||
|
||||
outer := errors.New(strings.Replace(
|
||||
format, "{{err}}", outerMsg, -1))
|
||||
|
||||
return Wrap(outer, err)
|
||||
}
|
||||
|
||||
// Contains checks if the given error contains an error with the
|
||||
// message msg. If err is not a wrapped error, this will always return
|
||||
// false unless the error itself happens to match this msg.
|
||||
func Contains(err error, msg string) bool {
|
||||
return len(GetAll(err, msg)) > 0
|
||||
}
|
||||
|
||||
// ContainsType checks if the given error contains an error with
|
||||
// the same concrete type as v. If err is not a wrapped error, this will
|
||||
// check the err itself.
|
||||
func ContainsType(err error, v interface{}) bool {
|
||||
return len(GetAllType(err, v)) > 0
|
||||
}
|
||||
|
||||
// Get is the same as GetAll but returns the deepest matching error.
|
||||
func Get(err error, msg string) error {
|
||||
es := GetAll(err, msg)
|
||||
if len(es) > 0 {
|
||||
return es[len(es)-1]
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetType is the same as GetAllType but returns the deepest matching error.
|
||||
func GetType(err error, v interface{}) error {
|
||||
es := GetAllType(err, v)
|
||||
if len(es) > 0 {
|
||||
return es[len(es)-1]
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetAll gets all the errors that might be wrapped in err with the
|
||||
// given message. The order of the errors is such that the outermost
|
||||
// matching error (the most recent wrap) is index zero, and so on.
|
||||
func GetAll(err error, msg string) []error {
|
||||
var result []error
|
||||
|
||||
Walk(err, func(err error) {
|
||||
if err.Error() == msg {
|
||||
result = append(result, err)
|
||||
}
|
||||
})
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// GetAllType gets all the errors that are the same type as v.
|
||||
//
|
||||
// The order of the return value is the same as described in GetAll.
|
||||
func GetAllType(err error, v interface{}) []error {
|
||||
var result []error
|
||||
|
||||
var search string
|
||||
if v != nil {
|
||||
search = reflect.TypeOf(v).String()
|
||||
}
|
||||
Walk(err, func(err error) {
|
||||
var needle string
|
||||
if err != nil {
|
||||
needle = reflect.TypeOf(err).String()
|
||||
}
|
||||
|
||||
if needle == search {
|
||||
result = append(result, err)
|
||||
}
|
||||
})
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// Walk walks all the wrapped errors in err and calls the callback. If
|
||||
// err isn't a wrapped error, this will be called once for err. If err
|
||||
// is a wrapped error, the callback will be called for both the wrapper
|
||||
// that implements error as well as the wrapped error itself.
|
||||
func Walk(err error, cb WalkFunc) {
|
||||
if err == nil {
|
||||
return
|
||||
}
|
||||
|
||||
switch e := err.(type) {
|
||||
case *wrappedError:
|
||||
cb(e.Outer)
|
||||
Walk(e.Inner, cb)
|
||||
case Wrapper:
|
||||
cb(err)
|
||||
|
||||
for _, err := range e.WrappedErrors() {
|
||||
Walk(err, cb)
|
||||
}
|
||||
default:
|
||||
cb(err)
|
||||
}
|
||||
}
|
||||
|
||||
// wrappedError is an implementation of error that has both the
|
||||
// outer and inner errors.
|
||||
type wrappedError struct {
|
||||
Outer error
|
||||
Inner error
|
||||
}
|
||||
|
||||
func (w *wrappedError) Error() string {
|
||||
return w.Outer.Error()
|
||||
}
|
||||
|
||||
func (w *wrappedError) WrappedErrors() []error {
|
||||
return []error{w.Outer, w.Inner}
|
||||
}
|
1
vendor/github.com/hashicorp/errwrap/go.mod
generated
vendored
Normal file
1
vendor/github.com/hashicorp/errwrap/go.mod
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
module github.com/hashicorp/errwrap
|
353
vendor/github.com/hashicorp/go-multierror/LICENSE
generated
vendored
Normal file
353
vendor/github.com/hashicorp/go-multierror/LICENSE
generated
vendored
Normal file
@ -0,0 +1,353 @@
|
||||
Mozilla Public License, version 2.0
|
||||
|
||||
1. Definitions
|
||||
|
||||
1.1. “Contributor”
|
||||
|
||||
means each individual or legal entity that creates, contributes to the
|
||||
creation of, or owns Covered Software.
|
||||
|
||||
1.2. “Contributor Version”
|
||||
|
||||
means the combination of the Contributions of others (if any) used by a
|
||||
Contributor and that particular Contributor’s Contribution.
|
||||
|
||||
1.3. “Contribution”
|
||||
|
||||
means Covered Software of a particular Contributor.
|
||||
|
||||
1.4. “Covered Software”
|
||||
|
||||
means Source Code Form to which the initial Contributor has attached the
|
||||
notice in Exhibit A, the Executable Form of such Source Code Form, and
|
||||
Modifications of such Source Code Form, in each case including portions
|
||||
thereof.
|
||||
|
||||
1.5. “Incompatible With Secondary Licenses”
|
||||
means
|
||||
|
||||
a. that the initial Contributor has attached the notice described in
|
||||
Exhibit B to the Covered Software; or
|
||||
|
||||
b. that the Covered Software was made available under the terms of version
|
||||
1.1 or earlier of the License, but not also under the terms of a
|
||||
Secondary License.
|
||||
|
||||
1.6. “Executable Form”
|
||||
|
||||
means any form of the work other than Source Code Form.
|
||||
|
||||
1.7. “Larger Work”
|
||||
|
||||
means a work that combines Covered Software with other material, in a separate
|
||||
file or files, that is not Covered Software.
|
||||
|
||||
1.8. “License”
|
||||
|
||||
means this document.
|
||||
|
||||
1.9. “Licensable”
|
||||
|
||||
means having the right to grant, to the maximum extent possible, whether at the
|
||||
time of the initial grant or subsequently, any and all of the rights conveyed by
|
||||
this License.
|
||||
|
||||
1.10. “Modifications”
|
||||
|
||||
means any of the following:
|
||||
|
||||
a. any file in Source Code Form that results from an addition to, deletion
|
||||
from, or modification of the contents of Covered Software; or
|
||||
|
||||
b. any new file in Source Code Form that contains any Covered Software.
|
||||
|
||||
1.11. “Patent Claims” of a Contributor
|
||||
|
||||
means any patent claim(s), including without limitation, method, process,
|
||||
and apparatus claims, in any patent Licensable by such Contributor that
|
||||
would be infringed, but for the grant of the License, by the making,
|
||||
using, selling, offering for sale, having made, import, or transfer of
|
||||
either its Contributions or its Contributor Version.
|
||||
|
||||
1.12. “Secondary License”
|
||||
|
||||
means either the GNU General Public License, Version 2.0, the GNU Lesser
|
||||
General Public License, Version 2.1, the GNU Affero General Public
|
||||
License, Version 3.0, or any later versions of those licenses.
|
||||
|
||||
1.13. “Source Code Form”
|
||||
|
||||
means the form of the work preferred for making modifications.
|
||||
|
||||
1.14. “You” (or “Your”)
|
||||
|
||||
means an individual or a legal entity exercising rights under this
|
||||
License. For legal entities, “You” includes any entity that controls, is
|
||||
controlled by, or is under common control with You. For purposes of this
|
||||
definition, “control” means (a) the power, direct or indirect, to cause
|
||||
the direction or management of such entity, whether by contract or
|
||||
otherwise, or (b) ownership of more than fifty percent (50%) of the
|
||||
outstanding shares or beneficial ownership of such entity.
|
||||
|
||||
|
||||
2. License Grants and Conditions
|
||||
|
||||
2.1. Grants
|
||||
|
||||
Each Contributor hereby grants You a world-wide, royalty-free,
|
||||
non-exclusive license:
|
||||
|
||||
a. under intellectual property rights (other than patent or trademark)
|
||||
Licensable by such Contributor to use, reproduce, make available,
|
||||
modify, display, perform, distribute, and otherwise exploit its
|
||||
Contributions, either on an unmodified basis, with Modifications, or as
|
||||
part of a Larger Work; and
|
||||
|
||||
b. under Patent Claims of such Contributor to make, use, sell, offer for
|
||||
sale, have made, import, and otherwise transfer either its Contributions
|
||||
or its Contributor Version.
|
||||
|
||||
2.2. Effective Date
|
||||
|
||||
The licenses granted in Section 2.1 with respect to any Contribution become
|
||||
effective for each Contribution on the date the Contributor first distributes
|
||||
such Contribution.
|
||||
|
||||
2.3. Limitations on Grant Scope
|
||||
|
||||
The licenses granted in this Section 2 are the only rights granted under this
|
||||
License. No additional rights or licenses will be implied from the distribution
|
||||
or licensing of Covered Software under this License. Notwithstanding Section
|
||||
2.1(b) above, no patent license is granted by a Contributor:
|
||||
|
||||
a. for any code that a Contributor has removed from Covered Software; or
|
||||
|
||||
b. for infringements caused by: (i) Your and any other third party’s
|
||||
modifications of Covered Software, or (ii) the combination of its
|
||||
Contributions with other software (except as part of its Contributor
|
||||
Version); or
|
||||
|
||||
c. under Patent Claims infringed by Covered Software in the absence of its
|
||||
Contributions.
|
||||
|
||||
This License does not grant any rights in the trademarks, service marks, or
|
||||
logos of any Contributor (except as may be necessary to comply with the
|
||||
notice requirements in Section 3.4).
|
||||
|
||||
2.4. Subsequent Licenses
|
||||
|
||||
No Contributor makes additional grants as a result of Your choice to
|
||||
distribute the Covered Software under a subsequent version of this License
|
||||
(see Section 10.2) or under the terms of a Secondary License (if permitted
|
||||
under the terms of Section 3.3).
|
||||
|
||||
2.5. Representation
|
||||
|
||||
Each Contributor represents that the Contributor believes its Contributions
|
||||
are its original creation(s) or it has sufficient rights to grant the
|
||||
rights to its Contributions conveyed by this License.
|
||||
|
||||
2.6. Fair Use
|
||||
|
||||
This License is not intended to limit any rights You have under applicable
|
||||
copyright doctrines of fair use, fair dealing, or other equivalents.
|
||||
|
||||
2.7. Conditions
|
||||
|
||||
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in
|
||||
Section 2.1.
|
||||
|
||||
|
||||
3. Responsibilities
|
||||
|
||||
3.1. Distribution of Source Form
|
||||
|
||||
All distribution of Covered Software in Source Code Form, including any
|
||||
Modifications that You create or to which You contribute, must be under the
|
||||
terms of this License. You must inform recipients that the Source Code Form
|
||||
of the Covered Software is governed by the terms of this License, and how
|
||||
they can obtain a copy of this License. You may not attempt to alter or
|
||||
restrict the recipients’ rights in the Source Code Form.
|
||||
|
||||
3.2. Distribution of Executable Form
|
||||
|
||||
If You distribute Covered Software in Executable Form then:
|
||||
|
||||
a. such Covered Software must also be made available in Source Code Form,
|
||||
as described in Section 3.1, and You must inform recipients of the
|
||||
Executable Form how they can obtain a copy of such Source Code Form by
|
||||
reasonable means in a timely manner, at a charge no more than the cost
|
||||
of distribution to the recipient; and
|
||||
|
||||
b. You may distribute such Executable Form under the terms of this License,
|
||||
or sublicense it under different terms, provided that the license for
|
||||
the Executable Form does not attempt to limit or alter the recipients’
|
||||
rights in the Source Code Form under this License.
|
||||
|
||||
3.3. Distribution of a Larger Work
|
||||
|
||||
You may create and distribute a Larger Work under terms of Your choice,
|
||||
provided that You also comply with the requirements of this License for the
|
||||
Covered Software. If the Larger Work is a combination of Covered Software
|
||||
with a work governed by one or more Secondary Licenses, and the Covered
|
||||
Software is not Incompatible With Secondary Licenses, this License permits
|
||||
You to additionally distribute such Covered Software under the terms of
|
||||
such Secondary License(s), so that the recipient of the Larger Work may, at
|
||||
their option, further distribute the Covered Software under the terms of
|
||||
either this License or such Secondary License(s).
|
||||
|
||||
3.4. Notices
|
||||
|
||||
You may not remove or alter the substance of any license notices (including
|
||||
copyright notices, patent notices, disclaimers of warranty, or limitations
|
||||
of liability) contained within the Source Code Form of the Covered
|
||||
Software, except that You may alter any license notices to the extent
|
||||
required to remedy known factual inaccuracies.
|
||||
|
||||
3.5. Application of Additional Terms
|
||||
|
||||
You may choose to offer, and to charge a fee for, warranty, support,
|
||||
indemnity or liability obligations to one or more recipients of Covered
|
||||
Software. However, You may do so only on Your own behalf, and not on behalf
|
||||
of any Contributor. You must make it absolutely clear that any such
|
||||
warranty, support, indemnity, or liability obligation is offered by You
|
||||
alone, and You hereby agree to indemnify every Contributor for any
|
||||
liability incurred by such Contributor as a result of warranty, support,
|
||||
indemnity or liability terms You offer. You may include additional
|
||||
disclaimers of warranty and limitations of liability specific to any
|
||||
jurisdiction.
|
||||
|
||||
4. Inability to Comply Due to Statute or Regulation
|
||||
|
||||
If it is impossible for You to comply with any of the terms of this License
|
||||
with respect to some or all of the Covered Software due to statute, judicial
|
||||
order, or regulation then You must: (a) comply with the terms of this License
|
||||
to the maximum extent possible; and (b) describe the limitations and the code
|
||||
they affect. Such description must be placed in a text file included with all
|
||||
distributions of the Covered Software under this License. Except to the
|
||||
extent prohibited by statute or regulation, such description must be
|
||||
sufficiently detailed for a recipient of ordinary skill to be able to
|
||||
understand it.
|
||||
|
||||
5. Termination
|
||||
|
||||
5.1. The rights granted under this License will terminate automatically if You
|
||||
fail to comply with any of its terms. However, if You become compliant,
|
||||
then the rights granted under this License from a particular Contributor
|
||||
are reinstated (a) provisionally, unless and until such Contributor
|
||||
explicitly and finally terminates Your grants, and (b) on an ongoing basis,
|
||||
if such Contributor fails to notify You of the non-compliance by some
|
||||
reasonable means prior to 60 days after You have come back into compliance.
|
||||
Moreover, Your grants from a particular Contributor are reinstated on an
|
||||
ongoing basis if such Contributor notifies You of the non-compliance by
|
||||
some reasonable means, this is the first time You have received notice of
|
||||
non-compliance with this License from such Contributor, and You become
|
||||
compliant prior to 30 days after Your receipt of the notice.
|
||||
|
||||
5.2. If You initiate litigation against any entity by asserting a patent
|
||||
infringement claim (excluding declaratory judgment actions, counter-claims,
|
||||
and cross-claims) alleging that a Contributor Version directly or
|
||||
indirectly infringes any patent, then the rights granted to You by any and
|
||||
all Contributors for the Covered Software under Section 2.1 of this License
|
||||
shall terminate.
|
||||
|
||||
5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user
|
||||
license agreements (excluding distributors and resellers) which have been
|
||||
validly granted by You or Your distributors under this License prior to
|
||||
termination shall survive termination.
|
||||
|
||||
6. Disclaimer of Warranty
|
||||
|
||||
Covered Software is provided under this License on an “as is” basis, without
|
||||
warranty of any kind, either expressed, implied, or statutory, including,
|
||||
without limitation, warranties that the Covered Software is free of defects,
|
||||
merchantable, fit for a particular purpose or non-infringing. The entire
|
||||
risk as to the quality and performance of the Covered Software is with You.
|
||||
Should any Covered Software prove defective in any respect, You (not any
|
||||
Contributor) assume the cost of any necessary servicing, repair, or
|
||||
correction. This disclaimer of warranty constitutes an essential part of this
|
||||
License. No use of any Covered Software is authorized under this License
|
||||
except under this disclaimer.
|
||||
|
||||
7. Limitation of Liability
|
||||
|
||||
Under no circumstances and under no legal theory, whether tort (including
|
||||
negligence), contract, or otherwise, shall any Contributor, or anyone who
|
||||
distributes Covered Software as permitted above, be liable to You for any
|
||||
direct, indirect, special, incidental, or consequential damages of any
|
||||
character including, without limitation, damages for lost profits, loss of
|
||||
goodwill, work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses, even if such party shall have been
|
||||
informed of the possibility of such damages. This limitation of liability
|
||||
shall not apply to liability for death or personal injury resulting from such
|
||||
party’s negligence to the extent applicable law prohibits such limitation.
|
||||
Some jurisdictions do not allow the exclusion or limitation of incidental or
|
||||
consequential damages, so this exclusion and limitation may not apply to You.
|
||||
|
||||
8. Litigation
|
||||
|
||||
Any litigation relating to this License may be brought only in the courts of
|
||||
a jurisdiction where the defendant maintains its principal place of business
|
||||
and such litigation shall be governed by laws of that jurisdiction, without
|
||||
reference to its conflict-of-law provisions. Nothing in this Section shall
|
||||
prevent a party’s ability to bring cross-claims or counter-claims.
|
||||
|
||||
9. Miscellaneous
|
||||
|
||||
This License represents the complete agreement concerning the subject matter
|
||||
hereof. If any provision of this License is held to be unenforceable, such
|
||||
provision shall be reformed only to the extent necessary to make it
|
||||
enforceable. Any law or regulation which provides that the language of a
|
||||
contract shall be construed against the drafter shall not be used to construe
|
||||
this License against a Contributor.
|
||||
|
||||
|
||||
10. Versions of the License
|
||||
|
||||
10.1. New Versions
|
||||
|
||||
Mozilla Foundation is the license steward. Except as provided in Section
|
||||
10.3, no one other than the license steward has the right to modify or
|
||||
publish new versions of this License. Each version will be given a
|
||||
distinguishing version number.
|
||||
|
||||
10.2. Effect of New Versions
|
||||
|
||||
You may distribute the Covered Software under the terms of the version of
|
||||
the License under which You originally received the Covered Software, or
|
||||
under the terms of any subsequent version published by the license
|
||||
steward.
|
||||
|
||||
10.3. Modified Versions
|
||||
|
||||
If you create software not governed by this License, and you want to
|
||||
create a new license for such software, you may create and use a modified
|
||||
version of this License if you rename the license and remove any
|
||||
references to the name of the license steward (except to note that such
|
||||
modified license differs from this License).
|
||||
|
||||
10.4. Distributing Source Code Form that is Incompatible With Secondary Licenses
|
||||
If You choose to distribute Source Code Form that is Incompatible With
|
||||
Secondary Licenses under the terms of this version of the License, the
|
||||
notice described in Exhibit B of this License must be attached.
|
||||
|
||||
Exhibit A - Source Code Form License Notice
|
||||
|
||||
This Source Code Form is subject to the
|
||||
terms of the Mozilla Public License, v.
|
||||
2.0. If a copy of the MPL was not
|
||||
distributed with this file, You can
|
||||
obtain one at
|
||||
http://mozilla.org/MPL/2.0/.
|
||||
|
||||
If it is not possible or desirable to put the notice in a particular file, then
|
||||
You may include the notice in a location (such as a LICENSE file in a relevant
|
||||
directory) where a recipient would be likely to look for such a notice.
|
||||
|
||||
You may add additional accurate notices of copyright ownership.
|
||||
|
||||
Exhibit B - “Incompatible With Secondary Licenses” Notice
|
||||
|
||||
This Source Code Form is “Incompatible
|
||||
With Secondary Licenses”, as defined by
|
||||
the Mozilla Public License, v. 2.0.
|
97
vendor/github.com/hashicorp/go-multierror/README.md
generated
vendored
Normal file
97
vendor/github.com/hashicorp/go-multierror/README.md
generated
vendored
Normal file
@ -0,0 +1,97 @@
|
||||
# go-multierror
|
||||
|
||||
[][travis]
|
||||
[][godocs]
|
||||
|
||||
[travis]: https://travis-ci.org/hashicorp/go-multierror
|
||||
[godocs]: https://godoc.org/github.com/hashicorp/go-multierror
|
||||
|
||||
`go-multierror` is a package for Go that provides a mechanism for
|
||||
representing a list of `error` values as a single `error`.
|
||||
|
||||
This allows a function in Go to return an `error` that might actually
|
||||
be a list of errors. If the caller knows this, they can unwrap the
|
||||
list and access the errors. If the caller doesn't know, the error
|
||||
formats to a nice human-readable format.
|
||||
|
||||
`go-multierror` implements the
|
||||
[errwrap](https://github.com/hashicorp/errwrap) interface so that it can
|
||||
be used with that library, as well.
|
||||
|
||||
## Installation and Docs
|
||||
|
||||
Install using `go get github.com/hashicorp/go-multierror`.
|
||||
|
||||
Full documentation is available at
|
||||
http://godoc.org/github.com/hashicorp/go-multierror
|
||||
|
||||
## Usage
|
||||
|
||||
go-multierror is easy to use and purposely built to be unobtrusive in
|
||||
existing Go applications/libraries that may not be aware of it.
|
||||
|
||||
**Building a list of errors**
|
||||
|
||||
The `Append` function is used to create a list of errors. This function
|
||||
behaves a lot like the Go built-in `append` function: it doesn't matter
|
||||
if the first argument is nil, a `multierror.Error`, or any other `error`,
|
||||
the function behaves as you would expect.
|
||||
|
||||
```go
|
||||
var result error
|
||||
|
||||
if err := step1(); err != nil {
|
||||
result = multierror.Append(result, err)
|
||||
}
|
||||
if err := step2(); err != nil {
|
||||
result = multierror.Append(result, err)
|
||||
}
|
||||
|
||||
return result
|
||||
```
|
||||
|
||||
**Customizing the formatting of the errors**
|
||||
|
||||
By specifying a custom `ErrorFormat`, you can customize the format
|
||||
of the `Error() string` function:
|
||||
|
||||
```go
|
||||
var result *multierror.Error
|
||||
|
||||
// ... accumulate errors here, maybe using Append
|
||||
|
||||
if result != nil {
|
||||
result.ErrorFormat = func([]error) string {
|
||||
return "errors!"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Accessing the list of errors**
|
||||
|
||||
`multierror.Error` implements `error` so if the caller doesn't know about
|
||||
multierror, it will work just fine. But if you're aware a multierror might
|
||||
be returned, you can use type switches to access the list of errors:
|
||||
|
||||
```go
|
||||
if err := something(); err != nil {
|
||||
if merr, ok := err.(*multierror.Error); ok {
|
||||
// Use merr.Errors
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Returning a multierror only if there are errors**
|
||||
|
||||
If you build a `multierror.Error`, you can use the `ErrorOrNil` function
|
||||
to return an `error` implementation only if there are errors to return:
|
||||
|
||||
```go
|
||||
var result *multierror.Error
|
||||
|
||||
// ... accumulate errors here
|
||||
|
||||
// Return the `error` only if errors were added to the multierror, otherwise
|
||||
// return nil since there are no errors.
|
||||
return result.ErrorOrNil()
|
||||
```
|
41
vendor/github.com/hashicorp/go-multierror/append.go
generated
vendored
Normal file
41
vendor/github.com/hashicorp/go-multierror/append.go
generated
vendored
Normal file
@ -0,0 +1,41 @@
|
||||
package multierror
|
||||
|
||||
// Append is a helper function that will append more errors
|
||||
// onto an Error in order to create a larger multi-error.
|
||||
//
|
||||
// If err is not a multierror.Error, then it will be turned into
|
||||
// one. If any of the errs are multierr.Error, they will be flattened
|
||||
// one level into err.
|
||||
func Append(err error, errs ...error) *Error {
|
||||
switch err := err.(type) {
|
||||
case *Error:
|
||||
// Typed nils can reach here, so initialize if we are nil
|
||||
if err == nil {
|
||||
err = new(Error)
|
||||
}
|
||||
|
||||
// Go through each error and flatten
|
||||
for _, e := range errs {
|
||||
switch e := e.(type) {
|
||||
case *Error:
|
||||
if e != nil {
|
||||
err.Errors = append(err.Errors, e.Errors...)
|
||||
}
|
||||
default:
|
||||
if e != nil {
|
||||
err.Errors = append(err.Errors, e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return err
|
||||
default:
|
||||
newErrs := make([]error, 0, len(errs)+1)
|
||||
if err != nil {
|
||||
newErrs = append(newErrs, err)
|
||||
}
|
||||
newErrs = append(newErrs, errs...)
|
||||
|
||||
return Append(&Error{}, newErrs...)
|
||||
}
|
||||
}
|
26
vendor/github.com/hashicorp/go-multierror/flatten.go
generated
vendored
Normal file
26
vendor/github.com/hashicorp/go-multierror/flatten.go
generated
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
package multierror
|
||||
|
||||
// Flatten flattens the given error, merging any *Errors together into
|
||||
// a single *Error.
|
||||
func Flatten(err error) error {
|
||||
// If it isn't an *Error, just return the error as-is
|
||||
if _, ok := err.(*Error); !ok {
|
||||
return err
|
||||
}
|
||||
|
||||
// Otherwise, make the result and flatten away!
|
||||
flatErr := new(Error)
|
||||
flatten(err, flatErr)
|
||||
return flatErr
|
||||
}
|
||||
|
||||
func flatten(err error, flatErr *Error) {
|
||||
switch err := err.(type) {
|
||||
case *Error:
|
||||
for _, e := range err.Errors {
|
||||
flatten(e, flatErr)
|
||||
}
|
||||
default:
|
||||
flatErr.Errors = append(flatErr.Errors, err)
|
||||
}
|
||||
}
|
27
vendor/github.com/hashicorp/go-multierror/format.go
generated
vendored
Normal file
27
vendor/github.com/hashicorp/go-multierror/format.go
generated
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
package multierror
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// ErrorFormatFunc is a function callback that is called by Error to
|
||||
// turn the list of errors into a string.
|
||||
type ErrorFormatFunc func([]error) string
|
||||
|
||||
// ListFormatFunc is a basic formatter that outputs the number of errors
|
||||
// that occurred along with a bullet point list of the errors.
|
||||
func ListFormatFunc(es []error) string {
|
||||
if len(es) == 1 {
|
||||
return fmt.Sprintf("1 error occurred:\n\t* %s\n\n", es[0])
|
||||
}
|
||||
|
||||
points := make([]string, len(es))
|
||||
for i, err := range es {
|
||||
points[i] = fmt.Sprintf("* %s", err)
|
||||
}
|
||||
|
||||
return fmt.Sprintf(
|
||||
"%d errors occurred:\n\t%s\n\n",
|
||||
len(es), strings.Join(points, "\n\t"))
|
||||
}
|
3
vendor/github.com/hashicorp/go-multierror/go.mod
generated
vendored
Normal file
3
vendor/github.com/hashicorp/go-multierror/go.mod
generated
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
module github.com/hashicorp/go-multierror
|
||||
|
||||
require github.com/hashicorp/errwrap v1.0.0
|
51
vendor/github.com/hashicorp/go-multierror/multierror.go
generated
vendored
Normal file
51
vendor/github.com/hashicorp/go-multierror/multierror.go
generated
vendored
Normal file
@ -0,0 +1,51 @@
|
||||
package multierror
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// Error is an error type to track multiple errors. This is used to
|
||||
// accumulate errors in cases and return them as a single "error".
|
||||
type Error struct {
|
||||
Errors []error
|
||||
ErrorFormat ErrorFormatFunc
|
||||
}
|
||||
|
||||
func (e *Error) Error() string {
|
||||
fn := e.ErrorFormat
|
||||
if fn == nil {
|
||||
fn = ListFormatFunc
|
||||
}
|
||||
|
||||
return fn(e.Errors)
|
||||
}
|
||||
|
||||
// ErrorOrNil returns an error interface if this Error represents
|
||||
// a list of errors, or returns nil if the list of errors is empty. This
|
||||
// function is useful at the end of accumulation to make sure that the value
|
||||
// returned represents the existence of errors.
|
||||
func (e *Error) ErrorOrNil() error {
|
||||
if e == nil {
|
||||
return nil
|
||||
}
|
||||
if len(e.Errors) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
return e
|
||||
}
|
||||
|
||||
func (e *Error) GoString() string {
|
||||
return fmt.Sprintf("*%#v", *e)
|
||||
}
|
||||
|
||||
// WrappedErrors returns the list of errors that this Error is wrapping.
|
||||
// It is an implementation of the errwrap.Wrapper interface so that
|
||||
// multierror.Error can be used with that library.
|
||||
//
|
||||
// This method is not safe to be called concurrently and is no different
|
||||
// than accessing the Errors field directly. It is implemented only to
|
||||
// satisfy the errwrap.Wrapper interface.
|
||||
func (e *Error) WrappedErrors() []error {
|
||||
return e.Errors
|
||||
}
|
37
vendor/github.com/hashicorp/go-multierror/prefix.go
generated
vendored
Normal file
37
vendor/github.com/hashicorp/go-multierror/prefix.go
generated
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
package multierror
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/hashicorp/errwrap"
|
||||
)
|
||||
|
||||
// Prefix is a helper function that will prefix some text
|
||||
// to the given error. If the error is a multierror.Error, then
|
||||
// it will be prefixed to each wrapped error.
|
||||
//
|
||||
// This is useful to use when appending multiple multierrors
|
||||
// together in order to give better scoping.
|
||||
func Prefix(err error, prefix string) error {
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
format := fmt.Sprintf("%s {{err}}", prefix)
|
||||
switch err := err.(type) {
|
||||
case *Error:
|
||||
// Typed nils can reach here, so initialize if we are nil
|
||||
if err == nil {
|
||||
err = new(Error)
|
||||
}
|
||||
|
||||
// Wrap each of the errors
|
||||
for i, e := range err.Errors {
|
||||
err.Errors[i] = errwrap.Wrapf(format, e)
|
||||
}
|
||||
|
||||
return err
|
||||
default:
|
||||
return errwrap.Wrapf(format, err)
|
||||
}
|
||||
}
|
16
vendor/github.com/hashicorp/go-multierror/sort.go
generated
vendored
Normal file
16
vendor/github.com/hashicorp/go-multierror/sort.go
generated
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
package multierror
|
||||
|
||||
// Len implements sort.Interface function for length
|
||||
func (err Error) Len() int {
|
||||
return len(err.Errors)
|
||||
}
|
||||
|
||||
// Swap implements sort.Interface function for swapping elements
|
||||
func (err Error) Swap(i, j int) {
|
||||
err.Errors[i], err.Errors[j] = err.Errors[j], err.Errors[i]
|
||||
}
|
||||
|
||||
// Less implements sort.Interface function for determining order
|
||||
func (err Error) Less(i, j int) bool {
|
||||
return err.Errors[i].Error() < err.Errors[j].Error()
|
||||
}
|
Loading…
Reference in New Issue
Block a user