summaryrefslogtreecommitdiff
path: root/vendor/github.com
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com')
-rw-r--r--vendor/github.com/acarl005/stripansi/LICENSE21
-rw-r--r--vendor/github.com/acarl005/stripansi/README.md30
-rw-r--r--vendor/github.com/acarl005/stripansi/stripansi.go13
-rw-r--r--vendor/github.com/blang/semver/.travis.yml21
-rw-r--r--vendor/github.com/blang/semver/README.md5
-rw-r--r--vendor/github.com/blang/semver/package.json17
-rw-r--r--vendor/github.com/blang/semver/range.go200
-rw-r--r--vendor/github.com/blang/semver/semver.go23
-rw-r--r--vendor/github.com/containerd/containerd/log/context.go90
-rw-r--r--vendor/github.com/containerd/containerd/platforms/compare.go229
-rw-r--r--vendor/github.com/containerd/containerd/platforms/cpuinfo.go117
-rw-r--r--vendor/github.com/containerd/containerd/platforms/database.go114
-rw-r--r--vendor/github.com/containerd/containerd/platforms/defaults.go38
-rw-r--r--vendor/github.com/containerd/containerd/platforms/defaults_unix.go24
-rw-r--r--vendor/github.com/containerd/containerd/platforms/defaults_windows.go31
-rw-r--r--vendor/github.com/containerd/containerd/platforms/platforms.go279
-rw-r--r--vendor/github.com/containernetworking/cni/libcni/api.go6
-rw-r--r--vendor/github.com/containernetworking/cni/pkg/invoke/args.go4
-rw-r--r--vendor/github.com/containernetworking/cni/pkg/invoke/raw_exec.go8
-rw-r--r--vendor/github.com/containernetworking/cni/pkg/types/020/types.go14
-rw-r--r--vendor/github.com/containernetworking/cni/pkg/types/current/types.go17
-rw-r--r--vendor/github.com/containernetworking/cni/pkg/types/types.go3
-rw-r--r--vendor/github.com/containernetworking/cni/pkg/utils/utils.go39
-rw-r--r--vendor/github.com/containers/buildah/.cirrus.yml232
-rw-r--r--vendor/github.com/containers/buildah/.papr.sh42
-rw-r--r--vendor/github.com/containers/buildah/.papr.yml87
-rw-r--r--vendor/github.com/containers/buildah/.travis.yml95
-rw-r--r--vendor/github.com/containers/buildah/CHANGELOG.md132
-rw-r--r--vendor/github.com/containers/buildah/CODE-OF-CONDUCT.md3
-rw-r--r--vendor/github.com/containers/buildah/CONTRIBUTING.md54
-rw-r--r--vendor/github.com/containers/buildah/Makefile12
-rw-r--r--vendor/github.com/containers/buildah/README.md4
-rw-r--r--vendor/github.com/containers/buildah/bors.toml44
-rw-r--r--vendor/github.com/containers/buildah/buildah.go38
-rw-r--r--vendor/github.com/containers/buildah/changelog.txt131
-rw-r--r--vendor/github.com/containers/buildah/chroot/run.go2
-rw-r--r--vendor/github.com/containers/buildah/chroot/seccomp.go21
-rw-r--r--vendor/github.com/containers/buildah/commit.go31
-rw-r--r--vendor/github.com/containers/buildah/common.go78
-rw-r--r--vendor/github.com/containers/buildah/go.mod39
-rw-r--r--vendor/github.com/containers/buildah/go.sum282
-rw-r--r--vendor/github.com/containers/buildah/image.go2
-rw-r--r--vendor/github.com/containers/buildah/imagebuildah/build.go27
-rw-r--r--vendor/github.com/containers/buildah/imagebuildah/executor.go53
-rw-r--r--vendor/github.com/containers/buildah/imagebuildah/stage_executor.go71
-rw-r--r--vendor/github.com/containers/buildah/imagebuildah/util.go8
-rw-r--r--vendor/github.com/containers/buildah/info.go3
-rw-r--r--vendor/github.com/containers/buildah/install.md131
-rw-r--r--vendor/github.com/containers/buildah/manifests/copy.go15
-rw-r--r--vendor/github.com/containers/buildah/manifests/manifests.go397
-rw-r--r--vendor/github.com/containers/buildah/new.go17
-rw-r--r--vendor/github.com/containers/buildah/pkg/cli/common.go35
-rw-r--r--vendor/github.com/containers/buildah/pkg/manifests/errors.go16
-rw-r--r--vendor/github.com/containers/buildah/pkg/manifests/manifests.go493
-rw-r--r--vendor/github.com/containers/buildah/pkg/parse/parse.go90
-rw-r--r--vendor/github.com/containers/buildah/pkg/parse/parse_unix.go18
-rw-r--r--vendor/github.com/containers/buildah/pkg/parse/parse_unsupported.go4
-rw-r--r--vendor/github.com/containers/buildah/pkg/supplemented/errors.go17
-rw-r--r--vendor/github.com/containers/buildah/pkg/supplemented/supplemented.go400
-rw-r--r--vendor/github.com/containers/buildah/pull.go23
-rw-r--r--vendor/github.com/containers/buildah/run_linux.go83
-rw-r--r--vendor/github.com/containers/buildah/util/util.go74
-rw-r--r--vendor/github.com/containers/buildah/util/util_linux.go29
-rw-r--r--vendor/github.com/containers/buildah/util/util_unsupported.go20
-rw-r--r--vendor/github.com/containers/common/pkg/capabilities/capabilities.go142
-rw-r--r--vendor/github.com/containers/common/pkg/cgroups/blkio.go149
-rw-r--r--vendor/github.com/containers/common/pkg/cgroups/cgroups.go564
-rw-r--r--vendor/github.com/containers/common/pkg/cgroups/cgroups_supported.go89
-rw-r--r--vendor/github.com/containers/common/pkg/cgroups/cgroups_unsupported.go14
-rw-r--r--vendor/github.com/containers/common/pkg/cgroups/cpu.go123
-rw-r--r--vendor/github.com/containers/common/pkg/cgroups/cpuset.go85
-rw-r--r--vendor/github.com/containers/common/pkg/cgroups/memory.go66
-rw-r--r--vendor/github.com/containers/common/pkg/cgroups/pids.go62
-rw-r--r--vendor/github.com/containers/common/pkg/cgroups/systemd.go79
-rw-r--r--vendor/github.com/containers/common/pkg/config/config.go878
-rw-r--r--vendor/github.com/containers/common/pkg/config/config_linux.go7
-rw-r--r--vendor/github.com/containers/common/pkg/config/config_unix.go15
-rw-r--r--vendor/github.com/containers/common/pkg/config/config_unsupported.go7
-rw-r--r--vendor/github.com/containers/common/pkg/config/config_windows.go10
-rw-r--r--vendor/github.com/containers/common/pkg/config/containers.conf379
-rw-r--r--vendor/github.com/containers/common/pkg/config/default.go346
-rw-r--r--vendor/github.com/containers/common/pkg/config/default_linux.go55
-rw-r--r--vendor/github.com/containers/common/pkg/config/default_unsupported.go13
-rw-r--r--vendor/github.com/containers/common/pkg/config/libpodConfig.go382
-rw-r--r--vendor/github.com/containers/common/pkg/config/util_supported.go69
-rw-r--r--vendor/github.com/containers/common/pkg/config/util_windows.go12
-rw-r--r--vendor/github.com/containers/common/pkg/unshare/getenv_linux_cgo.go22
-rw-r--r--vendor/github.com/containers/common/pkg/unshare/getenv_linux_nocgo.go11
-rw-r--r--vendor/github.com/containers/common/pkg/unshare/unshare_linux.go35
-rw-r--r--vendor/github.com/containers/image/v5/copy/copy.go33
-rw-r--r--vendor/github.com/containers/image/v5/copy/manifest.go14
-rw-r--r--vendor/github.com/containers/image/v5/directory/directory_dest.go21
-rw-r--r--vendor/github.com/containers/image/v5/docker/docker_client.go124
-rw-r--r--vendor/github.com/containers/image/v5/docker/docker_image.go2
-rw-r--r--vendor/github.com/containers/image/v5/docker/docker_image_dest.go11
-rw-r--r--vendor/github.com/containers/image/v5/docker/docker_image_src.go99
-rw-r--r--vendor/github.com/containers/image/v5/docker/errors.go11
-rw-r--r--vendor/github.com/containers/image/v5/docker/tarfile/dest.go3
-rw-r--r--vendor/github.com/containers/image/v5/docker/tarfile/src.go9
-rw-r--r--vendor/github.com/containers/image/v5/image/docker_schema2.go4
-rw-r--r--vendor/github.com/containers/image/v5/image/oci.go4
-rw-r--r--vendor/github.com/containers/image/v5/internal/iolimits/iolimits.go60
-rw-r--r--vendor/github.com/containers/image/v5/openshift/openshift.go4
-rw-r--r--vendor/github.com/containers/image/v5/signature/mechanism_gpgme.go4
-rw-r--r--vendor/github.com/containers/image/v5/signature/mechanism_openpgp.go2
-rw-r--r--vendor/github.com/containers/image/v5/types/types.go2
-rw-r--r--vendor/github.com/containers/image/v5/version/version.go4
-rw-r--r--vendor/github.com/containers/storage/.cirrus.yml55
-rw-r--r--vendor/github.com/containers/storage/.golangci.yml66
-rw-r--r--vendor/github.com/containers/storage/.travis.yml62
-rw-r--r--vendor/github.com/containers/storage/CODE-OF-CONDUCT.md3
-rw-r--r--vendor/github.com/containers/storage/Makefile11
-rw-r--r--vendor/github.com/containers/storage/VERSION2
-rw-r--r--vendor/github.com/containers/storage/drivers/aufs/aufs.go2
-rw-r--r--vendor/github.com/containers/storage/drivers/btrfs/btrfs.go2
-rw-r--r--vendor/github.com/containers/storage/drivers/chown.go9
-rw-r--r--vendor/github.com/containers/storage/drivers/chown_unix.go103
-rw-r--r--vendor/github.com/containers/storage/drivers/devmapper/deviceset.go47
-rw-r--r--vendor/github.com/containers/storage/drivers/devmapper/driver.go2
-rw-r--r--vendor/github.com/containers/storage/drivers/driver.go4
-rw-r--r--vendor/github.com/containers/storage/drivers/overlay/overlay.go15
-rw-r--r--vendor/github.com/containers/storage/drivers/overlayutils/overlayutils.go2
-rw-r--r--vendor/github.com/containers/storage/drivers/vfs/driver.go2
-rw-r--r--vendor/github.com/containers/storage/drivers/zfs/zfs.go2
-rw-r--r--vendor/github.com/containers/storage/drivers/zfs/zfs_linux.go2
-rw-r--r--vendor/github.com/containers/storage/go.mod18
-rw-r--r--vendor/github.com/containers/storage/go.sum113
-rw-r--r--vendor/github.com/containers/storage/images.go22
-rw-r--r--vendor/github.com/containers/storage/images_ffjson.go2
-rw-r--r--vendor/github.com/containers/storage/layers.go47
-rw-r--r--vendor/github.com/containers/storage/pkg/archive/archive.go18
-rw-r--r--vendor/github.com/containers/storage/pkg/archive/changes_unix.go10
-rw-r--r--vendor/github.com/containers/storage/pkg/archive/diff.go2
-rw-r--r--vendor/github.com/containers/storage/pkg/fileutils/fileutils.go30
-rw-r--r--vendor/github.com/containers/storage/pkg/homedir/homedir_linux.go101
-rw-r--r--vendor/github.com/containers/storage/pkg/homedir/homedir_others.go25
-rw-r--r--vendor/github.com/containers/storage/pkg/homedir/homedir_unix.go15
-rw-r--r--vendor/github.com/containers/storage/pkg/homedir/homedir_windows.go3
-rw-r--r--vendor/github.com/containers/storage/pkg/ioutils/fswriters.go4
-rw-r--r--vendor/github.com/containers/storage/pkg/ioutils/fswriters_linux.go11
-rw-r--r--vendor/github.com/containers/storage/pkg/ioutils/fswriters_unsupported.go11
-rw-r--r--vendor/github.com/containers/storage/pkg/lockfile/lockfile_unix.go14
-rw-r--r--vendor/github.com/containers/storage/pkg/mount/flags_freebsd.go49
-rw-r--r--vendor/github.com/containers/storage/pkg/mount/flags_unsupported.go2
-rw-r--r--vendor/github.com/containers/storage/pkg/mount/mount.go76
-rw-r--r--vendor/github.com/containers/storage/pkg/mount/mounter_freebsd.go6
-rw-r--r--vendor/github.com/containers/storage/pkg/mount/mounter_linux.go33
-rw-r--r--vendor/github.com/containers/storage/pkg/mount/mounter_solaris.go34
-rw-r--r--vendor/github.com/containers/storage/pkg/mount/mounter_unsupported.go6
-rw-r--r--vendor/github.com/containers/storage/pkg/mount/mountinfo.go14
-rw-r--r--vendor/github.com/containers/storage/pkg/mount/mountinfo_linux.go113
-rw-r--r--vendor/github.com/containers/storage/pkg/mount/mountinfo_solaris.go37
-rw-r--r--vendor/github.com/containers/storage/pkg/mount/mountinfo_unsupported.go2
-rw-r--r--vendor/github.com/containers/storage/pkg/mount/mountinfo_windows.go6
-rw-r--r--vendor/github.com/containers/storage/pkg/mount/sharedsubtree_linux.go29
-rw-r--r--vendor/github.com/containers/storage/pkg/mount/sharedsubtree_solaris.go58
-rw-r--r--vendor/github.com/containers/storage/pkg/mount/unmount_unix.go22
-rw-r--r--vendor/github.com/containers/storage/pkg/mount/unmount_unsupported.go7
-rw-r--r--vendor/github.com/containers/storage/pkg/reexec/command_linux.go15
-rw-r--r--vendor/github.com/containers/storage/pkg/system/lstat_unix.go3
-rw-r--r--vendor/github.com/containers/storage/pkg/system/process_unix.go2
-rw-r--r--vendor/github.com/containers/storage/pkg/system/rm.go15
-rw-r--r--vendor/github.com/containers/storage/pkg/system/stat_unix.go6
-rw-r--r--vendor/github.com/containers/storage/pkg/system/xattrs_linux.go49
-rw-r--r--vendor/github.com/containers/storage/storage.conf8
-rw-r--r--vendor/github.com/containers/storage/store.go132
-rw-r--r--vendor/github.com/containers/storage/utils.go142
-rw-r--r--vendor/github.com/coreos/go-systemd/v22/LICENSE (renamed from vendor/github.com/coreos/go-systemd/LICENSE)0
-rw-r--r--vendor/github.com/coreos/go-systemd/v22/NOTICE (renamed from vendor/github.com/coreos/go-systemd/NOTICE)0
-rw-r--r--vendor/github.com/coreos/go-systemd/v22/activation/files.go (renamed from vendor/github.com/coreos/go-systemd/activation/files.go)0
-rw-r--r--vendor/github.com/coreos/go-systemd/v22/activation/listeners.go (renamed from vendor/github.com/coreos/go-systemd/activation/listeners.go)0
-rw-r--r--vendor/github.com/coreos/go-systemd/v22/activation/packetconns.go (renamed from vendor/github.com/coreos/go-systemd/activation/packetconns.go)0
-rw-r--r--vendor/github.com/coreos/go-systemd/v22/dbus/dbus.go (renamed from vendor/github.com/coreos/go-systemd/dbus/dbus.go)2
-rw-r--r--vendor/github.com/coreos/go-systemd/v22/dbus/methods.go (renamed from vendor/github.com/coreos/go-systemd/dbus/methods.go)2
-rw-r--r--vendor/github.com/coreos/go-systemd/v22/dbus/properties.go (renamed from vendor/github.com/coreos/go-systemd/dbus/properties.go)4
-rw-r--r--vendor/github.com/coreos/go-systemd/v22/dbus/set.go (renamed from vendor/github.com/coreos/go-systemd/dbus/set.go)0
-rw-r--r--vendor/github.com/coreos/go-systemd/v22/dbus/subscription.go (renamed from vendor/github.com/coreos/go-systemd/dbus/subscription.go)2
-rw-r--r--vendor/github.com/coreos/go-systemd/v22/dbus/subscription_set.go (renamed from vendor/github.com/coreos/go-systemd/dbus/subscription_set.go)0
-rw-r--r--vendor/github.com/coreos/go-systemd/v22/internal/dlopen/dlopen.go (renamed from vendor/github.com/coreos/pkg/dlopen/dlopen.go)0
-rw-r--r--vendor/github.com/coreos/go-systemd/v22/journal/journal.go (renamed from vendor/github.com/coreos/go-systemd/journal/journal.go)0
-rw-r--r--vendor/github.com/coreos/go-systemd/v22/sdjournal/functions.go (renamed from vendor/github.com/coreos/go-systemd/sdjournal/functions.go)2
-rw-r--r--vendor/github.com/coreos/go-systemd/v22/sdjournal/journal.go (renamed from vendor/github.com/coreos/go-systemd/sdjournal/journal.go)0
-rw-r--r--vendor/github.com/coreos/go-systemd/v22/sdjournal/read.go (renamed from vendor/github.com/coreos/go-systemd/sdjournal/read.go)0
-rw-r--r--vendor/github.com/coreos/pkg/LICENSE202
-rw-r--r--vendor/github.com/coreos/pkg/NOTICE5
-rw-r--r--vendor/github.com/coreos/pkg/dlopen/dlopen_example.go56
-rw-r--r--vendor/github.com/docker/docker/oci/caps/defaults.go21
-rw-r--r--vendor/github.com/docker/docker/oci/caps/utils.go169
-rw-r--r--vendor/github.com/docker/docker/pkg/signal/README.md1
-rw-r--r--vendor/github.com/docker/docker/pkg/signal/signal.go54
-rw-r--r--vendor/github.com/docker/docker/pkg/signal/signal_darwin.go41
-rw-r--r--vendor/github.com/docker/docker/pkg/signal/signal_freebsd.go43
-rw-r--r--vendor/github.com/docker/docker/pkg/signal/signal_linux.go83
-rw-r--r--vendor/github.com/docker/docker/pkg/signal/signal_linux_mipsx.go84
-rw-r--r--vendor/github.com/docker/docker/pkg/signal/signal_unix.go21
-rw-r--r--vendor/github.com/docker/docker/pkg/signal/signal_unsupported.go10
-rw-r--r--vendor/github.com/docker/docker/pkg/signal/signal_windows.go26
-rw-r--r--vendor/github.com/docker/docker/pkg/signal/trap.go104
-rw-r--r--vendor/github.com/docker/spdystream/connection.go11
-rw-r--r--vendor/github.com/docker/spdystream/handlers.go4
-rw-r--r--vendor/github.com/fatih/camelcase/.travis.yml3
-rw-r--r--vendor/github.com/fatih/camelcase/LICENSE.md20
-rw-r--r--vendor/github.com/fatih/camelcase/README.md58
-rw-r--r--vendor/github.com/fatih/camelcase/camelcase.go90
-rw-r--r--vendor/github.com/fsnotify/fsnotify/.editorconfig9
-rw-r--r--vendor/github.com/fsnotify/fsnotify/.gitattributes1
-rw-r--r--vendor/github.com/fsnotify/fsnotify/.travis.yml20
-rw-r--r--vendor/github.com/fsnotify/fsnotify/LICENSE2
-rw-r--r--vendor/github.com/fsnotify/fsnotify/README.md71
-rw-r--r--vendor/github.com/fsnotify/fsnotify/fsnotify.go4
-rw-r--r--vendor/github.com/fsnotify/fsnotify/go.mod5
-rw-r--r--vendor/github.com/fsnotify/fsnotify/go.sum2
-rw-r--r--vendor/github.com/fsnotify/fsnotify/inotify_poller.go4
-rw-r--r--vendor/github.com/fsnotify/fsnotify/open_mode_bsd.go2
-rw-r--r--vendor/github.com/fsnotify/fsnotify/open_mode_darwin.go2
-rw-r--r--vendor/github.com/fsouza/go-dockerclient/.golangci.yaml1
-rw-r--r--vendor/github.com/fsouza/go-dockerclient/.travis.yml1
-rw-r--r--vendor/github.com/fsouza/go-dockerclient/AUTHORS1
-rw-r--r--vendor/github.com/fsouza/go-dockerclient/LICENSE2
-rw-r--r--vendor/github.com/fsouza/go-dockerclient/README.md2
-rw-r--r--vendor/github.com/fsouza/go-dockerclient/appveyor.yml5
-rw-r--r--vendor/github.com/fsouza/go-dockerclient/auth.go9
-rw-r--r--vendor/github.com/fsouza/go-dockerclient/container.go11
-rw-r--r--vendor/github.com/fsouza/go-dockerclient/go.mod6
-rw-r--r--vendor/github.com/fsouza/go-dockerclient/go.sum14
-rw-r--r--vendor/github.com/fsouza/go-dockerclient/swarm_service.go1
-rw-r--r--vendor/github.com/fsouza/go-dockerclient/tls.go1
-rw-r--r--vendor/github.com/godbus/dbus/.travis.yml46
-rw-r--r--vendor/github.com/godbus/dbus/go.mod3
-rw-r--r--vendor/github.com/godbus/dbus/v5/.travis.yml50
-rw-r--r--vendor/github.com/godbus/dbus/v5/CONTRIBUTING.md (renamed from vendor/github.com/godbus/dbus/CONTRIBUTING.md)0
-rw-r--r--vendor/github.com/godbus/dbus/v5/LICENSE (renamed from vendor/github.com/godbus/dbus/LICENSE)0
-rw-r--r--vendor/github.com/godbus/dbus/v5/MAINTAINERS (renamed from vendor/github.com/godbus/dbus/MAINTAINERS)0
-rw-r--r--vendor/github.com/godbus/dbus/v5/README.markdown (renamed from vendor/github.com/godbus/dbus/README.markdown)0
-rw-r--r--vendor/github.com/godbus/dbus/v5/auth.go (renamed from vendor/github.com/godbus/dbus/auth.go)4
-rw-r--r--vendor/github.com/godbus/dbus/v5/auth_anonymous.go (renamed from vendor/github.com/godbus/dbus/auth_anonymous.go)0
-rw-r--r--vendor/github.com/godbus/dbus/v5/auth_external.go (renamed from vendor/github.com/godbus/dbus/auth_external.go)0
-rw-r--r--vendor/github.com/godbus/dbus/v5/auth_sha1.go (renamed from vendor/github.com/godbus/dbus/auth_sha1.go)2
-rw-r--r--vendor/github.com/godbus/dbus/v5/call.go (renamed from vendor/github.com/godbus/dbus/call.go)0
-rw-r--r--vendor/github.com/godbus/dbus/v5/conn.go (renamed from vendor/github.com/godbus/dbus/conn.go)161
-rw-r--r--vendor/github.com/godbus/dbus/v5/conn_darwin.go (renamed from vendor/github.com/godbus/dbus/conn_darwin.go)0
-rw-r--r--vendor/github.com/godbus/dbus/v5/conn_other.go (renamed from vendor/github.com/godbus/dbus/conn_other.go)0
-rw-r--r--vendor/github.com/godbus/dbus/v5/conn_unix.go (renamed from vendor/github.com/godbus/dbus/conn_unix.go)5
-rw-r--r--vendor/github.com/godbus/dbus/v5/conn_windows.go (renamed from vendor/github.com/godbus/dbus/conn_windows.go)0
-rw-r--r--vendor/github.com/godbus/dbus/v5/dbus.go (renamed from vendor/github.com/godbus/dbus/dbus.go)1
-rw-r--r--vendor/github.com/godbus/dbus/v5/decoder.go (renamed from vendor/github.com/godbus/dbus/decoder.go)0
-rw-r--r--vendor/github.com/godbus/dbus/v5/default_handler.go (renamed from vendor/github.com/godbus/dbus/default_handler.go)115
-rw-r--r--vendor/github.com/godbus/dbus/v5/doc.go (renamed from vendor/github.com/godbus/dbus/doc.go)2
-rw-r--r--vendor/github.com/godbus/dbus/v5/encoder.go (renamed from vendor/github.com/godbus/dbus/encoder.go)2
-rw-r--r--vendor/github.com/godbus/dbus/v5/export.go (renamed from vendor/github.com/godbus/dbus/export.go)2
-rw-r--r--vendor/github.com/godbus/dbus/v5/go.mod3
-rw-r--r--vendor/github.com/godbus/dbus/v5/go.sum0
-rw-r--r--vendor/github.com/godbus/dbus/v5/homedir.go (renamed from vendor/github.com/godbus/dbus/homedir.go)0
-rw-r--r--vendor/github.com/godbus/dbus/v5/homedir_dynamic.go (renamed from vendor/github.com/godbus/dbus/homedir_dynamic.go)0
-rw-r--r--vendor/github.com/godbus/dbus/v5/homedir_static.go (renamed from vendor/github.com/godbus/dbus/homedir_static.go)0
-rw-r--r--vendor/github.com/godbus/dbus/v5/match.go62
-rw-r--r--vendor/github.com/godbus/dbus/v5/message.go (renamed from vendor/github.com/godbus/dbus/message.go)0
-rw-r--r--vendor/github.com/godbus/dbus/v5/object.go (renamed from vendor/github.com/godbus/dbus/object.go)43
-rw-r--r--vendor/github.com/godbus/dbus/v5/server_interfaces.go (renamed from vendor/github.com/godbus/dbus/server_interfaces.go)8
-rw-r--r--vendor/github.com/godbus/dbus/v5/sig.go (renamed from vendor/github.com/godbus/dbus/sig.go)0
-rw-r--r--vendor/github.com/godbus/dbus/v5/transport_darwin.go (renamed from vendor/github.com/godbus/dbus/transport_darwin.go)0
-rw-r--r--vendor/github.com/godbus/dbus/v5/transport_generic.go (renamed from vendor/github.com/godbus/dbus/transport_generic.go)0
-rw-r--r--vendor/github.com/godbus/dbus/v5/transport_nonce_tcp.go (renamed from vendor/github.com/godbus/dbus/transport_nonce_tcp.go)0
-rw-r--r--vendor/github.com/godbus/dbus/v5/transport_tcp.go (renamed from vendor/github.com/godbus/dbus/transport_tcp.go)0
-rw-r--r--vendor/github.com/godbus/dbus/v5/transport_unix.go (renamed from vendor/github.com/godbus/dbus/transport_unix.go)0
-rw-r--r--vendor/github.com/godbus/dbus/v5/transport_unixcred_dragonfly.go (renamed from vendor/github.com/godbus/dbus/transport_unixcred_dragonfly.go)0
-rw-r--r--vendor/github.com/godbus/dbus/v5/transport_unixcred_freebsd.go (renamed from vendor/github.com/godbus/dbus/transport_unixcred_freebsd.go)0
-rw-r--r--vendor/github.com/godbus/dbus/v5/transport_unixcred_linux.go (renamed from vendor/github.com/godbus/dbus/transport_unixcred_linux.go)0
-rw-r--r--vendor/github.com/godbus/dbus/v5/transport_unixcred_openbsd.go (renamed from vendor/github.com/godbus/dbus/transport_unixcred_openbsd.go)0
-rw-r--r--vendor/github.com/godbus/dbus/v5/variant.go (renamed from vendor/github.com/godbus/dbus/variant.go)4
-rw-r--r--vendor/github.com/godbus/dbus/v5/variant_lexer.go (renamed from vendor/github.com/godbus/dbus/variant_lexer.go)8
-rw-r--r--vendor/github.com/godbus/dbus/v5/variant_parser.go (renamed from vendor/github.com/godbus/dbus/variant_parser.go)0
-rw-r--r--vendor/github.com/gorilla/mux/README.md91
-rw-r--r--vendor/github.com/gorilla/mux/context.go18
-rw-r--r--vendor/github.com/gorilla/mux/go.mod2
-rw-r--r--vendor/github.com/gorilla/mux/middleware.go25
-rw-r--r--vendor/github.com/gorilla/mux/mux.go28
-rw-r--r--vendor/github.com/gorilla/mux/regexp.go65
-rw-r--r--vendor/github.com/gorilla/mux/route.go38
-rw-r--r--vendor/github.com/gorilla/mux/test_helpers.go2
-rw-r--r--vendor/github.com/ishidawataru/sctp/.travis.yml10
-rw-r--r--vendor/github.com/ishidawataru/sctp/NOTICE3
-rw-r--r--vendor/github.com/ishidawataru/sctp/go.mod3
-rw-r--r--vendor/github.com/ishidawataru/sctp/ipsock_linux.go4
-rw-r--r--vendor/github.com/ishidawataru/sctp/sctp.go49
-rw-r--r--vendor/github.com/ishidawataru/sctp/sctp_linux.go69
-rw-r--r--vendor/github.com/ishidawataru/sctp/sctp_unsupported.go39
-rw-r--r--vendor/github.com/klauspost/compress/flate/deflate.go45
-rw-r--r--vendor/github.com/klauspost/compress/flate/fast_encoder.go27
-rw-r--r--vendor/github.com/klauspost/compress/flate/gen_inflate.go274
-rw-r--r--vendor/github.com/klauspost/compress/flate/huffman_bit_writer.go74
-rw-r--r--vendor/github.com/klauspost/compress/flate/huffman_code.go80
-rw-r--r--vendor/github.com/klauspost/compress/flate/huffman_sortByFreq.go178
-rw-r--r--vendor/github.com/klauspost/compress/flate/huffman_sortByLiteral.go201
-rw-r--r--vendor/github.com/klauspost/compress/flate/inflate.go113
-rw-r--r--vendor/github.com/klauspost/compress/flate/inflate_gen.go922
-rw-r--r--vendor/github.com/klauspost/compress/flate/level1.go25
-rw-r--r--vendor/github.com/klauspost/compress/flate/level2.go32
-rw-r--r--vendor/github.com/klauspost/compress/flate/level3.go58
-rw-r--r--vendor/github.com/klauspost/compress/flate/level4.go34
-rw-r--r--vendor/github.com/klauspost/compress/flate/level5.go47
-rw-r--r--vendor/github.com/klauspost/compress/flate/level6.go37
-rw-r--r--vendor/github.com/klauspost/compress/flate/stateless.go67
-rw-r--r--vendor/github.com/klauspost/compress/flate/token.go46
-rw-r--r--vendor/github.com/klauspost/compress/zstd/blockenc.go8
-rw-r--r--vendor/github.com/klauspost/compress/zstd/bytebuf.go4
-rw-r--r--vendor/github.com/klauspost/compress/zstd/decoder.go4
-rw-r--r--vendor/github.com/klauspost/compress/zstd/enc_better.go521
-rw-r--r--vendor/github.com/klauspost/compress/zstd/enc_dfast.go98
-rw-r--r--vendor/github.com/klauspost/compress/zstd/enc_fast.go207
-rw-r--r--vendor/github.com/klauspost/compress/zstd/encoder.go17
-rw-r--r--vendor/github.com/klauspost/compress/zstd/encoder_options.go26
-rw-r--r--vendor/github.com/klauspost/compress/zstd/framedec.go2
-rw-r--r--vendor/github.com/klauspost/compress/zstd/fse_decoder.go2
-rw-r--r--vendor/github.com/klauspost/compress/zstd/fse_encoder.go8
-rw-r--r--vendor/github.com/klauspost/compress/zstd/internal/xxhash/xxhash_amd64.s8
-rw-r--r--vendor/github.com/klauspost/compress/zstd/zstd.go42
-rw-r--r--vendor/github.com/klauspost/pgzip/README.md17
-rw-r--r--vendor/github.com/klauspost/pgzip/gzip.go78
-rw-r--r--vendor/github.com/mattn/go-shellwords/go.mod2
-rw-r--r--vendor/github.com/mattn/go-shellwords/shellwords.go28
-rw-r--r--vendor/github.com/mattn/go-shellwords/util_go15.go29
-rw-r--r--vendor/github.com/mattn/go-shellwords/util_posix.go7
-rw-r--r--vendor/github.com/mattn/go-shellwords/util_windows.go7
-rw-r--r--vendor/github.com/mtrmac/gpgme/.appveyor.yml40
-rw-r--r--vendor/github.com/mtrmac/gpgme/.travis.yml32
-rw-r--r--vendor/github.com/mtrmac/gpgme/data.go18
-rw-r--r--vendor/github.com/mtrmac/gpgme/go.mod3
-rw-r--r--vendor/github.com/mtrmac/gpgme/go_gpgme.c22
-rw-r--r--vendor/github.com/mtrmac/gpgme/go_gpgme.h12
-rw-r--r--vendor/github.com/mtrmac/gpgme/gpgme.go346
-rw-r--r--vendor/github.com/mtrmac/gpgme/unset_agent_info.go18
-rw-r--r--vendor/github.com/mtrmac/gpgme/unset_agent_info_windows.go14
-rw-r--r--vendor/github.com/onsi/ginkgo/.travis.yml18
-rw-r--r--vendor/github.com/onsi/ginkgo/CHANGELOG.md5
-rw-r--r--vendor/github.com/onsi/ginkgo/config/config.go2
-rw-r--r--vendor/github.com/onsi/ginkgo/go.mod9
-rw-r--r--vendor/github.com/onsi/ginkgo/go.sum26
-rw-r--r--vendor/github.com/onsi/gomega/CHANGELOG.md7
-rw-r--r--vendor/github.com/onsi/gomega/gomega_dsl.go2
-rw-r--r--vendor/github.com/onsi/gomega/matchers.go14
-rw-r--r--vendor/github.com/onsi/gomega/matchers/consist_of.go91
-rw-r--r--vendor/github.com/onsi/gomega/matchers/contain_elements_matcher.go44
-rw-r--r--vendor/github.com/onsi/gomega/matchers/support/goraph/bipartitegraph/bipartitegraph.go26
-rw-r--r--vendor/github.com/onsi/gomega/matchers/support/goraph/bipartitegraph/bipartitegraphmatching.go37
-rw-r--r--vendor/github.com/onsi/gomega/matchers/support/goraph/edge/edge.go8
-rw-r--r--vendor/github.com/onsi/gomega/matchers/support/goraph/node/node.go3
-rw-r--r--vendor/github.com/opencontainers/selinux/go-selinux/label/label.go134
-rw-r--r--vendor/github.com/opencontainers/selinux/go-selinux/label/label_selinux.go122
-rw-r--r--vendor/github.com/opencontainers/selinux/go-selinux/label/label_stub.go54
-rw-r--r--vendor/github.com/opencontainers/selinux/go-selinux/selinux_linux.go208
-rw-r--r--vendor/github.com/opencontainers/selinux/go-selinux/selinux_stub.go14
-rw-r--r--vendor/github.com/opencontainers/selinux/go-selinux/xattrs.go72
-rw-r--r--vendor/github.com/opencontainers/selinux/pkg/pwalk/README.md42
-rw-r--r--vendor/github.com/opencontainers/selinux/pkg/pwalk/pwalk.go99
-rw-r--r--vendor/github.com/openshift/imagebuilder/builder.go6
-rw-r--r--vendor/github.com/openshift/imagebuilder/dispatchers.go84
-rw-r--r--vendor/github.com/openshift/imagebuilder/vendor.conf5
-rw-r--r--vendor/github.com/rootless-containers/rootlesskit/pkg/port/builtin/child/child.go7
-rw-r--r--vendor/github.com/rootless-containers/rootlesskit/pkg/port/builtin/msg/msg.go11
-rw-r--r--vendor/github.com/sirupsen/logrus/.golangci.yml40
-rw-r--r--vendor/github.com/sirupsen/logrus/.travis.yml14
-rw-r--r--vendor/github.com/sirupsen/logrus/README.md44
-rw-r--r--vendor/github.com/sirupsen/logrus/entry.go49
-rw-r--r--vendor/github.com/sirupsen/logrus/exported.go2
-rw-r--r--vendor/github.com/sirupsen/logrus/go.mod3
-rw-r--r--vendor/github.com/sirupsen/logrus/go.sum6
-rw-r--r--vendor/github.com/sirupsen/logrus/json_formatter.go4
-rw-r--r--vendor/github.com/sirupsen/logrus/logger.go11
-rw-r--r--vendor/github.com/sirupsen/logrus/logrus.go2
-rw-r--r--vendor/github.com/sirupsen/logrus/terminal_check_bsd.go2
-rw-r--r--vendor/github.com/sirupsen/logrus/terminal_check_js.go7
-rw-r--r--vendor/github.com/sirupsen/logrus/terminal_check_unix.go2
-rw-r--r--vendor/github.com/sirupsen/logrus/text_formatter.go47
-rw-r--r--vendor/github.com/sirupsen/logrus/writer.go6
-rw-r--r--vendor/github.com/spf13/cobra/.gitignore5
-rw-r--r--vendor/github.com/spf13/cobra/.travis.yml9
-rw-r--r--vendor/github.com/spf13/cobra/README.md105
-rw-r--r--vendor/github.com/spf13/cobra/bash_completions.go15
-rw-r--r--vendor/github.com/spf13/cobra/cobra.go4
-rw-r--r--vendor/github.com/spf13/cobra/command.go49
-rw-r--r--vendor/github.com/spf13/cobra/go.mod5
-rw-r--r--vendor/github.com/spf13/cobra/go.sum120
-rw-r--r--vendor/github.com/stretchr/testify/assert/assertion_format.go78
-rw-r--r--vendor/github.com/stretchr/testify/assert/assertion_forward.go156
-rw-r--r--vendor/github.com/stretchr/testify/assert/assertions.go218
-rw-r--r--vendor/github.com/stretchr/testify/assert/forward_assertions.go2
-rw-r--r--vendor/github.com/stretchr/testify/require/forward_requirements.go2
-rw-r--r--vendor/github.com/stretchr/testify/require/require.go210
-rw-r--r--vendor/github.com/stretchr/testify/require/require_forward.go156
-rw-r--r--vendor/github.com/stretchr/testify/require/requirements.go2
-rw-r--r--vendor/github.com/uber/jaeger-lib/metrics/metrics.go2
-rw-r--r--vendor/github.com/vbauerster/mpb/v4/bar_option.go7
-rw-r--r--vendor/github.com/vbauerster/mpb/v4/decor/decorator.go27
-rw-r--r--vendor/github.com/vbauerster/mpb/v4/decor/merge.go45
-rw-r--r--vendor/github.com/vbauerster/mpb/v4/go.mod1
-rw-r--r--vendor/github.com/vbauerster/mpb/v4/go.sum2
-rw-r--r--vendor/github.com/vbauerster/mpb/v4/proxyreader.go8
-rw-r--r--vendor/github.com/xeipuuv/gojsonschema/.travis.yml7
-rw-r--r--vendor/github.com/xeipuuv/gojsonschema/README.md3
-rw-r--r--vendor/github.com/xeipuuv/gojsonschema/draft.go8
-rw-r--r--vendor/github.com/xeipuuv/gojsonschema/errors.go104
-rw-r--r--vendor/github.com/xeipuuv/gojsonschema/format_checkers.go103
-rw-r--r--vendor/github.com/xeipuuv/gojsonschema/go.mod7
-rw-r--r--vendor/github.com/xeipuuv/gojsonschema/go.sum11
-rw-r--r--vendor/github.com/xeipuuv/gojsonschema/jsonContext.go1
-rw-r--r--vendor/github.com/xeipuuv/gojsonschema/jsonLoader.go42
-rw-r--r--vendor/github.com/xeipuuv/gojsonschema/locales.go165
-rw-r--r--vendor/github.com/xeipuuv/gojsonschema/result.go37
-rw-r--r--vendor/github.com/xeipuuv/gojsonschema/schema.go75
-rw-r--r--vendor/github.com/xeipuuv/gojsonschema/schemaLoader.go3
-rw-r--r--vendor/github.com/xeipuuv/gojsonschema/schemaPool.go10
-rw-r--r--vendor/github.com/xeipuuv/gojsonschema/subSchema.go117
-rw-r--r--vendor/github.com/xeipuuv/gojsonschema/types.go4
-rw-r--r--vendor/github.com/xeipuuv/gojsonschema/utils.go61
-rw-r--r--vendor/github.com/xeipuuv/gojsonschema/validation.go199
416 files changed, 13914 insertions, 6225 deletions
diff --git a/vendor/github.com/acarl005/stripansi/LICENSE b/vendor/github.com/acarl005/stripansi/LICENSE
new file mode 100644
index 000000000..00abe0dbf
--- /dev/null
+++ b/vendor/github.com/acarl005/stripansi/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2018 Andrew Carlson
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/vendor/github.com/acarl005/stripansi/README.md b/vendor/github.com/acarl005/stripansi/README.md
new file mode 100644
index 000000000..8bdb1f505
--- /dev/null
+++ b/vendor/github.com/acarl005/stripansi/README.md
@@ -0,0 +1,30 @@
+Strip ANSI
+==========
+
+This Go package removes ANSI escape codes from strings.
+
+Ideally, we would prevent these from appearing in any text we want to process.
+However, sometimes this can't be helped, and we need to be able to deal with that noise.
+This will use a regexp to remove those unwanted escape codes.
+
+
+## Install
+
+```sh
+$ go get -u github.com/acarl005/stripansi
+```
+
+## Usage
+
+```go
+import (
+ "fmt"
+ "github.com/acarl005/stripansi"
+)
+
+func main() {
+ msg := "\x1b[38;5;140m foo\x1b[0m bar"
+ cleanMsg := stripansi.Strip(msg)
+ fmt.Println(cleanMsg) // " foo bar"
+}
+```
diff --git a/vendor/github.com/acarl005/stripansi/stripansi.go b/vendor/github.com/acarl005/stripansi/stripansi.go
new file mode 100644
index 000000000..235732a78
--- /dev/null
+++ b/vendor/github.com/acarl005/stripansi/stripansi.go
@@ -0,0 +1,13 @@
+package stripansi
+
+import (
+ "regexp"
+)
+
+const ansi = "[\u001B\u009B][[\\]()#;?]*(?:(?:(?:[a-zA-Z\\d]*(?:;[a-zA-Z\\d]*)*)?\u0007)|(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PRZcf-ntqry=><~]))"
+
+var re = regexp.MustCompile(ansi)
+
+func Strip(str string) string {
+ return re.ReplaceAllString(str, "")
+}
diff --git a/vendor/github.com/blang/semver/.travis.yml b/vendor/github.com/blang/semver/.travis.yml
deleted file mode 100644
index 102fb9a69..000000000
--- a/vendor/github.com/blang/semver/.travis.yml
+++ /dev/null
@@ -1,21 +0,0 @@
-language: go
-matrix:
- include:
- - go: 1.4.3
- - go: 1.5.4
- - go: 1.6.3
- - go: 1.7
- - go: tip
- allow_failures:
- - go: tip
-install:
-- go get golang.org/x/tools/cmd/cover
-- go get github.com/mattn/goveralls
-script:
-- echo "Test and track coverage" ; $HOME/gopath/bin/goveralls -package "." -service=travis-ci
- -repotoken $COVERALLS_TOKEN
-- echo "Build examples" ; cd examples && go build
-- echo "Check if gofmt'd" ; diff -u <(echo -n) <(gofmt -d -s .)
-env:
- global:
- secure: HroGEAUQpVq9zX1b1VIkraLiywhGbzvNnTZq2TMxgK7JHP8xqNplAeF1izrR2i4QLL9nsY+9WtYss4QuPvEtZcVHUobw6XnL6radF7jS1LgfYZ9Y7oF+zogZ2I5QUMRLGA7rcxQ05s7mKq3XZQfeqaNts4bms/eZRefWuaFZbkw=
diff --git a/vendor/github.com/blang/semver/README.md b/vendor/github.com/blang/semver/README.md
index 08b2e4a3d..4399639e2 100644
--- a/vendor/github.com/blang/semver/README.md
+++ b/vendor/github.com/blang/semver/README.md
@@ -1,4 +1,4 @@
-semver for golang [![Build Status](https://travis-ci.org/blang/semver.svg?branch=master)](https://travis-ci.org/blang/semver) [![GoDoc](https://godoc.org/github.com/blang/semver?status.png)](https://godoc.org/github.com/blang/semver) [![Coverage Status](https://img.shields.io/coveralls/blang/semver.svg)](https://coveralls.io/r/blang/semver?branch=master)
+semver for golang [![Build Status](https://drone.io/github.com/blang/semver/status.png)](https://drone.io/github.com/blang/semver/latest) [![GoDoc](https://godoc.org/github.com/blang/semver?status.png)](https://godoc.org/github.com/blang/semver) [![Coverage Status](https://img.shields.io/coveralls/blang/semver.svg)](https://coveralls.io/r/blang/semver?branch=master)
======
semver is a [Semantic Versioning](http://semver.org/) library written in golang. It fully covers spec version `2.0.0`.
@@ -41,7 +41,6 @@ Features
- Compare Helper Methods
- InPlace manipulation
- Ranges `>=1.0.0 <2.0.0 || >=3.0.0 !3.0.1-beta.1`
-- Wildcards `>=1.x`, `<=2.5.x`
- Sortable (implements sort.Interface)
- database/sql compatible (sql.Scanner/Valuer)
- encoding/json compatible (json.Marshaler/Unmarshaler)
@@ -60,8 +59,6 @@ A condition is composed of an operator and a version. The supported operators ar
- `1.0.0`, `=1.0.0`, `==1.0.0` Equal to `1.0.0`
- `!1.0.0`, `!=1.0.0` Not equal to `1.0.0`. Excludes version `1.0.0`.
-Note that spaces between the operator and the version will be gracefully tolerated.
-
A `Range` can link multiple `Ranges` separated by space:
Ranges can be linked by logical AND:
diff --git a/vendor/github.com/blang/semver/package.json b/vendor/github.com/blang/semver/package.json
deleted file mode 100644
index 1cf8ebdd9..000000000
--- a/vendor/github.com/blang/semver/package.json
+++ /dev/null
@@ -1,17 +0,0 @@
-{
- "author": "blang",
- "bugs": {
- "URL": "https://github.com/blang/semver/issues",
- "url": "https://github.com/blang/semver/issues"
- },
- "gx": {
- "dvcsimport": "github.com/blang/semver"
- },
- "gxVersion": "0.10.0",
- "language": "go",
- "license": "MIT",
- "name": "semver",
- "releaseCmd": "git commit -a -m \"gx publish $VERSION\"",
- "version": "3.5.1"
-}
-
diff --git a/vendor/github.com/blang/semver/range.go b/vendor/github.com/blang/semver/range.go
index fca406d47..0a8eaa1c9 100644
--- a/vendor/github.com/blang/semver/range.go
+++ b/vendor/github.com/blang/semver/range.go
@@ -2,33 +2,10 @@ package semver
import (
"fmt"
- "strconv"
"strings"
"unicode"
)
-type wildcardType int
-
-const (
- noneWildcard wildcardType = iota
- majorWildcard wildcardType = 1
- minorWildcard wildcardType = 2
- patchWildcard wildcardType = 3
-)
-
-func wildcardTypefromInt(i int) wildcardType {
- switch i {
- case 1:
- return majorWildcard
- case 2:
- return minorWildcard
- case 3:
- return patchWildcard
- default:
- return noneWildcard
- }
-}
-
type comparator func(Version, Version) bool
var (
@@ -115,12 +92,8 @@ func ParseRange(s string) (Range, error) {
if err != nil {
return nil, err
}
- expandedParts, err := expandWildcardVersion(orParts)
- if err != nil {
- return nil, err
- }
var orFn Range
- for _, p := range expandedParts {
+ for _, p := range orParts {
var andFn Range
for _, ap := range p {
opStr, vStr, err := splitComparatorVersion(ap)
@@ -191,39 +164,20 @@ func buildVersionRange(opStr, vStr string) (*versionRange, error) {
}
-// inArray checks if a byte is contained in an array of bytes
-func inArray(s byte, list []byte) bool {
- for _, el := range list {
- if el == s {
- return true
- }
- }
- return false
-}
-
-// splitAndTrim splits a range string by spaces and cleans whitespaces
+// splitAndTrim splits a range string by spaces and cleans leading and trailing spaces
func splitAndTrim(s string) (result []string) {
last := 0
- var lastChar byte
- excludeFromSplit := []byte{'>', '<', '='}
for i := 0; i < len(s); i++ {
- if s[i] == ' ' && !inArray(lastChar, excludeFromSplit) {
+ if s[i] == ' ' {
if last < i-1 {
result = append(result, s[last:i])
}
last = i + 1
- } else if s[i] != ' ' {
- lastChar = s[i]
}
}
if last < len(s)-1 {
result = append(result, s[last:])
}
-
- for i, v := range result {
- result[i] = strings.Replace(v, " ", "", -1)
- }
-
// parts := strings.Split(s, " ")
// for _, x := range parts {
// if s := strings.TrimSpace(x); len(s) != 0 {
@@ -234,6 +188,7 @@ func splitAndTrim(s string) (result []string) {
}
// splitComparatorVersion splits the comparator from the version.
+// Spaces between the comparator and the version are not allowed.
// Input must be free of leading or trailing spaces.
func splitComparatorVersion(s string) (string, string, error) {
i := strings.IndexFunc(s, unicode.IsDigit)
@@ -243,144 +198,6 @@ func splitComparatorVersion(s string) (string, string, error) {
return strings.TrimSpace(s[0:i]), s[i:], nil
}
-// getWildcardType will return the type of wildcard that the
-// passed version contains
-func getWildcardType(vStr string) wildcardType {
- parts := strings.Split(vStr, ".")
- nparts := len(parts)
- wildcard := parts[nparts-1]
-
- possibleWildcardType := wildcardTypefromInt(nparts)
- if wildcard == "x" {
- return possibleWildcardType
- }
-
- return noneWildcard
-}
-
-// createVersionFromWildcard will convert a wildcard version
-// into a regular version, replacing 'x's with '0's, handling
-// special cases like '1.x.x' and '1.x'
-func createVersionFromWildcard(vStr string) string {
- // handle 1.x.x
- vStr2 := strings.Replace(vStr, ".x.x", ".x", 1)
- vStr2 = strings.Replace(vStr2, ".x", ".0", 1)
- parts := strings.Split(vStr2, ".")
-
- // handle 1.x
- if len(parts) == 2 {
- return vStr2 + ".0"
- }
-
- return vStr2
-}
-
-// incrementMajorVersion will increment the major version
-// of the passed version
-func incrementMajorVersion(vStr string) (string, error) {
- parts := strings.Split(vStr, ".")
- i, err := strconv.Atoi(parts[0])
- if err != nil {
- return "", err
- }
- parts[0] = strconv.Itoa(i + 1)
-
- return strings.Join(parts, "."), nil
-}
-
-// incrementMajorVersion will increment the minor version
-// of the passed version
-func incrementMinorVersion(vStr string) (string, error) {
- parts := strings.Split(vStr, ".")
- i, err := strconv.Atoi(parts[1])
- if err != nil {
- return "", err
- }
- parts[1] = strconv.Itoa(i + 1)
-
- return strings.Join(parts, "."), nil
-}
-
-// expandWildcardVersion will expand wildcards inside versions
-// following these rules:
-//
-// * when dealing with patch wildcards:
-// >= 1.2.x will become >= 1.2.0
-// <= 1.2.x will become < 1.3.0
-// > 1.2.x will become >= 1.3.0
-// < 1.2.x will become < 1.2.0
-// != 1.2.x will become < 1.2.0 >= 1.3.0
-//
-// * when dealing with minor wildcards:
-// >= 1.x will become >= 1.0.0
-// <= 1.x will become < 2.0.0
-// > 1.x will become >= 2.0.0
-// < 1.0 will become < 1.0.0
-// != 1.x will become < 1.0.0 >= 2.0.0
-//
-// * when dealing with wildcards without
-// version operator:
-// 1.2.x will become >= 1.2.0 < 1.3.0
-// 1.x will become >= 1.0.0 < 2.0.0
-func expandWildcardVersion(parts [][]string) ([][]string, error) {
- var expandedParts [][]string
- for _, p := range parts {
- var newParts []string
- for _, ap := range p {
- if strings.Index(ap, "x") != -1 {
- opStr, vStr, err := splitComparatorVersion(ap)
- if err != nil {
- return nil, err
- }
-
- versionWildcardType := getWildcardType(vStr)
- flatVersion := createVersionFromWildcard(vStr)
-
- var resultOperator string
- var shouldIncrementVersion bool
- switch opStr {
- case ">":
- resultOperator = ">="
- shouldIncrementVersion = true
- case ">=":
- resultOperator = ">="
- case "<":
- resultOperator = "<"
- case "<=":
- resultOperator = "<"
- shouldIncrementVersion = true
- case "", "=", "==":
- newParts = append(newParts, ">="+flatVersion)
- resultOperator = "<"
- shouldIncrementVersion = true
- case "!=", "!":
- newParts = append(newParts, "<"+flatVersion)
- resultOperator = ">="
- shouldIncrementVersion = true
- }
-
- var resultVersion string
- if shouldIncrementVersion {
- switch versionWildcardType {
- case patchWildcard:
- resultVersion, _ = incrementMinorVersion(flatVersion)
- case minorWildcard:
- resultVersion, _ = incrementMajorVersion(flatVersion)
- }
- } else {
- resultVersion = flatVersion
- }
-
- ap = resultOperator + resultVersion
- }
- newParts = append(newParts, ap)
- }
- expandedParts = append(expandedParts, newParts)
- }
-
- return expandedParts, nil
-}
-
func parseComparator(s string) comparator {
switch s {
case "==":
@@ -405,12 +222,3 @@ func parseComparator(s string) comparator {
return nil
}
-
-// MustParseRange is like ParseRange but panics if the range cannot be parsed.
-func MustParseRange(s string) Range {
- r, err := ParseRange(s)
- if err != nil {
- panic(`semver: ParseRange(` + s + `): ` + err.Error())
- }
- return r
-}
diff --git a/vendor/github.com/blang/semver/semver.go b/vendor/github.com/blang/semver/semver.go
index 8ee0842e6..bbf85ce97 100644
--- a/vendor/github.com/blang/semver/semver.go
+++ b/vendor/github.com/blang/semver/semver.go
@@ -200,29 +200,6 @@ func Make(s string) (Version, error) {
return Parse(s)
}
-// ParseTolerant allows for certain version specifications that do not strictly adhere to semver
-// specs to be parsed by this library. It does so by normalizing versions before passing them to
-// Parse(). It currently trims spaces, removes a "v" prefix, and adds a 0 patch number to versions
-// with only major and minor components specified
-func ParseTolerant(s string) (Version, error) {
- s = strings.TrimSpace(s)
- s = strings.TrimPrefix(s, "v")
-
- // Split into major.minor.(patch+pr+meta)
- parts := strings.SplitN(s, ".", 3)
- if len(parts) < 3 {
- if strings.ContainsAny(parts[len(parts)-1], "+-") {
- return Version{}, errors.New("Short version cannot contain PreRelease/Build meta data")
- }
- for len(parts) < 3 {
- parts = append(parts, "0")
- }
- s = strings.Join(parts, ".")
- }
-
- return Parse(s)
-}
-
// Parse parses version string and returns a validated Version or error
func Parse(s string) (Version, error) {
if len(s) == 0 {
diff --git a/vendor/github.com/containerd/containerd/log/context.go b/vendor/github.com/containerd/containerd/log/context.go
new file mode 100644
index 000000000..31f1a3ac0
--- /dev/null
+++ b/vendor/github.com/containerd/containerd/log/context.go
@@ -0,0 +1,90 @@
+/*
+ Copyright The containerd Authors.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+package log
+
+import (
+ "context"
+ "sync/atomic"
+
+ "github.com/sirupsen/logrus"
+)
+
+var (
+ // G is an alias for GetLogger.
+ //
+ // We may want to define this locally to a package to get package tagged log
+ // messages.
+ G = GetLogger
+
+ // L is an alias for the standard logger.
+ L = logrus.NewEntry(logrus.StandardLogger())
+)
+
+type (
+ loggerKey struct{}
+)
+
+// TraceLevel is the log level for tracing. Trace level is lower than debug level,
+// and is usually used to trace detailed behavior of the program.
+const TraceLevel = logrus.Level(uint32(logrus.DebugLevel + 1))
+
+// RFC3339NanoFixed is time.RFC3339Nano with nanoseconds padded using zeros to
+// ensure the formatted time is always the same number of characters.
+const RFC3339NanoFixed = "2006-01-02T15:04:05.000000000Z07:00"
+
+// ParseLevel takes a string level and returns the Logrus log level constant.
+// It supports trace level.
+func ParseLevel(lvl string) (logrus.Level, error) {
+ if lvl == "trace" {
+ return TraceLevel, nil
+ }
+ return logrus.ParseLevel(lvl)
+}
+
+// WithLogger returns a new context with the provided logger. Use in
+// combination with logger.WithField(s) for great effect.
+func WithLogger(ctx context.Context, logger *logrus.Entry) context.Context {
+ return context.WithValue(ctx, loggerKey{}, logger)
+}
+
+// GetLogger retrieves the current logger from the context. If no logger is
+// available, the default logger is returned.
+func GetLogger(ctx context.Context) *logrus.Entry {
+ logger := ctx.Value(loggerKey{})
+
+ if logger == nil {
+ return L
+ }
+
+ return logger.(*logrus.Entry)
+}
+
+// Trace logs a message at level Trace with the log entry passed-in.
+func Trace(e *logrus.Entry, args ...interface{}) {
+ level := logrus.Level(atomic.LoadUint32((*uint32)(&e.Logger.Level)))
+ if level >= TraceLevel {
+ e.Debug(args...)
+ }
+}
+
+// Tracef logs a message at level Trace with the log entry passed-in.
+func Tracef(e *logrus.Entry, format string, args ...interface{}) {
+ level := logrus.Level(atomic.LoadUint32((*uint32)(&e.Logger.Level)))
+ if level >= TraceLevel {
+ e.Debugf(format, args...)
+ }
+}
diff --git a/vendor/github.com/containerd/containerd/platforms/compare.go b/vendor/github.com/containerd/containerd/platforms/compare.go
new file mode 100644
index 000000000..3ad22a10d
--- /dev/null
+++ b/vendor/github.com/containerd/containerd/platforms/compare.go
@@ -0,0 +1,229 @@
+/*
+ Copyright The containerd Authors.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+package platforms
+
+import specs "github.com/opencontainers/image-spec/specs-go/v1"
+
+// MatchComparer is able to match and compare platforms to
+// filter and sort platforms.
+type MatchComparer interface {
+ Matcher
+
+ Less(specs.Platform, specs.Platform) bool
+}
+
+// Only returns a match comparer for a single platform
+// using default resolution logic for the platform.
+//
+// For ARMv8, will also match ARMv7, ARMv6 and ARMv5 (for 32bit runtimes)
+// For ARMv7, will also match ARMv6 and ARMv5
+// For ARMv6, will also match ARMv5
+func Only(platform specs.Platform) MatchComparer {
+ platform = Normalize(platform)
+ if platform.Architecture == "arm" {
+ if platform.Variant == "v8" {
+ return orderedPlatformComparer{
+ matchers: []Matcher{
+ &matcher{
+ Platform: platform,
+ },
+ &matcher{
+ Platform: specs.Platform{
+ Architecture: platform.Architecture,
+ OS: platform.OS,
+ OSVersion: platform.OSVersion,
+ OSFeatures: platform.OSFeatures,
+ Variant: "v7",
+ },
+ },
+ &matcher{
+ Platform: specs.Platform{
+ Architecture: platform.Architecture,
+ OS: platform.OS,
+ OSVersion: platform.OSVersion,
+ OSFeatures: platform.OSFeatures,
+ Variant: "v6",
+ },
+ },
+ &matcher{
+ Platform: specs.Platform{
+ Architecture: platform.Architecture,
+ OS: platform.OS,
+ OSVersion: platform.OSVersion,
+ OSFeatures: platform.OSFeatures,
+ Variant: "v5",
+ },
+ },
+ },
+ }
+ }
+ if platform.Variant == "v7" {
+ return orderedPlatformComparer{
+ matchers: []Matcher{
+ &matcher{
+ Platform: platform,
+ },
+ &matcher{
+ Platform: specs.Platform{
+ Architecture: platform.Architecture,
+ OS: platform.OS,
+ OSVersion: platform.OSVersion,
+ OSFeatures: platform.OSFeatures,
+ Variant: "v6",
+ },
+ },
+ &matcher{
+ Platform: specs.Platform{
+ Architecture: platform.Architecture,
+ OS: platform.OS,
+ OSVersion: platform.OSVersion,
+ OSFeatures: platform.OSFeatures,
+ Variant: "v5",
+ },
+ },
+ },
+ }
+ }
+ if platform.Variant == "v6" {
+ return orderedPlatformComparer{
+ matchers: []Matcher{
+ &matcher{
+ Platform: platform,
+ },
+ &matcher{
+ Platform: specs.Platform{
+ Architecture: platform.Architecture,
+ OS: platform.OS,
+ OSVersion: platform.OSVersion,
+ OSFeatures: platform.OSFeatures,
+ Variant: "v5",
+ },
+ },
+ },
+ }
+ }
+ }
+
+ return singlePlatformComparer{
+ Matcher: &matcher{
+ Platform: platform,
+ },
+ }
+}
+
+// Ordered returns a platform MatchComparer which matches any of the platforms
+// but orders them in order they are provided.
+func Ordered(platforms ...specs.Platform) MatchComparer {
+ matchers := make([]Matcher, len(platforms))
+ for i := range platforms {
+ matchers[i] = NewMatcher(platforms[i])
+ }
+ return orderedPlatformComparer{
+ matchers: matchers,
+ }
+}
+
+// Any returns a platform MatchComparer which matches any of the platforms
+// with no preference for ordering.
+func Any(platforms ...specs.Platform) MatchComparer {
+ matchers := make([]Matcher, len(platforms))
+ for i := range platforms {
+ matchers[i] = NewMatcher(platforms[i])
+ }
+ return anyPlatformComparer{
+ matchers: matchers,
+ }
+}
+
+// All is a platform MatchComparer which matches all platforms
+// with preference for ordering.
+var All MatchComparer = allPlatformComparer{}
+
+type singlePlatformComparer struct {
+ Matcher
+}
+
+func (c singlePlatformComparer) Less(p1, p2 specs.Platform) bool {
+ return c.Match(p1) && !c.Match(p2)
+}
+
+type orderedPlatformComparer struct {
+ matchers []Matcher
+}
+
+func (c orderedPlatformComparer) Match(platform specs.Platform) bool {
+ for _, m := range c.matchers {
+ if m.Match(platform) {
+ return true
+ }
+ }
+ return false
+}
+
+func (c orderedPlatformComparer) Less(p1 specs.Platform, p2 specs.Platform) bool {
+ for _, m := range c.matchers {
+ p1m := m.Match(p1)
+ p2m := m.Match(p2)
+ if p1m && !p2m {
+ return true
+ }
+ if p1m || p2m {
+ return false
+ }
+ }
+ return false
+}
+
+type anyPlatformComparer struct {
+ matchers []Matcher
+}
+
+func (c anyPlatformComparer) Match(platform specs.Platform) bool {
+ for _, m := range c.matchers {
+ if m.Match(platform) {
+ return true
+ }
+ }
+ return false
+}
+
+func (c anyPlatformComparer) Less(p1, p2 specs.Platform) bool {
+ var p1m, p2m bool
+ for _, m := range c.matchers {
+ if !p1m && m.Match(p1) {
+ p1m = true
+ }
+ if !p2m && m.Match(p2) {
+ p2m = true
+ }
+ if p1m && p2m {
+ return false
+ }
+ }
+ // If one matches, and the other does, sort match first
+ return p1m && !p2m
+}
+
+type allPlatformComparer struct{}
+
+func (allPlatformComparer) Match(specs.Platform) bool {
+ return true
+}
+
+func (allPlatformComparer) Less(specs.Platform, specs.Platform) bool {
+ return false
+}
diff --git a/vendor/github.com/containerd/containerd/platforms/cpuinfo.go b/vendor/github.com/containerd/containerd/platforms/cpuinfo.go
new file mode 100644
index 000000000..69b336d67
--- /dev/null
+++ b/vendor/github.com/containerd/containerd/platforms/cpuinfo.go
@@ -0,0 +1,117 @@
+/*
+ Copyright The containerd Authors.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+package platforms
+
+import (
+ "bufio"
+ "os"
+ "runtime"
+ "strings"
+
+ "github.com/containerd/containerd/errdefs"
+ "github.com/containerd/containerd/log"
+ "github.com/pkg/errors"
+)
+
+// Present the ARM instruction set architecture, eg: v7, v8
+var cpuVariant string
+
+func init() {
+ if isArmArch(runtime.GOARCH) {
+ cpuVariant = getCPUVariant()
+ } else {
+ cpuVariant = ""
+ }
+}
+
+// For Linux, the kernel has already detected the ABI, ISA and Features.
+// So we don't need to access the ARM registers to detect platform information
+// by ourselves. We can just parse these information from /proc/cpuinfo
+func getCPUInfo(pattern string) (info string, err error) {
+ if !isLinuxOS(runtime.GOOS) {
+ return "", errors.Wrapf(errdefs.ErrNotImplemented, "getCPUInfo for OS %s", runtime.GOOS)
+ }
+
+ cpuinfo, err := os.Open("/proc/cpuinfo")
+ if err != nil {
+ return "", err
+ }
+ defer cpuinfo.Close()
+
+ // Start to Parse the Cpuinfo line by line. For SMP SoC, we parse
+ // the first core is enough.
+ scanner := bufio.NewScanner(cpuinfo)
+ for scanner.Scan() {
+ newline := scanner.Text()
+ list := strings.Split(newline, ":")
+
+ if len(list) > 1 && strings.EqualFold(strings.TrimSpace(list[0]), pattern) {
+ return strings.TrimSpace(list[1]), nil
+ }
+ }
+
+ // Check whether the scanner encountered errors
+ err = scanner.Err()
+ if err != nil {
+ return "", err
+ }
+
+ return "", errors.Wrapf(errdefs.ErrNotFound, "getCPUInfo for pattern: %s", pattern)
+}
+
+func getCPUVariant() string {
+ if runtime.GOOS == "windows" {
+ // Windows only supports v7 for ARM32 and v8 for ARM64 and so we can use
+ // runtime.GOARCH to determine the variants
+ var variant string
+ switch runtime.GOARCH {
+ case "arm64":
+ variant = "v8"
+ case "arm":
+ variant = "v7"
+ default:
+ variant = "unknown"
+ }
+
+ return variant
+ }
+
+ variant, err := getCPUInfo("Cpu architecture")
+ if err != nil {
+ log.L.WithError(err).Error("failure getting variant")
+ return ""
+ }
+
+ switch variant {
+ case "8", "AArch64":
+ variant = "v8"
+ case "7", "7M", "?(12)", "?(13)", "?(14)", "?(15)", "?(16)", "?(17)":
+ variant = "v7"
+ case "6", "6TEJ":
+ variant = "v6"
+ case "5", "5T", "5TE", "5TEJ":
+ variant = "v5"
+ case "4", "4T":
+ variant = "v4"
+ case "3":
+ variant = "v3"
+ default:
+ variant = "unknown"
+ }
+
+ return variant
+}
diff --git a/vendor/github.com/containerd/containerd/platforms/database.go b/vendor/github.com/containerd/containerd/platforms/database.go
new file mode 100644
index 000000000..6ede94061
--- /dev/null
+++ b/vendor/github.com/containerd/containerd/platforms/database.go
@@ -0,0 +1,114 @@
+/*
+ Copyright The containerd Authors.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+package platforms
+
+import (
+ "runtime"
+ "strings"
+)
+
+// isLinuxOS returns true if the operating system is Linux.
+//
+// The OS value should be normalized before calling this function.
+func isLinuxOS(os string) bool {
+ return os == "linux"
+}
+
+// These function are generated from https://golang.org/src/go/build/syslist.go.
+//
+// We use switch statements because they are slightly faster than map lookups
+// and use a little less memory.
+
+// isKnownOS returns true if we know about the operating system.
+//
+// The OS value should be normalized before calling this function.
+func isKnownOS(os string) bool {
+ switch os {
+ case "aix", "android", "darwin", "dragonfly", "freebsd", "hurd", "illumos", "js", "linux", "nacl", "netbsd", "openbsd", "plan9", "solaris", "windows", "zos":
+ return true
+ }
+ return false
+}
+
+// isArmArch returns true if the architecture is ARM.
+//
+// The arch value should be normalized before being passed to this function.
+func isArmArch(arch string) bool {
+ switch arch {
+ case "arm", "arm64":
+ return true
+ }
+ return false
+}
+
+// isKnownArch returns true if we know about the architecture.
+//
+// The arch value should be normalized before being passed to this function.
+func isKnownArch(arch string) bool {
+ switch arch {
+ case "386", "amd64", "amd64p32", "arm", "armbe", "arm64", "arm64be", "ppc64", "ppc64le", "mips", "mipsle", "mips64", "mips64le", "mips64p32", "mips64p32le", "ppc", "riscv", "riscv64", "s390", "s390x", "sparc", "sparc64", "wasm":
+ return true
+ }
+ return false
+}
+
+func normalizeOS(os string) string {
+ if os == "" {
+ return runtime.GOOS
+ }
+ os = strings.ToLower(os)
+
+ switch os {
+ case "macos":
+ os = "darwin"
+ }
+ return os
+}
+
+// normalizeArch normalizes the architecture.
+func normalizeArch(arch, variant string) (string, string) {
+ arch, variant = strings.ToLower(arch), strings.ToLower(variant)
+ switch arch {
+ case "i386":
+ arch = "386"
+ variant = ""
+ case "x86_64", "x86-64":
+ arch = "amd64"
+ variant = ""
+ case "aarch64", "arm64":
+ arch = "arm64"
+ switch variant {
+ case "8", "v8":
+ variant = ""
+ }
+ case "armhf":
+ arch = "arm"
+ variant = "v7"
+ case "armel":
+ arch = "arm"
+ variant = "v6"
+ case "arm":
+ switch variant {
+ case "", "7":
+ variant = "v7"
+ case "5", "6", "8":
+ variant = "v" + variant
+ }
+ }
+
+ return arch, variant
+}
diff --git a/vendor/github.com/containerd/containerd/platforms/defaults.go b/vendor/github.com/containerd/containerd/platforms/defaults.go
new file mode 100644
index 000000000..a14d80e58
--- /dev/null
+++ b/vendor/github.com/containerd/containerd/platforms/defaults.go
@@ -0,0 +1,38 @@
+/*
+ Copyright The containerd Authors.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+package platforms
+
+import (
+ "runtime"
+
+ specs "github.com/opencontainers/image-spec/specs-go/v1"
+)
+
+// DefaultString returns the default string specifier for the platform.
+func DefaultString() string {
+ return Format(DefaultSpec())
+}
+
+// DefaultSpec returns the current platform's default platform specification.
+func DefaultSpec() specs.Platform {
+ return specs.Platform{
+ OS: runtime.GOOS,
+ Architecture: runtime.GOARCH,
+ // The Variant field will be empty if arch != ARM.
+ Variant: cpuVariant,
+ }
+}
diff --git a/vendor/github.com/containerd/containerd/platforms/defaults_unix.go b/vendor/github.com/containerd/containerd/platforms/defaults_unix.go
new file mode 100644
index 000000000..e8a7d5ffa
--- /dev/null
+++ b/vendor/github.com/containerd/containerd/platforms/defaults_unix.go
@@ -0,0 +1,24 @@
+// +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 platforms
+
+// Default returns the default matcher for the platform.
+func Default() MatchComparer {
+ return Only(DefaultSpec())
+}
diff --git a/vendor/github.com/containerd/containerd/platforms/defaults_windows.go b/vendor/github.com/containerd/containerd/platforms/defaults_windows.go
new file mode 100644
index 000000000..0defbd36c
--- /dev/null
+++ b/vendor/github.com/containerd/containerd/platforms/defaults_windows.go
@@ -0,0 +1,31 @@
+// +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 platforms
+
+import (
+ specs "github.com/opencontainers/image-spec/specs-go/v1"
+)
+
+// Default returns the default matcher for the platform.
+func Default() MatchComparer {
+ return Ordered(DefaultSpec(), specs.Platform{
+ OS: "linux",
+ Architecture: "amd64",
+ })
+}
diff --git a/vendor/github.com/containerd/containerd/platforms/platforms.go b/vendor/github.com/containerd/containerd/platforms/platforms.go
new file mode 100644
index 000000000..d2b73ac3d
--- /dev/null
+++ b/vendor/github.com/containerd/containerd/platforms/platforms.go
@@ -0,0 +1,279 @@
+/*
+ Copyright The containerd Authors.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+// Package platforms provides a toolkit for normalizing, matching and
+// specifying container platforms.
+//
+// Centered around OCI platform specifications, we define a string-based
+// specifier syntax that can be used for user input. With a specifier, users
+// only need to specify the parts of the platform that are relevant to their
+// context, providing an operating system or architecture or both.
+//
+// How do I use this package?
+//
+// The vast majority of use cases should simply use the match function with
+// user input. The first step is to parse a specifier into a matcher:
+//
+// m, err := Parse("linux")
+// if err != nil { ... }
+//
+// Once you have a matcher, use it to match against the platform declared by a
+// component, typically from an image or runtime. Since extracting an images
+// platform is a little more involved, we'll use an example against the
+// platform default:
+//
+// if ok := m.Match(Default()); !ok { /* doesn't match */ }
+//
+// This can be composed in loops for resolving runtimes or used as a filter for
+// fetch and select images.
+//
+// More details of the specifier syntax and platform spec follow.
+//
+// Declaring Platform Support
+//
+// Components that have strict platform requirements should use the OCI
+// platform specification to declare their support. Typically, this will be
+// images and runtimes that should make these declaring which platform they
+// support specifically. This looks roughly as follows:
+//
+// type Platform struct {
+// Architecture string
+// OS string
+// Variant string
+// }
+//
+// Most images and runtimes should at least set Architecture and OS, according
+// to their GOARCH and GOOS values, respectively (follow the OCI image
+// specification when in doubt). ARM should set variant under certain
+// discussions, which are outlined below.
+//
+// Platform Specifiers
+//
+// While the OCI platform specifications provide a tool for components to
+// specify structured information, user input typically doesn't need the full
+// context and much can be inferred. To solve this problem, we introduced
+// "specifiers". A specifier has the format
+// `<os>|<arch>|<os>/<arch>[/<variant>]`. The user can provide either the
+// operating system or the architecture or both.
+//
+// An example of a common specifier is `linux/amd64`. If the host has a default
+// of runtime that matches this, the user can simply provide the component that
+// matters. For example, if a image provides amd64 and arm64 support, the
+// operating system, `linux` can be inferred, so they only have to provide
+// `arm64` or `amd64`. Similar behavior is implemented for operating systems,
+// where the architecture may be known but a runtime may support images from
+// different operating systems.
+//
+// Normalization
+//
+// Because not all users are familiar with the way the Go runtime represents
+// platforms, several normalizations have been provided to make this package
+// easier to user.
+//
+// The following are performed for architectures:
+//
+// Value Normalized
+// aarch64 arm64
+// armhf arm
+// armel arm/v6
+// i386 386
+// x86_64 amd64
+// x86-64 amd64
+//
+// We also normalize the operating system `macos` to `darwin`.
+//
+// ARM Support
+//
+// To qualify ARM architecture, the Variant field is used to qualify the arm
+// version. The most common arm version, v7, is represented without the variant
+// unless it is explicitly provided. This is treated as equivalent to armhf. A
+// previous architecture, armel, will be normalized to arm/v6.
+//
+// While these normalizations are provided, their support on arm platforms has
+// not yet been fully implemented and tested.
+package platforms
+
+import (
+ "regexp"
+ "runtime"
+ "strconv"
+ "strings"
+
+ "github.com/containerd/containerd/errdefs"
+ specs "github.com/opencontainers/image-spec/specs-go/v1"
+ "github.com/pkg/errors"
+)
+
+var (
+ specifierRe = regexp.MustCompile(`^[A-Za-z0-9_-]+$`)
+)
+
+// Matcher matches platforms specifications, provided by an image or runtime.
+type Matcher interface {
+ Match(platform specs.Platform) bool
+}
+
+// NewMatcher returns a simple matcher based on the provided platform
+// specification. The returned matcher only looks for equality based on os,
+// architecture and variant.
+//
+// One may implement their own matcher if this doesn't provide the required
+// functionality.
+//
+// Applications should opt to use `Match` over directly parsing specifiers.
+func NewMatcher(platform specs.Platform) Matcher {
+ return &matcher{
+ Platform: Normalize(platform),
+ }
+}
+
+type matcher struct {
+ specs.Platform
+}
+
+func (m *matcher) Match(platform specs.Platform) bool {
+ normalized := Normalize(platform)
+ return m.OS == normalized.OS &&
+ m.Architecture == normalized.Architecture &&
+ m.Variant == normalized.Variant
+}
+
+func (m *matcher) String() string {
+ return Format(m.Platform)
+}
+
+// Parse parses the platform specifier syntax into a platform declaration.
+//
+// Platform specifiers are in the format `<os>|<arch>|<os>/<arch>[/<variant>]`.
+// The minimum required information for a platform specifier is the operating
+// system or architecture. If there is only a single string (no slashes), the
+// value will be matched against the known set of operating systems, then fall
+// back to the known set of architectures. The missing component will be
+// inferred based on the local environment.
+func Parse(specifier string) (specs.Platform, error) {
+ if strings.Contains(specifier, "*") {
+ // TODO(stevvooe): need to work out exact wildcard handling
+ return specs.Platform{}, errors.Wrapf(errdefs.ErrInvalidArgument, "%q: wildcards not yet supported", specifier)
+ }
+
+ parts := strings.Split(specifier, "/")
+
+ for _, part := range parts {
+ if !specifierRe.MatchString(part) {
+ return specs.Platform{}, errors.Wrapf(errdefs.ErrInvalidArgument, "%q is an invalid component of %q: platform specifier component must match %q", part, specifier, specifierRe.String())
+ }
+ }
+
+ var p specs.Platform
+ switch len(parts) {
+ case 1:
+ // in this case, we will test that the value might be an OS, then look
+ // it up. If it is not known, we'll treat it as an architecture. Since
+ // we have very little information about the platform here, we are
+ // going to be a little more strict if we don't know about the argument
+ // value.
+ p.OS = normalizeOS(parts[0])
+ if isKnownOS(p.OS) {
+ // picks a default architecture
+ p.Architecture = runtime.GOARCH
+ if p.Architecture == "arm" {
+ // TODO(stevvooe): Resolve arm variant, if not v6 (default)
+ return specs.Platform{}, errors.Wrapf(errdefs.ErrNotImplemented, "arm support not fully implemented")
+ }
+
+ return p, nil
+ }
+
+ p.Architecture, p.Variant = normalizeArch(parts[0], "")
+ if p.Architecture == "arm" && p.Variant == "v7" {
+ p.Variant = ""
+ }
+ if isKnownArch(p.Architecture) {
+ p.OS = runtime.GOOS
+ return p, nil
+ }
+
+ return specs.Platform{}, errors.Wrapf(errdefs.ErrInvalidArgument, "%q: unknown operating system or architecture", specifier)
+ case 2:
+ // In this case, we treat as a regular os/arch pair. We don't care
+ // about whether or not we know of the platform.
+ p.OS = normalizeOS(parts[0])
+ p.Architecture, p.Variant = normalizeArch(parts[1], "")
+ if p.Architecture == "arm" && p.Variant == "v7" {
+ p.Variant = ""
+ }
+
+ return p, nil
+ case 3:
+ // we have a fully specified variant, this is rare
+ p.OS = normalizeOS(parts[0])
+ p.Architecture, p.Variant = normalizeArch(parts[1], parts[2])
+ if p.Architecture == "arm64" && p.Variant == "" {
+ p.Variant = "v8"
+ }
+
+ return p, nil
+ }
+
+ return specs.Platform{}, errors.Wrapf(errdefs.ErrInvalidArgument, "%q: cannot parse platform specifier", specifier)
+}
+
+// MustParse is like Parses but panics if the specifier cannot be parsed.
+// Simplifies initialization of global variables.
+func MustParse(specifier string) specs.Platform {
+ p, err := Parse(specifier)
+ if err != nil {
+ panic("platform: Parse(" + strconv.Quote(specifier) + "): " + err.Error())
+ }
+ return p
+}
+
+// Format returns a string specifier from the provided platform specification.
+func Format(platform specs.Platform) string {
+ if platform.OS == "" {
+ return "unknown"
+ }
+
+ return joinNotEmpty(platform.OS, platform.Architecture, platform.Variant)
+}
+
+func joinNotEmpty(s ...string) string {
+ var ss []string
+ for _, s := range s {
+ if s == "" {
+ continue
+ }
+
+ ss = append(ss, s)
+ }
+
+ return strings.Join(ss, "/")
+}
+
+// Normalize validates and translate the platform to the canonical value.
+//
+// For example, if "Aarch64" is encountered, we change it to "arm64" or if
+// "x86_64" is encountered, it becomes "amd64".
+func Normalize(platform specs.Platform) specs.Platform {
+ platform.OS = normalizeOS(platform.OS)
+ platform.Architecture, platform.Variant = normalizeArch(platform.Architecture, platform.Variant)
+
+ // these fields are deprecated, remove them
+ platform.OSFeatures = nil
+ platform.OSVersion = ""
+
+ return platform
+}
diff --git a/vendor/github.com/containernetworking/cni/libcni/api.go b/vendor/github.com/containernetworking/cni/libcni/api.go
index 22b111742..7e52bd838 100644
--- a/vendor/github.com/containernetworking/cni/libcni/api.go
+++ b/vendor/github.com/containernetworking/cni/libcni/api.go
@@ -409,6 +409,9 @@ func (c *CNIConfig) addNetwork(ctx context.Context, name, cniVersion string, net
if err := utils.ValidateNetworkName(name); err != nil {
return nil, err
}
+ if err := utils.ValidateInterfaceName(rt.IfName); err != nil {
+ return nil, err
+ }
newConf, err := buildOneConfig(name, cniVersion, net, prevResult, rt)
if err != nil {
@@ -629,6 +632,9 @@ func (c *CNIConfig) validatePlugin(ctx context.Context, pluginName, expectedVers
if err != nil {
return err
}
+ if expectedVersion == "" {
+ expectedVersion = "0.1.0"
+ }
vi, err := invoke.GetVersionInfo(ctx, pluginPath, c.exec)
if err != nil {
diff --git a/vendor/github.com/containernetworking/cni/pkg/invoke/args.go b/vendor/github.com/containernetworking/cni/pkg/invoke/args.go
index d31a44e87..3cdb4bc8d 100644
--- a/vendor/github.com/containernetworking/cni/pkg/invoke/args.go
+++ b/vendor/github.com/containernetworking/cni/pkg/invoke/args.go
@@ -60,8 +60,8 @@ func (args *Args) AsEnv() []string {
pluginArgsStr = stringify(args.PluginArgs)
}
- // Duplicated values which come first will be overrided, so we must put the
- // custom values in the end to avoid being overrided by the process environments.
+ // Duplicated values which come first will be overridden, so we must put the
+ // custom values in the end to avoid being overridden by the process environments.
env = append(env,
"CNI_COMMAND="+args.Command,
"CNI_CONTAINERID="+args.ContainerID,
diff --git a/vendor/github.com/containernetworking/cni/pkg/invoke/raw_exec.go b/vendor/github.com/containernetworking/cni/pkg/invoke/raw_exec.go
index ad8498ba2..4f89a5dda 100644
--- a/vendor/github.com/containernetworking/cni/pkg/invoke/raw_exec.go
+++ b/vendor/github.com/containernetworking/cni/pkg/invoke/raw_exec.go
@@ -44,10 +44,14 @@ func (e *RawExec) ExecPlugin(ctx context.Context, pluginPath string, stdinData [
}
func pluginErr(err error, output []byte) error {
- if _, ok := err.(*exec.ExitError); ok {
+ if exitError, ok := err.(*exec.ExitError); ok {
emsg := types.Error{}
if len(output) == 0 {
- emsg.Msg = "netplugin failed with no error message"
+ if len(exitError.Stderr) == 0 {
+ emsg.Msg = "netplugin failed with no error message"
+ } else {
+ emsg.Msg = fmt.Sprintf("netplugin failed: %q", string(exitError.Stderr))
+ }
} else if perr := json.Unmarshal(output, &emsg); perr != nil {
emsg.Msg = fmt.Sprintf("netplugin failed but error parsing its diagnostic message %q: %v", string(output), perr)
}
diff --git a/vendor/github.com/containernetworking/cni/pkg/types/020/types.go b/vendor/github.com/containernetworking/cni/pkg/types/020/types.go
index 53256167f..36f31678a 100644
--- a/vendor/github.com/containernetworking/cni/pkg/types/020/types.go
+++ b/vendor/github.com/containernetworking/cni/pkg/types/020/types.go
@@ -86,20 +86,6 @@ func (r *Result) PrintTo(writer io.Writer) error {
return err
}
-// String returns a formatted string in the form of "[IP4: $1,][ IP6: $2,] DNS: $3" where
-// $1 represents the receiver's IPv4, $2 represents the receiver's IPv6 and $3 the
-// receiver's DNS. If $1 or $2 are nil, they won't be present in the returned string.
-func (r *Result) String() string {
- var str string
- if r.IP4 != nil {
- str = fmt.Sprintf("IP4:%+v, ", *r.IP4)
- }
- if r.IP6 != nil {
- str += fmt.Sprintf("IP6:%+v, ", *r.IP6)
- }
- return fmt.Sprintf("%sDNS:%+v", str, r.DNS)
-}
-
// IPConfig contains values necessary to configure an interface
type IPConfig struct {
IP net.IPNet
diff --git a/vendor/github.com/containernetworking/cni/pkg/types/current/types.go b/vendor/github.com/containernetworking/cni/pkg/types/current/types.go
index 7267a2e6d..754cc6e72 100644
--- a/vendor/github.com/containernetworking/cni/pkg/types/current/types.go
+++ b/vendor/github.com/containernetworking/cni/pkg/types/current/types.go
@@ -207,23 +207,6 @@ func (r *Result) PrintTo(writer io.Writer) error {
return err
}
-// String returns a formatted string in the form of "[Interfaces: $1,][ IP: $2,] DNS: $3" where
-// $1 represents the receiver's Interfaces, $2 represents the receiver's IP addresses and $3 the
-// receiver's DNS. If $1 or $2 are nil, they won't be present in the returned string.
-func (r *Result) String() string {
- var str string
- if len(r.Interfaces) > 0 {
- str += fmt.Sprintf("Interfaces:%+v, ", r.Interfaces)
- }
- if len(r.IPs) > 0 {
- str += fmt.Sprintf("IP:%+v, ", r.IPs)
- }
- if len(r.Routes) > 0 {
- str += fmt.Sprintf("Routes:%+v, ", r.Routes)
- }
- return fmt.Sprintf("%sDNS:%+v", str, r.DNS)
-}
-
// Convert this old version result to the current CNI version result
func (r *Result) Convert() (*Result, error) {
return r, nil
diff --git a/vendor/github.com/containernetworking/cni/pkg/types/types.go b/vendor/github.com/containernetworking/cni/pkg/types/types.go
index 3e185c1ce..3fa757a5d 100644
--- a/vendor/github.com/containernetworking/cni/pkg/types/types.go
+++ b/vendor/github.com/containernetworking/cni/pkg/types/types.go
@@ -100,9 +100,6 @@ type Result interface {
// Prints the result in JSON format to provided writer
PrintTo(writer io.Writer) error
-
- // Returns a JSON string representation of the result
- String() string
}
func PrintResult(result Result, version string) error {
diff --git a/vendor/github.com/containernetworking/cni/pkg/utils/utils.go b/vendor/github.com/containernetworking/cni/pkg/utils/utils.go
index 324c40dea..b8ec38874 100644
--- a/vendor/github.com/containernetworking/cni/pkg/utils/utils.go
+++ b/vendor/github.com/containernetworking/cni/pkg/utils/utils.go
@@ -15,14 +15,22 @@
package utils
import (
+ "bytes"
+ "fmt"
"regexp"
+ "unicode"
"github.com/containernetworking/cni/pkg/types"
)
-// cniValidNameChars is the regexp used to validate valid characters in
-// containerID and networkName
-const cniValidNameChars = `[a-zA-Z0-9][a-zA-Z0-9_.\-]`
+const (
+ // cniValidNameChars is the regexp used to validate valid characters in
+ // containerID and networkName
+ cniValidNameChars = `[a-zA-Z0-9][a-zA-Z0-9_.\-]`
+
+ // maxInterfaceNameLength is the length max of a valid interface name
+ maxInterfaceNameLength = 15
+)
var cniReg = regexp.MustCompile(`^` + cniValidNameChars + `*$`)
@@ -49,3 +57,28 @@ func ValidateNetworkName(networkName string) *types.Error {
}
return nil
}
+
+// ValidateInterfaceName will validate the interface name based on the three rules below
+// 1. The name must not be empty
+// 2. The name must be less than 16 characters
+// 3. The name must not be "." or ".."
+// 3. The name must not contain / or : or any whitespace characters
+// ref to https://github.com/torvalds/linux/blob/master/net/core/dev.c#L1024
+func ValidateInterfaceName(ifName string) *types.Error {
+ if len(ifName) == 0 {
+ return types.NewError(types.ErrInvalidEnvironmentVariables, "interface name is empty", "")
+ }
+ if len(ifName) > maxInterfaceNameLength {
+ return types.NewError(types.ErrInvalidEnvironmentVariables, "interface name is too long", fmt.Sprintf("interface name should be less than %d characters", maxInterfaceNameLength+1))
+ }
+ if ifName == "." || ifName == ".." {
+ return types.NewError(types.ErrInvalidEnvironmentVariables, "interface name is . or ..", "")
+ }
+ for _, r := range bytes.Runes([]byte(ifName)) {
+ if r == '/' || r == ':' || unicode.IsSpace(r) {
+ return types.NewError(types.ErrInvalidEnvironmentVariables, "interface name contains / or : or whitespace characters", "")
+ }
+ }
+
+ return nil
+}
diff --git a/vendor/github.com/containers/buildah/.cirrus.yml b/vendor/github.com/containers/buildah/.cirrus.yml
index 66774c226..65bbd31ff 100644
--- a/vendor/github.com/containers/buildah/.cirrus.yml
+++ b/vendor/github.com/containers/buildah/.cirrus.yml
@@ -5,24 +5,33 @@ env:
####
#### Global variables used for all tasks
####
+ # Name of the ultimate destination branch for this CI run, PR or post-merge.
+ DEST_BRANCH: "master"
+ GOPATH: "/var/tmp/go"
+ GOSRC: "${GOPATH}/src/github.com/containers/buildah"
# Overrides default location (/tmp/cirrus) for repo clone
- CIRRUS_WORKING_DIR: "/var/tmp/go/src/github.com/containers/buildah"
+ CIRRUS_WORKING_DIR: "${GOSRC}"
# Shell used to execute all script commands
CIRRUS_SHELL: "/bin/bash"
# Automation script path relative to $CIRRUS_WORKING_DIR)
SCRIPT_BASE: "./contrib/cirrus"
# No need to go crazy, but grab enough to cover most PRs
CIRRUS_CLONE_DEPTH: 50
+ # Unless set by in_podman.sh, default to operating outside of a podman container
+ IN_PODMAN: 'false'
+ # Not cross-compiling by default
+ CROSS_TARGET: ""
####
#### Cache-image names to test with
####
# GCE project where images live
IMAGE_PROJECT: "libpod-218412"
+ # TODO: Setting up from base-images is very inefficient, use libpod's cache-images instead?
FEDORA_CACHE_IMAGE_NAME: "fedora-cloud-base-30-1-2-1565360543"
PRIOR_FEDORA_CACHE_IMAGE_NAME: "fedora-cloud-base-29-1-2-1565360543"
- UBUNTU_CACHE_IMAGE_NAME: "ubuntu-1904-disco-v20190724" # Latest
- PRIOR_UBUNTU_CACHE_IMAGE_NAME: "ubuntu-1804-bionic-v20190722a" # LTS
+ UBUNTU_CACHE_IMAGE_NAME: "ubuntu-1904-disco-v20190724"
+ PRIOR_UBUNTU_CACHE_IMAGE_NAME: "ubuntu-1804-bionic-v20190722a"
####
#### Command variables to help avoid duplication
@@ -30,10 +39,6 @@ env:
# Command to prefix every output line with a timestamp
# (can't do inline awk script, Cirrus-CI or YAML mangles quoting)
_TIMESTAMP: 'awk -f ${CIRRUS_WORKING_DIR}/${SCRIPT_BASE}/timestamp.awk'
- _DFCMD: 'df -lhTx tmpfs'
- _RAUDITCMD: 'cat /var/log/audit/audit.log'
- _UAUDITCMD: 'cat /var/log/kern.log'
- _JOURNALCMD: 'journalctl -b'
gcp_credentials: ENCRYPTED[ae0bf7370f0b6e446bc61d0865a2c55d3e166b3fab9466eb0393e38e1c66a31ca4c71ddc7e0139d47d075c36dd6d3fd7]
@@ -50,43 +55,81 @@ gce_instance:
image_name: "${FEDORA_CACHE_IMAGE_NAME}"
-testing_task:
- gce_instance: # Only need to specify differences from defaults (above)
- matrix: # Duplicate this task for each matrix product.
- image_name: "${FEDORA_CACHE_IMAGE_NAME}"
- image_name: "${PRIOR_FEDORA_CACHE_IMAGE_NAME}"
- image_name: "${UBUNTU_CACHE_IMAGE_NAME}"
- image_name: "${PRIOR_UBUNTU_CACHE_IMAGE_NAME}"
+# Update metadata on VM images referenced by this repository state
+'cirrus-ci/only_prs/meta_task':
+
+ # see bors.toml
+ skip: $CIRRUS_BRANCH =~ ".*\.tmp"
+
+ container:
+ image: "quay.io/libpod/imgts:latest" # see contrib/imgts
+ cpu: 1
+ memory: 1
+
+ env:
+ # Space-separated list of images used by this repository state
+ IMGNAMES: |-
+ ${FEDORA_CACHE_IMAGE_NAME}
+ ${PRIOR_FEDORA_CACHE_IMAGE_NAME}
+ ${UBUNTU_CACHE_IMAGE_NAME}
+ ${PRIOR_UBUNTU_CACHE_IMAGE_NAME}
+ BUILDID: "${CIRRUS_BUILD_ID}"
+ REPOREF: "${CIRRUS_CHANGE_IN_REPO}"
+ GCPJSON: ENCRYPTED[d3614d6f5cc0e66be89d4252b3365fd84f14eee0259d4eb47e25fc0bc2842c7937f5ee8c882b7e547b4c5ec4b6733b14]
+ GCPNAME: ENCRYPTED[8509e6a681b859479ce6aa275bd3c4ac82de5beec6df6057925afc4cd85b7ef2e879066ae8baaa2d453b82958e434578]
+ GCPPROJECT: ENCRYPTED[cc09b62d0ec6746a3df685e663ad25d9d5af95ef5fd843c96f3d0ec9d7f065dc63216b9c685c9f43a776a1d403991494]
+ CIRRUS_CLONE_DEPTH: 1 # source not used
+
+ script: '/usr/local/bin/entrypoint.sh |& ${_TIMESTAMP}'
- # Separate scripts for separate outputs, makes debugging easier.
- setup_script: '${CIRRUS_WORKING_DIR}/${SCRIPT_BASE}/setup.sh |& ${_TIMESTAMP}'
- build_and_test_script: '${CIRRUS_WORKING_DIR}/${SCRIPT_BASE}/build_and_test.sh |& ${_TIMESTAMP}'
- # Log collection when job was successful
- df_script: '${_DFCMD} || true'
- rh_audit_log_script: '${_RAUDITCMD} || true'
- ubuntu_audit_log_script: '${_UAUDITCMD} || true'
- journal_log_script: '${_JOURNALCMD} || true'
+'cirrus-ci/only_prs/gate_task':
+
+ # see bors.toml
+ skip: $CIRRUS_BRANCH =~ ".*\.tmp"
+
+ timeout_in: 30m
- on_failure: # Script names must be different from above
- failure_df_script: '${_DFCMD} || true'
- failure_rh_audit_log_script: '${_RAUDITCMD} || true'
- failure_ubuntu_audit_log_script: '${_UAUDITCMD} || true'
- failure_journal_log_script: '${_JOURNALCMD} || true'
+ setup_script: '${SCRIPT_BASE}/setup.sh |& ${_TIMESTAMP}'
+ build_script: '${SCRIPT_BASE}/build.sh |& ${_TIMESTAMP}'
+ validate_test_script: '${SCRIPT_BASE}/test.sh validate |& ${_TIMESTAMP}'
+
+ binary_artifacts:
+ path: ./bin/*
+
+
+'cirrus-ci/only_prs/unit_task':
+
+ # see bors.toml
+ skip: $CIRRUS_BRANCH =~ ".*\.tmp"
+
+ # not supported by bors-ng
+ # allow_failures: $CI == $CI
+
+ timeout_in: 30m
+
+ setup_script: '${SCRIPT_BASE}/setup.sh |& ${_TIMESTAMP}'
+ build_script: '${SCRIPT_BASE}/build.sh |& ${_TIMESTAMP}'
+ # FIXME: These tests mostly/always fail
+ unit_test_script: '${SCRIPT_BASE}/test.sh unit |& ${_TIMESTAMP} || true'
+
+ binary_artifacts:
+ path: ./bin/*
# This task runs `make vendor` followed by ./hack/tree_status.sh to check
# whether the git tree is clean. The reasoning for that is to make sure
# that the vendor.conf, the code and the vendored packages in ./vendor are
# in sync at all times.
-vendor_task:
+'cirrus-ci/only_prs/vendor_task':
- only_if: $CIRRUS_CHANGE_MESSAGE !=~ '.*\*\*\*\s*CIRRUS:\s*TEST\s*IMAGES\s*\*\*\*.*'
+ # see bors.toml
+ skip: $CIRRUS_BRANCH =~ ".*\.tmp"
env:
CIRRUS_WORKING_DIR: "/var/tmp/go/src/github.com/containers/buildah"
- GOPATH: "/go"
- GOSRC: "/go/src/github.com/containers/buildah"
+ GOPATH: "/var/tmp/go"
+ GOSRC: "/var/tmp/go/src/github.com/containers/buildah"
# Runs within Cirrus's "community cluster"
container:
@@ -94,35 +137,118 @@ vendor_task:
cpu: 1
memory: 1
- timeout_in: 30m
+ timeout_in: 5m
vendor_script:
- - 'cd ${CIRRUS_WORKING_DIR} && make vendor'
- - 'cd ${CIRRUS_WORKING_DIR} && ./hack/tree_status.sh'
+ - 'make vendor'
+ - './hack/tree_status.sh'
-# Update metadata on VM images referenced by this repository state
-meta_task:
+
+'cirrus-ci/only_prs/cross_task':
+
+ # see bors.toml
+ skip: $CIRRUS_BRANCH =~ ".*\.tmp"
depends_on:
- - "vendor"
+ - 'cirrus-ci/only_prs/gate'
+ - 'cirrus-ci/only_prs/vendor'
container:
- image: "quay.io/libpod/imgts:latest" # see contrib/imgts
- cpu: 1
- memory: 1
+ image: registry.fedoraproject.org/fedora:30
env:
- # Space-separated list of images used by this repository state
- IMGNAMES: |-
- ${FEDORA_CACHE_IMAGE_NAME}
- ${PRIOR_FEDORA_CACHE_IMAGE_NAME}
- ${UBUNTU_CACHE_IMAGE_NAME}
- ${PRIOR_UBUNTU_CACHE_IMAGE_NAME}
- BUILDID: "${CIRRUS_BUILD_ID}"
- REPOREF: "${CIRRUS_CHANGE_IN_REPO}"
- GCPJSON: ENCRYPTED[d3614d6f5cc0e66be89d4252b3365fd84f14eee0259d4eb47e25fc0bc2842c7937f5ee8c882b7e547b4c5ec4b6733b14]
- GCPNAME: ENCRYPTED[8509e6a681b859479ce6aa275bd3c4ac82de5beec6df6057925afc4cd85b7ef2e879066ae8baaa2d453b82958e434578]
- GCPPROJECT: ENCRYPTED[cc09b62d0ec6746a3df685e663ad25d9d5af95ef5fd843c96f3d0ec9d7f065dc63216b9c685c9f43a776a1d403991494]
- CIRRUS_CLONE_DEPTH: 1 # source not used
+ matrix:
+ CROSS_TARGET: darwin
- script: '/usr/local/bin/entrypoint.sh |& ${_TIMESTAMP}'
+ setup_script: '${SCRIPT_BASE}/setup.sh |& ${_TIMESTAMP}'
+ build_script: '${SCRIPT_BASE}/build.sh |& ${_TIMESTAMP}'
+
+ binary_artifacts:
+ path: ./bin/*
+
+
+'cirrus-ci/required/testing_task':
+
+ # see bors.toml
+ skip: $CIRRUS_BRANCH =~ ".*\.tmp"
+
+ depends_on:
+ - 'cirrus-ci/only_prs/gate'
+ - 'cirrus-ci/only_prs/vendor'
+
+ gce_instance: # Only need to specify differences from defaults (above)
+ matrix: # Duplicate this task for each matrix product.
+ image_name: "${FEDORA_CACHE_IMAGE_NAME}"
+ # TODO: Re-enable once prior image is F30 and above is F31
+ # image_name: "${PRIOR_FEDORA_CACHE_IMAGE_NAME}"
+ image_name: "${UBUNTU_CACHE_IMAGE_NAME}"
+ image_name: "${PRIOR_UBUNTU_CACHE_IMAGE_NAME}"
+
+ # Separate scripts for separate outputs, makes debugging easier.
+ setup_script: '${SCRIPT_BASE}/setup.sh |& ${_TIMESTAMP}'
+ build_script: '${SCRIPT_BASE}/build.sh |& ${_TIMESTAMP}'
+ integration_test_script: '${SCRIPT_BASE}/test.sh integration |& ${_TIMESTAMP}'
+
+ binary_artifacts:
+ path: ./bin/*
+
+ always: &standardlogs
+ audit_log_script: '$GOSRC/$SCRIPT_BASE/logcollector.sh audit'
+ df_script: '$GOSRC/$SCRIPT_BASE/logcollector.sh df'
+ journal_script: '$GOSRC/$SCRIPT_BASE/logcollector.sh journal'
+ podman_system_info_script: '$GOSRC/$SCRIPT_BASE/logcollector.sh podman'
+ buildah_version_script: '$GOSRC/$SCRIPT_BASE/logcollector.sh buildah_version'
+ buildah_info_script: '$GOSRC/$SCRIPT_BASE/logcollector.sh buildah_info'
+ package_versions_script: '$GOSRC/$SCRIPT_BASE/logcollector.sh packages'
+
+
+'cirrus-ci/required/in_podman_task':
+
+ # see bors.toml
+ skip: $CIRRUS_BRANCH =~ ".*\.tmp"
+
+ depends_on:
+ - 'cirrus-ci/only_prs/gate'
+ - 'cirrus-ci/only_prs/vendor'
+
+ env:
+ # This is key, it causes the scripts to re-execute themselves inside a container.
+ IN_PODMAN: 'true'
+ BUILDAH_ISOLATION: 'chroot'
+ STORAGE_DRIVER: 'vfs'
+ STORAGE_OPTIONS: ''
+
+ # Separate scripts for separate outputs, makes debugging easier.
+ setup_script: '${SCRIPT_BASE}/setup.sh |& ${_TIMESTAMP}'
+ build_script: '${SCRIPT_BASE}/build.sh |& ${_TIMESTAMP}'
+ integration_test_script: '${SCRIPT_BASE}/test.sh integration |& ${_TIMESTAMP}'
+
+ binary_artifacts:
+ path: ./bin/*
+
+ always:
+ <<: *standardlogs
+
+# TODO: Bors-ng has trouble interpreting multiple status-checks as being required
+# when their names contain wild-cards (like `testing%`). Until that issue
+# can be fixed, use a single "test" to represent pass/fail status of all
+# required checks.
+'cirrus-ci/success_task':
+
+ # see bors.toml
+ skip: $CIRRUS_BRANCH =~ ".*\.tmp"
+
+ depends_on:
+ - "cirrus-ci/required/testing"
+ - "cirrus-ci/required/in_podman"
+
+ env:
+ CIRRUS_WORKING_DIR: /tmp
+ CIRRUS_CLONE_DEPTH: 1 # no code is being used by this task
+
+ container:
+ image: "registry.fedoraproject.org/fedora-minimal:latest"
+ cpu: 1
+ memory: 1
+
+ script: /bin/true
diff --git a/vendor/github.com/containers/buildah/.papr.sh b/vendor/github.com/containers/buildah/.papr.sh
deleted file mode 100644
index 2795e9ec0..000000000
--- a/vendor/github.com/containers/buildah/.papr.sh
+++ /dev/null
@@ -1,42 +0,0 @@
-#!/bin/bash
-set -xeuo pipefail
-export GOPATH=/go
-export PATH=$HOME/gopath/bin:$PATH:$GOPATH/bin
-export GOSRC=$GOPATH/src/github.com/containers/buildah
-
-cp -fv /etc/yum.repos.d{.host/*.repo,}
-
-dnf install -y \
- bats \
- btrfs-progs-devel \
- bzip2 \
- device-mapper-devel \
- findutils \
- git \
- glib2-devel \
- glibc-static \
- gnupg \
- golang \
- gpgme-devel \
- libassuan-devel \
- libseccomp-devel \
- libselinux-devel \
- libselinux-static \
- libseccomp-static \
- libselinux-utils \
- make \
- openssl \
- skopeo-containers \
- which
-
-
-# Install gomega
-go get github.com/onsi/gomega/...
-
-# PAPR adds a merge commit, for testing, which fails the
-# short-commit-subject validation test, so tell git-validate.sh to only check
-# up to, but not including, the merge commit.
-export GITVALIDATE_TIP=$(cd $GOSRC; git log -2 --pretty='%H' | tail -n 1)
-make -C $GOSRC install.tools runc all validate test-unit test-integration static
-env BUILDAH_ISOLATION=chroot make -C $GOSRC test-integration
-env BUILDAH_ISOLATION=rootless make -C $GOSRC test-integration
diff --git a/vendor/github.com/containers/buildah/.papr.yml b/vendor/github.com/containers/buildah/.papr.yml
deleted file mode 100644
index 4be12a18e..000000000
--- a/vendor/github.com/containers/buildah/.papr.yml
+++ /dev/null
@@ -1,87 +0,0 @@
-branches:
- - master
- - auto
- - try
-
-host:
- # 29 is the highest level of atomic
- distro: fedora/29/atomic
-
-required: true
-
-tests:
- # Let's create a self signed certificate and get it in the right places
- - hostname
- - ip a
- - ping -c 3 localhost
- - cat /etc/hostname
- - mkdir -p /home/travis/auth
- - openssl req -newkey rsa:4096 -nodes -sha256 -keyout /home/travis/auth/domain.key -x509 -days 2 -out /home/travis/auth/domain.crt -subj "/C=US/ST=Foo/L=Bar/O=Red Hat, Inc./CN=localhost"
- - cp /home/travis/auth/domain.crt /home/travis/auth/domain.cert
- - sudo mkdir -p /etc/docker/certs.d/docker.io/
- - sudo cp /home/travis/auth/domain.crt /etc/docker/certs.d/docker.io/ca.crt
- - sudo mkdir -p /etc/docker/certs.d/localhost:5000/
- - sudo cp /home/travis/auth/domain.crt /etc/docker/certs.d/localhost:5000/ca.crt
- - sudo cp /home/travis/auth/domain.crt /etc/docker/certs.d/localhost:5000/domain.crt
- # Create the credentials file, then start up the Docker registry
- - podman run --entrypoint htpasswd registry:2 -Bbn testuser testpassword > /home/travis/auth/htpasswd
- - podman run -d -p 5000:5000 --name registry -v /home/travis/auth:/home/travis/auth:Z -e "REGISTRY_AUTH=htpasswd" -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" -e REGISTRY_AUTH_HTPASSWD_PATH=/home/travis/auth/htpasswd -e REGISTRY_HTTP_TLS_CERTIFICATE=/home/travis/auth/domain.crt -e REGISTRY_HTTP_TLS_KEY=/home/travis/auth/domain.key registry:2
-
-# Test Podman setup
- - podman version
- - podman info
- - podman ps --all
- - podman images
- - ls -alF /home/travis/auth
- - podman pull alpine
- - podman login localhost:5000 --username testuser --password testpassword
- - podman tag alpine localhost:5000/my-alpine
- - podman push --creds=testuser:testpassword localhost:5000/my-alpine
- - podman ps --all
- - podman images
- - podman rmi docker.io/alpine
- - podman rmi localhost:5000/my-alpine
- - podman pull --creds=testuser:testpassword localhost:5000/my-alpine
- - podman ps --all
- - podman images
- - podman rmi localhost:5000/my-alpine
-
- # mount yum repos to inherit injected mirrors from PAPR
- - podman run --net=host --security-opt label=disable --cap-add all --security-opt seccomp=unconfined -v /etc/yum.repos.d:/etc/yum.repos.d.host:ro
- -v $PWD:/go/src/github.com/containers/buildah
- --workdir /go/src/github.com/containers/buildah
- registry.fedoraproject.org/fedora:30 bash -c sh ./.papr.sh
-
----
-
-container:
- image: registry.fedoraproject.org/fedora:30
-
-packages:
- - btrfs-progs-devel
- - bzip2
- - device-mapper-devel
- - findutils
- - git
- - glib2-devel
- - gnupg
- - golang
- - libassuan-devel
- - make
- - skopeo-containers
-
-required: false
-pulls: true
-
-env:
- GOPATH: /go
- GOSRC: /go/src/github.com/containers
-
-tests:
- - mkdir -p $GOSRC && ln -s /var/tmp/checkout $GOSRC/buildah
- - cd $GOSRC/buildah && make darwin
-
-artifacts:
- - test-suite.log
-
-context: "darwin CI"
diff --git a/vendor/github.com/containers/buildah/.travis.yml b/vendor/github.com/containers/buildah/.travis.yml
deleted file mode 100644
index 04b665611..000000000
--- a/vendor/github.com/containers/buildah/.travis.yml
+++ /dev/null
@@ -1,95 +0,0 @@
-language: go
-dist: xenial
-sudo: required
-go:
- - 1.13.x
- - tip
-go_import_path: github.com/containers/buildah
-
-env:
- global:
- - TRAVIS_ENV="-e TRAVIS=$TRAVIS
- -e CI=$CI
- -e TRAVIS_COMMIT=$TRAVIS_COMMIT
- -e TRAVIS_COMMIT_RANGE=$TRAVIS_COMMIT_RANGE
- -e TRAVIS_REPO_SLUG=$TRAVIS_REPO_SLUG
- -e TRAVIS_PULL_REQUEST=$TRAVIS_PULL_REQUEST
- -e TRAVIS_PULL_REQUEST_SHA=$TRAVIS_PULL_REQUEST_SHA
- -e TRAVIS_PULL_REQUEST_SLUG=$TRAVIS_PULL_REQUEST_SLUG
- -e TRAVIS_BRANCH=$TRAVIS_BRANCH
- -e TRAVIS_JOB_ID=$TRAVIS_JOB_ID
- -e TRAVIS_BUILD_DIR=$TRAVIS_BUILD_DIR"
- matrix:
- - BUILDAH_ISOLATION=oci
- DISTRO="ubuntu"
- - BUILDAH_ISOLATION=chroot
- DISTRO="ubuntu"
- - BUILDAH_ISOLATION=rootless
- DISTRO="ubuntu"
-matrix:
- # If the latest unstable development version of go fails, that's OK.
- allow_failures:
- - go: tip
- - env: TEST_GROUP=conformance
-
- # Don't hold on the tip tests to finish. Mark tests green if the
- # stable versions pass.
- fast_finish: true
-
-services:
- - docker
-before_install:
- - sudo apt-get -qq install software-properties-common
- - sudo add-apt-repository -y ppa:duggan/bats
- - sudo apt-get update
- - sudo apt-get -qq install bats btrfs-tools git libapparmor-dev libc-dev libdevmapper-dev libglib2.0-dev libgpgme11-dev libselinux1-dev linux-libc-dev realpath e2fslibs-dev libfuse-dev codespell
- - sudo apt-get -qq update
- - sudo apt-get -y -o Dpkg::Options::="--force-confnew" install docker-ce
- - mkdir /home/travis/auth
- - sudo mkdir -p /var/lib/containers/storage/overlay
-install:
- # Let's create a self signed certificate and get it in the right places
- - hostname
- - ip a
- - ping -c 3 localhost
- - cat /etc/hostname
- - openssl req -newkey rsa:4096 -nodes -sha256 -keyout /home/travis/auth/domain.key -x509 -days 2 -out /home/travis/auth/domain.crt -subj "/C=US/ST=Foo/L=Bar/O=Red Hat, Inc./CN=localhost"
- - cp /home/travis/auth/domain.crt /home/travis/auth/domain.cert
- - sudo mkdir -p /etc/docker/certs.d/docker.io/
- - sudo cp /home/travis/auth/domain.crt /etc/docker/certs.d/docker.io/ca.crt
- - sudo mkdir -p /etc/docker/certs.d/localhost:5000/
- - sudo cp /home/travis/auth/domain.crt /etc/docker/certs.d/localhost:5000/ca.crt
- - sudo cp /home/travis/auth/domain.crt /etc/docker/certs.d/localhost:5000/domain.crt
- # Create the credentials file, then start up the Docker registry
- - docker run --entrypoint htpasswd registry:2 -Bbn testuser testpassword > /home/travis/auth/htpasswd
- - docker run -d -p 5000:5000 --name registry -v /home/travis/auth:/home/travis/auth:Z -e "REGISTRY_AUTH=htpasswd" -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" -e REGISTRY_AUTH_HTPASSWD_PATH=/home/travis/auth/htpasswd -e REGISTRY_HTTP_TLS_CERTIFICATE=/home/travis/auth/domain.crt -e REGISTRY_HTTP_TLS_KEY=/home/travis/auth/domain.key registry:2
-script:
- # Fail fast
- - set -e
- # Let's do some docker stuff just for verification purposes
-# Commented out the following in order to get travis runs
-# under the 50 minute requirement. Do not remove as we may
-# want to use this in cirrius testing when we move there.
-# - docker ps --all
-# - docker images
-# - ls -alF /home/travis/auth
-# - docker pull docker.io/alpine
-# - echo testpassword | docker login localhost:5000 --username testuser --password-stdin
-# - docker tag alpine localhost:5000/my-alpine
-# - docker push localhost:5000/my-alpine
-# - docker ps --all
-# - docker images
-# - docker rmi docker.io/alpine
-# - docker rmi localhost:5000/my-alpine
-# - docker pull localhost:5000/my-alpine
-# - docker ps --all
-# - docker images
-# - docker rmi localhost:5000/my-alpine
-# End Speed up comment
- # Setting up Docker Registry is complete, let's do Buildah testing!
- - make install.tools -j4
- - make install.libseccomp.sudo all runc validate lint SECURITYTAGS="apparmor seccomp"
- - go test -c -tags "apparmor seccomp `./btrfs_tag.sh` `./libdm_tag.sh` `./selinux_tag.sh`" ./cmd/buildah
- - tmp=`mktemp -d`; mkdir $tmp/root $tmp/runroot; sudo PATH="$PATH" ./buildah.test -test.v --root $tmp/root --runroot $tmp/runroot --storage-driver vfs --signature-policy `pwd`/tests/policy.json --registries-conf `pwd`/tests/registries.conf
- - cd tests; sudo PATH="$PATH" ./test_runner.sh
- - cd ..
diff --git a/vendor/github.com/containers/buildah/CHANGELOG.md b/vendor/github.com/containers/buildah/CHANGELOG.md
index 30dd0dc04..8d1944c65 100644
--- a/vendor/github.com/containers/buildah/CHANGELOG.md
+++ b/vendor/github.com/containers/buildah/CHANGELOG.md
@@ -2,8 +2,121 @@
# Changelog
+## v1.14.3 (2020-03-17)
+ Update containers/storage to v1.16.5
+ Bump github.com/containers/storage from 1.16.2 to 1.16.4
+ Bump github.com/openshift/imagebuilder from 1.1.1 to 1.1.2
+ Update github.com/openshift/imagebuilder vendoring
+ Update unshare man page to fix script example
+ Fix compilation errors on non linux platforms
+ Bump containers/common and opencontainers/selinux versions
+ Add tests for volume ownership
+ Preserve volume uid and gid through subsequent commands
+ Fix FORWARD_NULL errors found by Coverity
+ Bump github.com/containers/storage from 1.16.1 to 1.16.2
+ Fix errors found by codespell
+ Bump back to v1.15.0-dev
+ Add Pull Request Template
+
+## v1.14.2 (2020-03-03)
+ Add Buildah pull request template
+ Bump to containers/storage v1.16.1
+ run_linux: fix tight loop if file is not pollable
+ Bump github.com/opencontainers/selinux from 1.3.2 to 1.3.3
+ Bump github.com/containers/common from 0.4.1 to 0.4.2
+ Bump back to v1.15.0-dev
+ Add Containerfile to build a versioned stable image on quay.io
+
+## v1.14.1 (2020-02-27)
+ Search for local runtime per values in containers.conf
+ Set correct ownership on working directory
+ BATS : in teardown, umount stale mounts
+ Bump github.com/spf13/cobra from 0.0.5 to 0.0.6
+ Bump github.com/fsouza/go-dockerclient from 1.6.1 to 1.6.3
+ Bump github.com/stretchr/testify from 1.4.0 to 1.5.1
+ Replace unix with syscall to allow vendoring into libpod
+ Update to containers/common v0.4.1
+ Improve remote manifest retrieval
+ Fix minor spelling errors in containertools README
+ Clear the right variable in buildahimage
+ Correct a couple of incorrect format specifiers
+ Update to containers/common v0.3.0
+ manifest push --format: force an image type, not a list type
+ run: adjust the order in which elements are added to $PATH
+ getDateAndDigestAndSize(): handle creation time not being set
+ Bump github.com/containers/common from 0.2.0 to 0.2.1
+ include installation steps for CentOS 8 and Stream
+ include installation steps for CentOS7 and forks
+ Adjust Ubuntu install info to also work on Pop!_OS
+ Make the commit id clear like Docker
+ Show error on copied file above context directory in build
+ Bump github.com/containers/image/v5 from 5.2.0 to 5.2.1
+ pull/from/commit/push: retry on most failures
+ Makefile: fix install.cni.sudo
+ Repair buildah so it can use containers.conf on the server side
+ Bump github.com/mattn/go-shellwords from 1.0.9 to 1.0.10
+ Bump github.com/fsouza/go-dockerclient from 1.6.0 to 1.6.1
+ Fixing formatting & build instructions
+ Add Code of Conduct
+ Bors: Fix no. req. github reviews
+ Cirrus+Bors: Simplify temp branch skipping
+ Bors-ng: Add documentation and status-icon
+ Bump github.com/onsi/ginkgo from 1.11.0 to 1.12.0
+ fix XDG_RUNTIME_DIR for authfile
+ Cirrus: Disable F29 testing
+ Cirrus: Add jq package
+ Cirrus: Fix lint + validation using wrong epoch
+ Stop using fedorproject registry
+ Bors: Workaround ineffective required statuses
+ Bors: Enable app + Disable Travis
+ Cirrus: Add standardized log-collection
+ Cirrus: Improve automated lint + validation
+ Allow passing options to golangci-lint
+ Cirrus: Fixes from review feedback
+ Cirrus: Temporarily ignore VM testing failures
+ Cirrus: Migrate off papr + implement VM testing
+ Cirrus: Update packages + fixes for get_ci_vm.sh
+ Show validation command-line
+ Skip overlay test w/ vfs driver
+ use alpine, not centos, for various tests
+ Flake handling: cache and prefetch images
+ Bump to v1.15.0-dev
+
+## v1.14.0 (2020-02-05)
+ bump github.com/mtrmac/gpgme
+ Update containers/common to v0.1.4
+ manifest push: add --format option
+ Bump github.com/onsi/gomega from 1.8.1 to 1.9.0
+ vendor github.com/containers/image/v5@v5.2.0
+ info test: deal with random key order
+ Bump back to v1.14.0-dev
+
+## v1.13.2 (2020-01-29)
+ sign.bats: set GPG_TTY=/dev/null
+ Fix parse_unsupported.go
+ getDateAndDigestAndSize(): use manifest.Digest
+ Bump github.com/opencontainers/selinux from 1.3.0 to 1.3.1
+ Bump github.com/containers/common from 0.1.0 to 0.1.2
+ Touch up os/arch doc
+ chroot: handle slightly broken seccomp defaults
+ buildahimage: specify fuse-overlayfs mount options
+ Bump github.com/mattn/go-shellwords from 1.0.7 to 1.0.9
+ copy.bats: make sure we detect failures due to missing source
+ parse: don't complain about not being able to rename something to itself
+ Makefile: use a $(GO_TEST) macro, fix a typo
+ manifests: unit test fix
+ Fix build for 32bit platforms
+ Allow users to set OS and architecture on bud
+ Fix COPY in containerfile with envvar
+ Bump c/storage to v1.15.7
+ add --sign-by to bud/commit/push, --remove-signatures for pull/push
+ Remove cut/paste error in CHANGELOG.md
+ Update vendor of containers/common to v0.1.0
+ update install instructions for Debian, Raspbian and Ubuntu
+ Add support for containers.conf
+ Bump back to v1.14.0-dev
+
## v1.13.1 (2020-01-14)
-Changelog for v1.13.1 (2020-01-14)
Bump github.com/containers/common from 0.0.5 to 0.0.7
Bump github.com/onsi/ginkgo from 1.10.3 to 1.11.0
Bump github.com/pkg/errors from 0.8.1 to 0.9.0
@@ -25,23 +138,6 @@ Changelog for v1.13.1 (2020-01-14)
discard outputs coming from onbuild command on buildah-from --quiet
make --format columnizing consistent with buildah images
Bump to v1.14.0-dev
- Bump to v1.13.0
- Bump to c/storage v1.15.5
- Update container/storage to v1.15.4
- Fix option handling for volumes in build
- Rework overlay pkg for use with libpod
- Fix buildahimage builds for buildah
- Add support for FIPS-Mode backends
- Set the TMPDIR for pulling/pushing image to $TMPDIR
- WIP: safer test for pull --all-tags
- BATS major cleanup: blobcache.bats: refactor
- BATS major cleanup: part 4: manual stuff
- BATS major cleanup, step 3: yet more run_buildah
- BATS major cleanup, part 2: use more run_buildah
- BATS major cleanup, part 1: log-level
- Bump github.com/containers/image/v5 from 5.0.0 to 5.1.0
- Bump github.com/containers/common from 0.0.3 to 0.0.5
- Bump to v1.13.0-dev
## v1.13.0 (2019-12-27)
Bump to c/storage v1.15.5
diff --git a/vendor/github.com/containers/buildah/CODE-OF-CONDUCT.md b/vendor/github.com/containers/buildah/CODE-OF-CONDUCT.md
new file mode 100644
index 000000000..247674cce
--- /dev/null
+++ b/vendor/github.com/containers/buildah/CODE-OF-CONDUCT.md
@@ -0,0 +1,3 @@
+## The Buildah Project Community Code of Conduct
+
+The Buildah Project follows the [Containers Community Code of Conduct](https://github.com/containers/common/blob/master/CODE-OF-CONDUCT.md).
diff --git a/vendor/github.com/containers/buildah/CONTRIBUTING.md b/vendor/github.com/containers/buildah/CONTRIBUTING.md
index 8118a240b..553cb15dc 100644
--- a/vendor/github.com/containers/buildah/CONTRIBUTING.md
+++ b/vendor/github.com/containers/buildah/CONTRIBUTING.md
@@ -10,6 +10,7 @@ that we follow.
* [Reporting Issues](#reporting-issues)
* [Submitting Pull Requests](#submitting-pull-requests)
* [Sign your PRs](#sign-your-prs)
+* [Merge bot interaction](#merge-bot-interaction)
* [Communications](#communications)
* [Becoming a Maintainer](#becoming-a-maintainer)
@@ -116,6 +117,57 @@ Use your real name (sorry, no pseudonyms or anonymous contributions.)
If you set your `user.name` and `user.email` git configs, you can sign your
commit automatically with `git commit -s`.
+## Merge bot interaction
+
+Maintainers should never merge anything directly into upstream
+branches. Instead, interact with the [bors-ng bot](https://bors.tech/)
+through PR comments as summarized below. This ensures all upstream
+branches contain commits in a predictable order, and that every commit
+has passed automated testing at some point in the past. A
+[Maintainer portal](https://app.bors.tech/repositories/22803)
+is available, showing all PRs awaiting review and approval.
+
+### Common [bors-ng comment commands](https://bors.tech/documentation/):
+
+(must be on a single comment-line, without any other extraneous text)
+
+* `bors r+` - Check the current number of Github Code-review Approvals.
+ If the PR has that many approvals or more, the bot will add the PR into
+ the queue for testing and possible merging. Both the success criteria
+ and minimum approval number are set in the configuration file (see below).
+* `bors retry` - Re-run whatever request was previously issued to the bot. Useful
+ when there was a testing flake upon attempted merge.
+* `bors try` - Optional / simulate the actions of `bors r+` (see above) having
+ met the minimum number of required approvals. The result will be reported
+ back as a comment in the PR, by the bors bot.
+* `bors ping` - Confirm bot is functioning, it will post a comment in the PR if so.
+
+
+### Interaction/Monitoring
+
+Bors-ng relies on the regular branch-testing occurring when it updates the
+special branches ('trying' or 'staging'). Therefore you may use the full
+capabilities available within the CI system. ***Note:*** A single bors-ng
+run may include multiple PRs at once.
+
+The easiest way to access a running 'bors try' or 'bors r+' run, is by clicking the
+yellow-circle "status" icon that shows up in an affected PR, for example:
+
+![Screenshot of Github PR](contrib/cirrus/bors-ng.png)
+
+This will cause a pop-up window to appear with the relevant test-statuses and 'details'
+links available. Since bors-ng will wait for success, as long as one test is still
+running, it's possible to manually re-run any failed tests (e.g. due to flakes).
+
+
+### Configuration of bors-ng:
+
+* The `bors.toml` file in the repository root. This controls
+ runtime options for timeouts, blocking labels, and required status names.
+* The [settings page](https://app.bors.tech/repositories/22803/settings).
+ This contains mostly security-related and branch-control options.
+
+
## Communications
For general questions or discussions, please use the
@@ -126,7 +178,7 @@ that has been setup.
#### Buildah Mailing List
-You can join the Buildah mailing list by sending an email to `buildah-join@lists.buildah.io` with the word `subscribe` in the subject. You can also go to this [page](https://lists.podman.io/admin/lists/buildah.lists.buildah.io/), then scroll down to the bottom of the page and enter your email and optionally name, then click on the "Subscribe" buton.
+You can join the Buildah mailing list by sending an email to `buildah-join@lists.buildah.io` with the word `subscribe` in the subject. You can also go to this [page](https://lists.podman.io/admin/lists/buildah.lists.buildah.io/), then scroll down to the bottom of the page and enter your email and optionally name, then click on the "Subscribe" button.
#### GitHub
You can also use the github
diff --git a/vendor/github.com/containers/buildah/Makefile b/vendor/github.com/containers/buildah/Makefile
index 2e4eb61c4..928a2e64d 100644
--- a/vendor/github.com/containers/buildah/Makefile
+++ b/vendor/github.com/containers/buildah/Makefile
@@ -18,8 +18,10 @@ GOVERSION := $(findstring $(GO110),$(shell go version))
# test for go module support
ifeq ($(shell go help mod >/dev/null 2>&1 && echo true), true)
export GO_BUILD=GO111MODULE=on $(GO) build -mod=vendor
+export GO_TEST=GO111MODULE=on $(GO) test -mod=vendor
else
export GO_BUILD=$(GO) build
+export GO_TEST=$(GO) test
endif
GIT_COMMIT ?= $(if $(shell git rev-parse --short HEAD),$(shell git rev-parse --short HEAD),$(error "git failed"))
@@ -35,6 +37,8 @@ EXTRALDFLAGS :=
LDFLAGS := -ldflags '-X main.GitCommit=$(GIT_COMMIT) -X main.buildInfo=$(SOURCE_DATE_EPOCH) -X main.cniVersion=$(CNI_COMMIT)' $(EXTRALDFLAGS)
SOURCES=*.go imagebuildah/*.go bind/*.go chroot/*.go cmd/buildah/*.go docker/*.go pkg/blobcache/*.go pkg/cli/*.go pkg/parse/*.go util/*.go
+LINTFLAGS ?=
+
all: buildah imgtype docs
.PHONY: static
@@ -97,7 +101,7 @@ install.libseccomp.sudo: gopath
install.cni.sudo: gopath
rm -rf ../../containernetworking/plugins
git clone https://github.com/containernetworking/plugins ../../containernetworking/plugins
- cd ../../containernetworking/plugins && ./build.sh && mkdir -p /opt/cni/bin && sudo install -v -m755 bin/* /opt/cni/bin/
+ cd ../../containernetworking/plugins && ./build_linux.sh && sudo install -D -v -m755 -t /opt/cni/bin/ bin/*
.PHONY: install
install:
@@ -128,10 +132,10 @@ tests/testreport/testreport: tests/testreport/testreport.go
.PHONY: test-unit
test-unit: tests/testreport/testreport
- $(GO) test -v -tags "$(STOAGETAGS) $(SECURITYTAGS)" -race $(shell $(GO) list ./... | grep -v vendor | grep -v tests | grep -v cmd)
+ $(GO_TEST) -v -tags "$(STORAGETAGS) $(SECURITYTAGS)" -race $(shell $(GO) list ./... | grep -v vendor | grep -v tests | grep -v cmd)
tmp=$(shell mktemp -d) ; \
mkdir -p $$tmp/root $$tmp/runroot; \
- $(GO) test -v -tags "$(STORAGETAGS) $(SECURITYTAGS)" ./cmd/buildah -args -root $$tmp/root -runroot $$tmp/runroot -storage-driver vfs -signature-policy $(shell pwd)/tests/policy.json -registries-conf $(shell pwd)/tests/registries.conf
+ $(GO_TEST) -v -tags "$(STORAGETAGS) $(SECURITYTAGS)" ./cmd/buildah -args -root $$tmp/root -runroot $$tmp/runroot -storage-driver vfs -signature-policy $(shell pwd)/tests/policy.json -registries-conf $(shell pwd)/tests/registries.conf
vendor-in-container:
podman run --privileged --rm --env HOME=/root -v `pwd`:/src -w /src docker.io/library/golang:1.13 make vendor
@@ -145,4 +149,4 @@ vendor:
.PHONY: lint
lint: install.tools
- ./tests/tools/build/golangci-lint run
+ ./tests/tools/build/golangci-lint run $(LINTFLAGS)
diff --git a/vendor/github.com/containers/buildah/README.md b/vendor/github.com/containers/buildah/README.md
index 01e376a17..7589da51d 100644
--- a/vendor/github.com/containers/buildah/README.md
+++ b/vendor/github.com/containers/buildah/README.md
@@ -3,7 +3,9 @@
# [Buildah](https://www.youtube.com/embed/YVk5NgSiUw8) - a tool that facilitates building [Open Container Initiative (OCI)](https://www.opencontainers.org/) container images
[![Go Report Card](https://goreportcard.com/badge/github.com/containers/buildah)](https://goreportcard.com/report/github.com/containers/buildah)
-[![Travis](https://travis-ci.org/containers/buildah.svg?branch=master)](https://travis-ci.org/containers/buildah)
+
+[![Bors enabled](https://bors.tech/images/badge_small.svg)](https://app.bors.tech/repositories/22803)
+
The Buildah package provides a command line tool that can be used to
* create a working container, either from scratch or using an image as a starting point
diff --git a/vendor/github.com/containers/buildah/bors.toml b/vendor/github.com/containers/buildah/bors.toml
new file mode 100644
index 000000000..df68695e8
--- /dev/null
+++ b/vendor/github.com/containers/buildah/bors.toml
@@ -0,0 +1,44 @@
+# Bors-ng is a service which provides a merge and review bot for github PRs.
+# When approved for merging (`bors r+`) or test merging (`bors try`), all
+# pending PRs at the time will be merged together in one of two special
+# branches. Either 'staging' or 'trying'. In the case of `staging` branch,
+# when all status tests pass (see below) the serialized set of merges will become
+# the new destination branch HEAD (i.e. master). This guarantees there is never
+# any conflicts with PR merge order on the destination branch(es).
+#
+# Note: The branches 'staging.tmp' and 'trying.tmp' must always be ignored
+# by _all_ CI systems. They are by bors temporarily, and may go away at
+# unpredictable times.
+#
+# Format Ref: https://bors.tech/documentation/#configuration-borstoml
+#
+# status
+# ------------------
+# Selects which tests are required for merging, matching against values
+# from BOTH the older github 'status API' (ref: https://developer.github.com/v3/repos/statuses
+# /#list-statuses-for-a-specific-ref) AND newer 'checks API'. Ref: https://developer.github.com/v3/checks
+# /runs/#list-check-runs-in-a-check-suite both return JSON:
+#
+# Status API: Matches against '[].context' values
+# Checks API: Matches against 'check_runs[].name' values
+#
+# Note: The wild-card character '%' is available.
+status = [
+ "cirrus-ci/success",
+]
+
+# Same as 'status' (above) but statuses that must pass on every PR
+pr_status = [
+ "cirrus-ci/success",
+]
+
+# Cirrus-CI Max Timeout is 60 * 60 * 2
+timeout_sec = 7200
+
+# List of strings: PR Labels that must NOT be present
+block_labels = []
+
+# The number of required GitHub code reviews set 'Approve'
+# before 'bors r+' will allow merging. Does not require
+# the reviewer being in the 'Reviewers' list for the PR.
+required_approvals = 0
diff --git a/vendor/github.com/containers/buildah/buildah.go b/vendor/github.com/containers/buildah/buildah.go
index b359feaf8..0fee906e5 100644
--- a/vendor/github.com/containers/buildah/buildah.go
+++ b/vendor/github.com/containers/buildah/buildah.go
@@ -8,10 +8,10 @@ import (
"io/ioutil"
"os"
"path/filepath"
+ "sort"
"time"
"github.com/containers/buildah/docker"
- "github.com/containers/buildah/util"
"github.com/containers/image/v5/types"
"github.com/containers/storage"
"github.com/containers/storage/pkg/ioutils"
@@ -27,7 +27,7 @@ const (
Package = "buildah"
// Version for the Package. Bump version in contrib/rpm/buildah.spec
// too.
- Version = "1.13.1"
+ Version = "1.14.3"
// The value we use to identify what type of information, currently a
// serialized Builder structure, we are using as per-container state.
// This should only be changed when we make incompatible changes to
@@ -180,13 +180,8 @@ type Builder struct {
CNIConfigDir string
// ID mapping options to use when running processes in the container with non-host user namespaces.
IDMappingOptions IDMappingOptions
- // AddCapabilities is a list of capabilities to add to the default set when running
- // commands in the container.
- AddCapabilities []string
- // DropCapabilities is a list of capabilities to remove from the default set,
- // after processing the AddCapabilities set, when running commands in the container.
- // If a capability appears in both lists, it will be dropped.
- DropCapabilities []string
+ // Capabilities is a list of capabilities to use when running commands in the container.
+ Capabilities []string
// PrependedEmptyLayers are history entries that we'll add to a
// committed image, after any history items that we inherit from a base
// image, but before the history item for the layer that we're
@@ -229,13 +224,11 @@ type BuilderInfo struct {
DefaultMountsFilePath string
Isolation string
NamespaceOptions NamespaceOptions
+ Capabilities []string
ConfigureNetwork string
CNIPluginPath string
CNIConfigDir string
IDMappingOptions IDMappingOptions
- DefaultCapabilities []string
- AddCapabilities []string
- DropCapabilities []string
History []v1.History
Devices []configs.Device
}
@@ -255,6 +248,7 @@ func GetBuildInfo(b *Builder) BuilderInfo {
EmptyLayer: false,
})
history = append(history, copyHistory(b.AppendedEmptyLayers)...)
+ sort.Strings(b.Capabilities)
return BuilderInfo{
Type: b.Type,
FromImage: b.FromImage,
@@ -278,9 +272,7 @@ func GetBuildInfo(b *Builder) BuilderInfo {
CNIPluginPath: b.CNIPluginPath,
CNIConfigDir: b.CNIConfigDir,
IDMappingOptions: b.IDMappingOptions,
- DefaultCapabilities: append([]string{}, util.DefaultCapabilities...),
- AddCapabilities: append([]string{}, b.AddCapabilities...),
- DropCapabilities: append([]string{}, b.DropCapabilities...),
+ Capabilities: b.Capabilities,
History: history,
Devices: b.Devices,
}
@@ -406,19 +398,21 @@ type BuilderOptions struct {
CNIConfigDir string
// ID mapping options to use if we're setting up our own user namespace.
IDMappingOptions *IDMappingOptions
- // AddCapabilities is a list of capabilities to add to the default set when
+ // Capabilities is a list of capabilities to use when
// running commands in the container.
- AddCapabilities []string
- // DropCapabilities is a list of capabilities to remove from the default set,
- // after processing the AddCapabilities set, when running commands in the
- // container. If a capability appears in both lists, it will be dropped.
- DropCapabilities []string
-
+ Capabilities []string
CommonBuildOpts *CommonBuildOptions
// Format for the container image
Format string
// Devices are the additional devices to add to the containers
Devices []configs.Device
+ //DefaultEnv for containers
+ DefaultEnv []string
+ // MaxPullRetries is the maximum number of attempts we'll make to pull
+ // any one image from the external registry if the first attempt fails.
+ MaxPullRetries int
+ // PullRetryDelay is how long to wait before retrying a pull attempt.
+ PullRetryDelay time.Duration
}
// ImportOptions are used to initialize a Builder from an existing container
diff --git a/vendor/github.com/containers/buildah/changelog.txt b/vendor/github.com/containers/buildah/changelog.txt
index 3f48ec4fe..900accf10 100644
--- a/vendor/github.com/containers/buildah/changelog.txt
+++ b/vendor/github.com/containers/buildah/changelog.txt
@@ -1,3 +1,117 @@
+- Changelog for v1.14.3 (2020-03-17)
+ * Update containers/storage to v1.16.5
+ * Bump github.com/containers/storage from 1.16.2 to 1.16.4
+ * Bump github.com/openshift/imagebuilder from 1.1.1 to 1.1.2
+ * Update github.com/openshift/imagebuilder vendoring
+ * Update unshare man page to fix script example
+ * Fix compilation errors on non linux platforms
+ * Bump containers/common and opencontainers/selinux versions
+ * Add tests for volume ownership
+ * Preserve volume uid and gid through subsequent commands
+ * Fix FORWARD_NULL errors found by Coverity
+ * Bump github.com/containers/storage from 1.16.1 to 1.16.2
+ * Fix errors found by codespell
+ * Bump back to v1.15.0-dev
+ * Add Pull Request Template
+
+- Changelog for v1.14.2 (2020-03-03)
+ * Add Buildah pull request template
+ * Bump to containers/storage v1.16.1
+ * run_linux: fix tight loop if file is not pollable
+ * Bump github.com/opencontainers/selinux from 1.3.2 to 1.3.3
+ * Bump github.com/containers/common from 0.4.1 to 0.4.2
+ * Bump back to v1.15.0-dev
+ * Add Containerfile to build a versioned stable image on quay.io
+
+- Changelog for v1.14.1 (2020-02-27)
+ * Search for local runtime per values in containers.conf
+ * Set correct ownership on working directory
+ * BATS : in teardown, umount stale mounts
+ * Bump github.com/spf13/cobra from 0.0.5 to 0.0.6
+ * Bump github.com/fsouza/go-dockerclient from 1.6.1 to 1.6.3
+ * Bump github.com/stretchr/testify from 1.4.0 to 1.5.1
+ * Replace unix with syscall to allow vendoring into libpod
+ * Update to containers/common v0.4.1
+ * Improve remote manifest retrieval
+ * Fix minor spelling errors in containertools README
+ * Clear the right variable in buildahimage
+ * Correct a couple of incorrect format specifiers
+ * Update to containers/common v0.3.0
+ * manifest push --format: force an image type, not a list type
+ * run: adjust the order in which elements are added to $PATH
+ * getDateAndDigestAndSize(): handle creation time not being set
+ * Bump github.com/containers/common from 0.2.0 to 0.2.1
+ * include installation steps for CentOS 8 and Stream
+ * include installation steps for CentOS7 and forks
+ * Adjust Ubuntu install info to also work on Pop!_OS
+ * Make the commit id clear like Docker
+ * Show error on copied file above context directory in build
+ * Bump github.com/containers/image/v5 from 5.2.0 to 5.2.1
+ * pull/from/commit/push: retry on most failures
+ * Makefile: fix install.cni.sudo
+ * Repair buildah so it can use containers.conf on the server side
+ * Bump github.com/mattn/go-shellwords from 1.0.9 to 1.0.10
+ * Bump github.com/fsouza/go-dockerclient from 1.6.0 to 1.6.1
+ * Fixing formatting & build instructions
+ * Add Code of Conduct
+ * Bors: Fix no. req. github reviews
+ * Cirrus+Bors: Simplify temp branch skipping
+ * Bors-ng: Add documentation and status-icon
+ * Bump github.com/onsi/ginkgo from 1.11.0 to 1.12.0
+ * fix XDG_RUNTIME_DIR for authfile
+ * Cirrus: Disable F29 testing
+ * Cirrus: Add jq package
+ * Cirrus: Fix lint + validation using wrong epoch
+ * Stop using fedorproject registry
+ * Bors: Workaround ineffective required statuses
+ * Bors: Enable app + Disable Travis
+ * Cirrus: Add standardized log-collection
+ * Cirrus: Improve automated lint + validation
+ * Allow passing options to golangci-lint
+ * Cirrus: Fixes from review feedback
+ * Cirrus: Temporarily ignore VM testing failures
+ * Cirrus: Migrate off papr + implement VM testing
+ * Cirrus: Update packages + fixes for get_ci_vm.sh
+ * Show validation command-line
+ * Skip overlay test w/ vfs driver
+ * use alpine, not centos, for various tests
+ * Flake handling: cache and prefetch images
+ * Bump to v1.15.0-dev
+
+- Changelog for v1.14.0 (2020-02-05)
+ * bump github.com/mtrmac/gpgme
+ * Update containers/common to v0.1.4
+ * manifest push: add --format option
+ * Bump github.com/onsi/gomega from 1.8.1 to 1.9.0
+ * vendor github.com/containers/image/v5@v5.2.0
+ * info test: deal with random key order
+ * Bump back to v1.14.0-dev
+
+- Changelog for v1.13.2 (2020-01-29)
+ * sign.bats: set GPG_TTY=/dev/null
+ * Fix parse_unsupported.go
+ * getDateAndDigestAndSize(): use manifest.Digest
+ * Bump github.com/opencontainers/selinux from 1.3.0 to 1.3.1
+ * Bump github.com/containers/common from 0.1.0 to 0.1.2
+ * Touch up os/arch doc
+ * chroot: handle slightly broken seccomp defaults
+ * buildahimage: specify fuse-overlayfs mount options
+ * Bump github.com/mattn/go-shellwords from 1.0.7 to 1.0.9
+ * copy.bats: make sure we detect failures due to missing source
+ * parse: don't complain about not being able to rename something to itself
+ * Makefile: use a $(GO_TEST) macro, fix a typo
+ * manifests: unit test fix
+ * Fix build for 32bit platforms
+ * Allow users to set OS and architecture on bud
+ * Fix COPY in containerfile with envvar
+ * Bump c/storage to v1.15.7
+ * add --sign-by to bud/commit/push, --remove-signatures for pull/push
+ * Remove cut/paste error in CHANGELOG.md
+ * Update vendor of containers/common to v0.1.0
+ * update install instructions for Debian, Raspbian and Ubuntu
+ * Add support for containers.conf
+ * Bump back to v1.14.0-dev
+
- Changelog for v1.13.1 (2020-01-14)
* Bump github.com/containers/common from 0.0.5 to 0.0.7
* Bump github.com/onsi/ginkgo from 1.10.3 to 1.11.0
@@ -20,23 +134,6 @@
* discard outputs coming from onbuild command on buildah-from --quiet
* make --format columnizing consistent with buildah images
* Bump to v1.14.0-dev
- * Bump to v1.13.0
- * Bump to c/storage v1.15.5
- * Update container/storage to v1.15.4
- * Fix option handling for volumes in build
- * Rework overlay pkg for use with libpod
- * Fix buildahimage builds for buildah
- * Add support for FIPS-Mode backends
- * Set the TMPDIR for pulling/pushing image to $TMPDIR
- * WIP: safer test for pull --all-tags
- * BATS major cleanup: blobcache.bats: refactor
- * BATS major cleanup: part 4: manual stuff
- * BATS major cleanup, step 3: yet more run_buildah
- * BATS major cleanup, part 2: use more run_buildah
- * BATS major cleanup, part 1: log-level
- * Bump github.com/containers/image/v5 from 5.0.0 to 5.1.0
- * Bump github.com/containers/common from 0.0.3 to 0.0.5
- * Bump to v1.13.0-dev
- Changelog for v1.13.0 (2019-12-27)
* Bump to c/storage v1.15.5
diff --git a/vendor/github.com/containers/buildah/chroot/run.go b/vendor/github.com/containers/buildah/chroot/run.go
index 482fef693..8dfa8aba0 100644
--- a/vendor/github.com/containers/buildah/chroot/run.go
+++ b/vendor/github.com/containers/buildah/chroot/run.go
@@ -656,7 +656,7 @@ func runUsingChrootExecMain() {
// Set the hostname. We're already in a distinct UTS namespace and are admins in the user
// namespace which created it, so we shouldn't get a permissions error, but seccomp policy
// might deny our attempt to call sethostname() anyway, so log a debug message for that.
- if options.Spec.Hostname != "" {
+ if options.Spec != nil && options.Spec.Hostname != "" {
if err := unix.Sethostname([]byte(options.Spec.Hostname)); err != nil {
logrus.Debugf("failed to set hostname %q for process: %v", options.Spec.Hostname, err)
}
diff --git a/vendor/github.com/containers/buildah/chroot/seccomp.go b/vendor/github.com/containers/buildah/chroot/seccomp.go
index f2c55017f..12a9b0032 100644
--- a/vendor/github.com/containers/buildah/chroot/seccomp.go
+++ b/vendor/github.com/containers/buildah/chroot/seccomp.go
@@ -3,7 +3,7 @@
package chroot
import (
- "github.com/opencontainers/runtime-spec/specs-go"
+ specs "github.com/opencontainers/runtime-spec/specs-go"
"github.com/pkg/errors"
libseccomp "github.com/seccomp/libseccomp-golang"
"github.com/sirupsen/logrus"
@@ -118,15 +118,32 @@ func setSeccomp(spec *specs.Spec) error {
continue
}
var conditions []libseccomp.ScmpCondition
+ opsAreAllEquality := true
for _, arg := range rule.Args {
condition, err := libseccomp.MakeCondition(arg.Index, mapOp(arg.Op), arg.Value, arg.ValueTwo)
if err != nil {
return errors.Wrapf(err, "error building a seccomp condition %d:%v:%d:%d", arg.Index, arg.Op, arg.Value, arg.ValueTwo)
}
+ if arg.Op != specs.OpEqualTo {
+ opsAreAllEquality = false
+ }
conditions = append(conditions, condition)
}
if err = filter.AddRuleConditional(scnum, mapAction(rule.Action), conditions); err != nil {
- return errors.Wrapf(err, "error adding a conditional rule (%q:%q) to seccomp filter", scnames[scnum], rule.Action)
+ // Okay, if the rules specify multiple equality
+ // checks, assume someone thought that they
+ // were OR'd, when in fact they're ordinarily
+ // supposed to be AND'd. Break them up into
+ // different rules to get that OR effect.
+ if len(rule.Args) > 1 && opsAreAllEquality && err.Error() == "two checks on same syscall argument" {
+ for i := range conditions {
+ if err = filter.AddRuleConditional(scnum, mapAction(rule.Action), conditions[i:i+1]); err != nil {
+ return errors.Wrapf(err, "error adding a conditional rule (%q:%q[%d]) to seccomp filter", scnames[scnum], rule.Action, i)
+ }
+ }
+ } else {
+ return errors.Wrapf(err, "error adding a conditional rule (%q:%q) to seccomp filter", scnames[scnum], rule.Action)
+ }
}
}
}
diff --git a/vendor/github.com/containers/buildah/commit.go b/vendor/github.com/containers/buildah/commit.go
index 24642f4dc..d25ba110a 100644
--- a/vendor/github.com/containers/buildah/commit.go
+++ b/vendor/github.com/containers/buildah/commit.go
@@ -12,7 +12,6 @@ import (
"github.com/containers/buildah/pkg/blobcache"
"github.com/containers/buildah/util"
- cp "github.com/containers/image/v5/copy"
"github.com/containers/image/v5/docker"
"github.com/containers/image/v5/docker/reference"
"github.com/containers/image/v5/manifest"
@@ -81,6 +80,14 @@ type CommitOptions struct {
// OmitTimestamp forces epoch 0 as created timestamp to allow for
// deterministic, content-addressable builds.
OmitTimestamp bool
+ // SignBy is the fingerprint of a GPG key to use for signing the image.
+ SignBy string
+ // MaxRetries is the maximum number of attempts we'll make to commit
+ // the image to an external registry if the first attempt fails.
+ MaxRetries int
+ // RetryDelay is how long to wait before retrying a commit attempt to a
+ // registry.
+ RetryDelay time.Duration
}
// PushOptions can be used to alter how an image is copied somewhere.
@@ -115,6 +122,16 @@ type PushOptions struct {
// the user will be displayed, this is best used for logging.
// The default is false.
Quiet bool
+ // SignBy is the fingerprint of a GPG key to use for signing the image.
+ SignBy string
+ // RemoveSignatures causes any existing signatures for the image to be
+ // discarded for the pushed copy.
+ RemoveSignatures bool
+ // MaxRetries is the maximum number of attempts we'll make to push any
+ // one image to the external registry if the first attempt fails.
+ MaxRetries int
+ // RetryDelay is how long to wait before retrying a push attempt.
+ RetryDelay time.Duration
}
var (
@@ -293,8 +310,16 @@ func (b *Builder) Commit(ctx context.Context, dest types.ImageReference, options
case archive.Gzip:
systemContext.DirForceCompress = true
}
+
+ if systemContext.ArchitectureChoice != b.Architecture() {
+ systemContext.ArchitectureChoice = b.Architecture()
+ }
+ if systemContext.OSChoice != b.OS() {
+ systemContext.OSChoice = b.OS()
+ }
+
var manifestBytes []byte
- if manifestBytes, err = cp.Image(ctx, policyContext, maybeCachedDest, maybeCachedSrc, getCopyOptions(b.store, options.ReportWriter, nil, systemContext, "")); err != nil {
+ if manifestBytes, err = retryCopyImage(ctx, policyContext, maybeCachedDest, maybeCachedSrc, dest, "push", getCopyOptions(b.store, options.ReportWriter, nil, systemContext, "", false, options.SignBy), options.MaxRetries, options.RetryDelay); err != nil {
return imgID, nil, "", errors.Wrapf(err, "error copying layers and metadata for container %q", b.ContainerID)
}
// If we've got more names to attach, and we know how to do that for
@@ -426,7 +451,7 @@ func Push(ctx context.Context, image string, dest types.ImageReference, options
systemContext.DirForceCompress = true
}
var manifestBytes []byte
- if manifestBytes, err = cp.Image(ctx, policyContext, dest, maybeCachedSrc, getCopyOptions(options.Store, options.ReportWriter, nil, systemContext, options.ManifestType)); err != nil {
+ if manifestBytes, err = retryCopyImage(ctx, policyContext, dest, maybeCachedSrc, dest, "push", getCopyOptions(options.Store, options.ReportWriter, nil, systemContext, options.ManifestType, options.RemoveSignatures, options.SignBy), options.MaxRetries, options.RetryDelay); err != nil {
return nil, "", errors.Wrapf(err, "error copying layers and metadata from %q to %q", transports.ImageName(maybeCachedSrc), transports.ImageName(dest))
}
if options.ReportWriter != nil {
diff --git a/vendor/github.com/containers/buildah/common.go b/vendor/github.com/containers/buildah/common.go
index 35a7c6538..22bbb1efd 100644
--- a/vendor/github.com/containers/buildah/common.go
+++ b/vendor/github.com/containers/buildah/common.go
@@ -1,14 +1,26 @@
package buildah
import (
+ "context"
"io"
+ "net"
+ "net/url"
"os"
"path/filepath"
+ "syscall"
+ "time"
"github.com/containers/common/pkg/unshare"
cp "github.com/containers/image/v5/copy"
+ "github.com/containers/image/v5/docker"
+ "github.com/containers/image/v5/signature"
"github.com/containers/image/v5/types"
"github.com/containers/storage"
+ "github.com/docker/distribution/registry/api/errcode"
+ errcodev2 "github.com/docker/distribution/registry/api/v2"
+ multierror "github.com/hashicorp/go-multierror"
+ "github.com/pkg/errors"
+ "github.com/sirupsen/logrus"
)
const (
@@ -18,7 +30,7 @@ const (
DOCKER = "docker"
)
-func getCopyOptions(store storage.Store, reportWriter io.Writer, sourceSystemContext *types.SystemContext, destinationSystemContext *types.SystemContext, manifestType string) *cp.Options {
+func getCopyOptions(store storage.Store, reportWriter io.Writer, sourceSystemContext *types.SystemContext, destinationSystemContext *types.SystemContext, manifestType string, removeSignatures bool, addSigner string) *cp.Options {
sourceCtx := getSystemContext(store, nil, "")
if sourceSystemContext != nil {
*sourceCtx = *sourceSystemContext
@@ -33,6 +45,8 @@ func getCopyOptions(store storage.Store, reportWriter io.Writer, sourceSystemCon
SourceCtx: sourceCtx,
DestinationCtx: destinationCtx,
ForceManifestMIMEType: manifestType,
+ RemoveSignatures: removeSignatures,
+ SignBy: addSigner,
}
}
@@ -57,3 +71,65 @@ func getSystemContext(store storage.Store, defaults *types.SystemContext, signat
}
return sc
}
+
+func isRetryable(err error) bool {
+ err = errors.Cause(err)
+ type unwrapper interface {
+ Unwrap() error
+ }
+ if unwrapper, ok := err.(unwrapper); ok {
+ err = unwrapper.Unwrap()
+ return isRetryable(err)
+ }
+ if registryError, ok := err.(errcode.Error); ok {
+ switch registryError.Code {
+ case errcode.ErrorCodeUnauthorized, errcodev2.ErrorCodeNameUnknown, errcodev2.ErrorCodeManifestUnknown:
+ return false
+ }
+ return true
+ }
+ if op, ok := err.(*net.OpError); ok {
+ return isRetryable(op.Err)
+ }
+ if url, ok := err.(*url.Error); ok {
+ return isRetryable(url.Err)
+ }
+ if errno, ok := err.(syscall.Errno); ok {
+ if errno == syscall.ECONNREFUSED {
+ return false
+ }
+ }
+ if errs, ok := err.(errcode.Errors); ok {
+ // if this error is a group of errors, process them all in turn
+ for i := range errs {
+ if !isRetryable(errs[i]) {
+ return false
+ }
+ }
+ }
+ if errs, ok := err.(*multierror.Error); ok {
+ // if this error is a group of errors, process them all in turn
+ for i := range errs.Errors {
+ if !isRetryable(errs.Errors[i]) {
+ return false
+ }
+ }
+ }
+ return true
+}
+
+func retryCopyImage(ctx context.Context, policyContext *signature.PolicyContext, dest, src, registry types.ImageReference, action string, copyOptions *cp.Options, maxRetries int, retryDelay time.Duration) ([]byte, error) {
+ manifestBytes, err := cp.Image(ctx, policyContext, dest, src, copyOptions)
+ for retries := 0; err != nil && isRetryable(err) && registry != nil && registry.Transport().Name() == docker.Transport.Name() && retries < maxRetries; retries++ {
+ if retryDelay == 0 {
+ retryDelay = 5 * time.Second
+ }
+ logrus.Infof("Warning: %s failed, retrying in %s ... (%d/%d)", action, retryDelay, retries+1, maxRetries)
+ time.Sleep(retryDelay)
+ manifestBytes, err = cp.Image(ctx, policyContext, dest, src, copyOptions)
+ if err == nil {
+ break
+ }
+ }
+ return manifestBytes, err
+}
diff --git a/vendor/github.com/containers/buildah/go.mod b/vendor/github.com/containers/buildah/go.mod
index b4f7d82db..862c7e1a2 100644
--- a/vendor/github.com/containers/buildah/go.mod
+++ b/vendor/github.com/containers/buildah/go.mod
@@ -3,46 +3,39 @@ module github.com/containers/buildah
go 1.12
require (
- github.com/blang/semver v3.5.0+incompatible // indirect
- github.com/containernetworking/cni v0.7.1
- github.com/containers/common v0.0.7
- github.com/containers/image/v5 v5.1.0
- github.com/containers/storage v1.15.5
+ github.com/containernetworking/cni v0.7.2-0.20190904153231-83439463f784
+ github.com/containers/common v0.5.0
+ github.com/containers/image/v5 v5.2.1
+ github.com/containers/storage v1.16.5
github.com/cyphar/filepath-securejoin v0.2.2
github.com/docker/distribution v2.7.1+incompatible
github.com/docker/go-metrics v0.0.1 // indirect
github.com/docker/go-units v0.4.0
github.com/docker/libnetwork v0.8.0-dev.2.0.20190625141545-5a177b73e316
github.com/etcd-io/bbolt v1.3.3
- github.com/fsouza/go-dockerclient v1.6.0
+ github.com/fsouza/go-dockerclient v1.6.3
github.com/ghodss/yaml v1.0.0
github.com/hashicorp/go-multierror v1.0.0
- github.com/ishidawataru/sctp v0.0.0-20180918013207-6e2cb1366111 // indirect
- github.com/mattn/go-shellwords v1.0.6
- github.com/morikuni/aec v1.0.0 // indirect
- github.com/onsi/ginkgo v1.11.0
- github.com/onsi/gomega v1.8.1
+ github.com/ishidawataru/sctp v0.0.0-20191218070446-00ab2ac2db07 // indirect
+ github.com/mattn/go-shellwords v1.0.10
+ github.com/onsi/ginkgo v1.12.0
+ github.com/onsi/gomega v1.9.0
github.com/opencontainers/go-digest v1.0.0-rc1
github.com/opencontainers/image-spec v1.0.2-0.20190823105129-775207bd45b6
github.com/opencontainers/runc v1.0.0-rc9
github.com/opencontainers/runtime-spec v0.1.2-0.20190618234442-a950415649c7
github.com/opencontainers/runtime-tools v0.9.0
- github.com/opencontainers/selinux v1.3.0
+ github.com/opencontainers/selinux v1.4.0
github.com/openshift/api v0.0.0-20200106203948-7ab22a2c8316
- github.com/openshift/imagebuilder v1.1.1
- github.com/pkg/errors v0.9.0
- github.com/seccomp/containers-golang v0.0.0-20180629143253-cdfdaa7543f4
+ github.com/openshift/imagebuilder v1.1.2
+ github.com/pkg/errors v0.9.1
+ github.com/seccomp/containers-golang v0.0.0-20190312124753-8ca8945ccf5f
github.com/seccomp/libseccomp-golang v0.9.1
github.com/sirupsen/logrus v1.4.2
- github.com/spf13/cobra v0.0.5
+ github.com/spf13/cobra v0.0.6
github.com/spf13/pflag v1.0.5
- github.com/stretchr/testify v1.4.0
+ github.com/stretchr/testify v1.5.1
github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2
- github.com/vishvananda/netlink v1.0.0 // indirect
- github.com/vishvananda/netns v0.0.0-20190625233234-7109fa855b0f // indirect
- github.com/xeipuuv/gojsonschema v1.1.0 // indirect
- golang.org/x/crypto v0.0.0-20191112222119-e1110fd1c708
+ golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975
golang.org/x/sys v0.0.0-20191127021746-63cb32ae39b2
- golang.org/x/time v0.0.0-20190921001708-c4c64cad1fd0 // indirect
- k8s.io/client-go v0.0.0-20181219152756-3dd551c0f083 // indirect
)
diff --git a/vendor/github.com/containers/buildah/go.sum b/vendor/github.com/containers/buildah/go.sum
index e32fb0bec..17ea81042 100644
--- a/vendor/github.com/containers/buildah/go.sum
+++ b/vendor/github.com/containers/buildah/go.sum
@@ -1,13 +1,16 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
+cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
github.com/14rcole/gopopulate v0.0.0-20180821133914-b175b219e774 h1:SCbEWT58NSt7d2mcFdvxC9uyrdcTfvBbPLThhkDmXzg=
github.com/14rcole/gopopulate v0.0.0-20180821133914-b175b219e774/go.mod h1:6/0dYRLLXyJjbkIPeeGyoJ/eKOSI0eU6eTlCBYibgd0=
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 h1:w+iIsaOQNcT7OZ575w+acHgRric5iCyQh+xv+KJ4HB8=
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
+github.com/Azure/go-autorest v11.1.2+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/DataDog/zstd v1.4.0 h1:vhoV+DUHnRZdKW1i5UMjAk2G4JY8wN4ayRfYDNdEhwo=
github.com/DataDog/zstd v1.4.0/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo=
+github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA=
github.com/Microsoft/go-winio v0.4.12 h1:xAfWHN1IrQ0NJ9TBC0KBZoqLjzDTr1ML+4MywiUOryc=
github.com/Microsoft/go-winio v0.4.12/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA=
github.com/Microsoft/go-winio v0.4.14 h1:+hMXMk01us9KgxGb7ftKQt2Xpf5hH/yky+TDA+qxleU=
@@ -21,23 +24,35 @@ github.com/Microsoft/hcsshim v0.8.7-0.20191101173118-65519b62243c/go.mod h1:7xhj
github.com/Microsoft/hcsshim v0.8.7 h1:ptnOoufxGSzauVTsdE+wMYnCWA301PdoN4xg5oRdZpg=
github.com/Microsoft/hcsshim v0.8.7/go.mod h1:OHd7sQqRFrYd3RmSgbgji+ctCwkbq2wbEYNSzOYtcBQ=
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
+github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
github.com/VividCortex/ewma v1.1.1 h1:MnEK4VOv6n0RSY4vtRe3h11qjxL3+t0B8yOL8iMXdcM=
github.com/VividCortex/ewma v1.1.1/go.mod h1:2Tkkvm3sRDVXaiyucHiACn4cqf7DpdyLvmxzcbUokwA=
+github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d h1:licZJFw2RwpHMqeKTCYkitsPqHNxTmd4SNR5r94FGM8=
+github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d/go.mod h1:asat636LX7Bqt5lYEZ27JNDcqxfjdBQuJ/MM4CN/Lzo=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
+github.com/alexflint/go-filemutex v0.0.0-20171022225611-72bdc8eae2ae/go.mod h1:CgnQgUtFrFz9mxFNtED3jI5tLDjKlOM+oUF/sTk6ps0=
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
+github.com/blang/semver v3.1.0+incompatible h1:7hqmJYuaEK3qwVjWubYiht3j93YI0WQBuysxHIfUriU=
github.com/blang/semver v3.1.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
github.com/blang/semver v3.5.0+incompatible h1:CGxCgetQ64DKk7rdZ++Vfnb1+ogGNnB17OJKJXD2Cfs=
github.com/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
+github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ=
+github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
+github.com/buger/goterm v0.0.0-20181115115552-c206103e1f37/go.mod h1:u9UyCz2eTrSGy6fbupqJ54eY5c4IC8gREQ1053dK12U=
+github.com/buger/jsonparser v0.0.0-20180808090653-f4dd9f5a6b44/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s=
+github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
+github.com/checkpoint-restore/go-criu v0.0.0-20190109184317-bdb7599cd87b/go.mod h1:TrMrLQfeENAPYPRsJuq3jsqdlRh3lvi6trTZJG8+tho=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
+github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=
github.com/containerd/cgroups v0.0.0-20190919134610-bf292b21730f h1:tSNMc+rJDfmYntojat8lljbt1mgKNpTxUZJsSzJ9Y1s=
github.com/containerd/cgroups v0.0.0-20190919134610-bf292b21730f/go.mod h1:OApqhQ4XNSNC13gXIwDjhOQxjWa/NxkwZXJ1EvqT0ko=
github.com/containerd/console v0.0.0-20180822173158-c12b1e7919c1/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw=
@@ -56,22 +71,63 @@ github.com/containerd/ttrpc v0.0.0-20190828154514-0e0f228740de/go.mod h1:PvCDdDG
github.com/containerd/typeurl v0.0.0-20180627222232-a93fcdb778cd/go.mod h1:Cm3kwCdlkCfMSHURc+r6fwoGH6/F1hH3S4sg0rLFWPc=
github.com/containernetworking/cni v0.7.1 h1:fE3r16wpSEyaqY4Z4oFrLMmIGfBYIKpPrHK31EJ9FzE=
github.com/containernetworking/cni v0.7.1/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY=
+github.com/containernetworking/cni v0.7.2-0.20190904153231-83439463f784 h1:rqUVLD8I859xRgUx/WMC3v7QAFqbLKZbs+0kqYboRJc=
+github.com/containernetworking/cni v0.7.2-0.20190904153231-83439463f784/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY=
+github.com/containernetworking/plugins v0.8.5/go.mod h1:UZ2539umj8djuRQmBxuazHeJbYrLV8BSBejkk+she6o=
+github.com/containers/buildah v1.13.1/go.mod h1:U0LcOzSqoYdyQC5L2hMeLbtCDuCCLxmZV1eb+SWY4GA=
github.com/containers/common v0.0.3 h1:C2Zshb0w720FqPa42MCRuiGfbW0kwbURRwvK1EWIC5I=
github.com/containers/common v0.0.3/go.mod h1:CaOgMRiwi2JJHISMZ6VPPZhQYFUDRv3YYVss2RqUCMg=
github.com/containers/common v0.0.5 h1:Hi4+eyUZx8hXB4reLNPbdT6XT8MGMAzdlbg8V+WifkQ=
github.com/containers/common v0.0.5/go.mod h1:lhWV3MLhO1+KGE2x6v9+K38MxpjXGso+edmpkFnCOqI=
github.com/containers/common v0.0.7 h1:eKYZLKfJ2d/RNDgecLDFv45cHb4imYzIcrQHx1Y029M=
github.com/containers/common v0.0.7/go.mod h1:lhWV3MLhO1+KGE2x6v9+K38MxpjXGso+edmpkFnCOqI=
+github.com/containers/common v0.0.8-0.20200106141003-a79791495fd1 h1:udiDqxQSdunVXNjBW4icHrnFLNOiTpvH6GRG+ywA4f4=
+github.com/containers/common v0.0.8-0.20200106141003-a79791495fd1/go.mod h1:lhWV3MLhO1+KGE2x6v9+K38MxpjXGso+edmpkFnCOqI=
+github.com/containers/common v0.0.8-0.20200108114752-d87ce6ce296b h1:G+DKyzrku0fC5Qa3paArNBERTwRleTg45ypY0qjo7YM=
+github.com/containers/common v0.0.8-0.20200108114752-d87ce6ce296b/go.mod h1:ss8uGpUsaDE4DPmaVFOjzKrlgf5eUnSAWL+d/PYGaoM=
+github.com/containers/common v0.1.0 h1:RsAxx1yeepYhXXEasNpspi/nPC8KKP1AzzOgEuvfWXk=
+github.com/containers/common v0.1.0/go.mod h1:ss8uGpUsaDE4DPmaVFOjzKrlgf5eUnSAWL+d/PYGaoM=
+github.com/containers/common v0.1.2 h1:EYAgJsQgH3akh6kdlN4c2t09bqRgyzpxyWmlFTf1Igc=
+github.com/containers/common v0.1.2/go.mod h1:ss8uGpUsaDE4DPmaVFOjzKrlgf5eUnSAWL+d/PYGaoM=
+github.com/containers/common v0.1.4 h1:6tizbvX9BJTnJ0S3pe65Vcu8gJagbm6oFBCmwUIiOE4=
+github.com/containers/common v0.1.4/go.mod h1:ss8uGpUsaDE4DPmaVFOjzKrlgf5eUnSAWL+d/PYGaoM=
+github.com/containers/common v0.2.0 h1:umTbAiX39/0oNxHn10ia0RyXrZCs/CnjJQlRiTdiXb8=
+github.com/containers/common v0.2.0/go.mod h1:ss8uGpUsaDE4DPmaVFOjzKrlgf5eUnSAWL+d/PYGaoM=
+github.com/containers/common v0.2.1 h1:sEMQm9S+Z7zaQNaSJYbJ5DeR539rk8qscH11RMYw9Fk=
+github.com/containers/common v0.2.1/go.mod h1:ss8uGpUsaDE4DPmaVFOjzKrlgf5eUnSAWL+d/PYGaoM=
+github.com/containers/common v0.3.0 h1:9ysL/OfPcMls1Ac3jzFA4XZJVSD/JG7Dst3uQSwQtwA=
+github.com/containers/common v0.3.0/go.mod h1:AiPCv0ZcBOVshnup/X6MuaqkySZQZ3iBWfInjJFIl40=
+github.com/containers/common v0.4.0 h1:LpX2J19cZKSpn4PBtbLX/tTk3JzTtaqRWbaEoX5YGAI=
+github.com/containers/common v0.4.0/go.mod h1:AiPCv0ZcBOVshnup/X6MuaqkySZQZ3iBWfInjJFIl40=
+github.com/containers/common v0.4.1 h1:Uu7f2ZDM/5xsqOkZwIEVKSjUI3YxKjvNIY5x57kjaKo=
+github.com/containers/common v0.4.1/go.mod h1:m62kenckrWi5rZx32kaLje2Og0hpf6NsaTBn6+b+Oys=
+github.com/containers/common v0.4.2 h1:O5d1gj/xdpQdZi0MEivRQ/7AeRaVeHdbSP/bvShw458=
+github.com/containers/common v0.4.2/go.mod h1:m62kenckrWi5rZx32kaLje2Og0hpf6NsaTBn6+b+Oys=
+github.com/containers/common v0.4.3 h1:TJ7UQxB8wf//IY4LNZobswrTjbhIjXpidrRbCA2l+kg=
+github.com/containers/common v0.4.3/go.mod h1:m62kenckrWi5rZx32kaLje2Og0hpf6NsaTBn6+b+Oys=
+github.com/containers/common v0.4.4 h1:oXQUPDQOIQ+XmQ2cWyLCs2TctDfISykAr1gEa3CNwlQ=
+github.com/containers/common v0.4.4/go.mod h1:vMkHkvczHslJbUj8xasSQmdNrLUgZYuUxVNGJDfjRIQ=
+github.com/containers/common v0.5.0 h1:ZAef7h3oO46PcbTyfooZf8XLHrYad+GkhSu3EhH6P24=
+github.com/containers/common v0.5.0/go.mod h1:m62kenckrWi5rZx32kaLje2Og0hpf6NsaTBn6+b+Oys=
+github.com/containers/common v1.0.0 h1:sZB48LzGP4bP1CmrkQIFUzdUVBysqRv3kWVk4+qbaVA=
+github.com/containers/common v1.0.0/go.mod h1:m62kenckrWi5rZx32kaLje2Og0hpf6NsaTBn6+b+Oys=
+github.com/containers/conmon v2.0.10+incompatible/go.mod h1:hgwZ2mtuDrppv78a/cOBNiCm6O0UMWGx1mu7P00nu5I=
github.com/containers/image/v4 v4.0.1 h1:idNGHChj0Pyv3vLrxul2oSVMZLeFqpoq3CjLeVgapSQ=
github.com/containers/image/v4 v4.0.1/go.mod h1:0ASJH1YgJiX/eqFZObqepgsvIA4XjCgpyfwn9pDGafA=
github.com/containers/image/v5 v5.0.0 h1:arnXgbt1ucsC/ndtSpiQY87rA0UjhF+/xQnPzqdBDn4=
github.com/containers/image/v5 v5.0.0/go.mod h1:MgiLzCfIeo8lrHi+4Lb8HP+rh513sm0Mlk6RrhjFOLY=
github.com/containers/image/v5 v5.1.0 h1:5FjAvPJniamuNNIQHkh4PnsL+n+xzs6Aonzaz5dqTEo=
github.com/containers/image/v5 v5.1.0/go.mod h1:BKlMD34WxRo1ruGHHEOrPQP0Qci7SWoPwU6fS7arsCU=
+github.com/containers/image/v5 v5.2.0 h1:DowY5OII5x9Pb6Pt76vnHU79BgG4/jdwhZjeAj2R+t8=
+github.com/containers/image/v5 v5.2.0/go.mod h1:IAub4gDGvXoxaIAdNy4e3FbVTDPVNMv9F0UfVVFbYCU=
+github.com/containers/image/v5 v5.2.1 h1:rQR6QSUneWBoW1bTFpP9EJJTevQFv27YsKYQVJIzg+s=
+github.com/containers/image/v5 v5.2.1/go.mod h1:TfhmLwH+v1/HBVPIWH7diLs8XwcOkP3c7t7JFgqaUEc=
+github.com/containers/libpod v1.8.0/go.mod h1:53h7AOg4tQSX1rqKfR78/6Us/whERRzCQ20z0GiR44U=
github.com/containers/libtrust v0.0.0-20190913040956-14b96171aa3b h1:Q8ePgVfHDplZ7U33NwHZkrVELsZP5fYj9pM5WBZB2GE=
github.com/containers/libtrust v0.0.0-20190913040956-14b96171aa3b/go.mod h1:9rfv8iPl1ZP7aqh9YA68wnZv2NUDbXdcdPHVz0pFbPY=
github.com/containers/ocicrypt v0.0.0-20190930154801-b87a4a69c741 h1:8tQkOcednLJtUcZgK7sPglscXtxvMOnFOa6wd09VWLM=
github.com/containers/ocicrypt v0.0.0-20190930154801-b87a4a69c741/go.mod h1:MeJDzk1RJHv89LjsH0Sp5KTY3ZYkjXO/C+bKAeWFIrc=
+github.com/containers/psgo v1.4.0/go.mod h1:ENXXLQ5E1At4K0EUsGogXBJi/C28gwqkONWeLPI9fJ8=
github.com/containers/storage v1.13.2/go.mod h1:6D8nK2sU9V7nEmAraINRs88ZEscM5C5DK+8Npp27GeA=
github.com/containers/storage v1.13.4 h1:j0bBaJDKbUHtAW1MXPFnwXJtqcH+foWeuXK1YaBV5GA=
github.com/containers/storage v1.13.4/go.mod h1:6D8nK2sU9V7nEmAraINRs88ZEscM5C5DK+8Npp27GeA=
@@ -93,20 +149,49 @@ github.com/containers/storage v1.15.4 h1:eiUtV9MOTnPHibO18nDRI+aDhKudY7WmAiJdyVM
github.com/containers/storage v1.15.4/go.mod h1:v0lq/3f+cXH3Y/HiDaFYRR0zilwDve7I4W7U5xQxvF8=
github.com/containers/storage v1.15.5 h1:dBZx9yRFHod9c8FVaXlVtRqr2cmlAhpl+9rt87cE7J4=
github.com/containers/storage v1.15.5/go.mod h1:v0lq/3f+cXH3Y/HiDaFYRR0zilwDve7I4W7U5xQxvF8=
+github.com/containers/storage v1.15.7 h1:ecPmv2y/qpxeSTHZ147jQLO6to8wDn8yUPtDCZlz0H4=
+github.com/containers/storage v1.15.7/go.mod h1:gLZIp+/hP8nFn9tLS0uJlnk4h1tSoDu3oS2eFiaIqkE=
+github.com/containers/storage v1.15.8 h1:ef7OfUMTpyq0PIVAhV7qfufEI92gAldk25nItrip+6Q=
+github.com/containers/storage v1.15.8/go.mod h1:zhvjIIl/fR6wt/lgqQAC+xanHQ+8gUQ0GBVeXYN81qI=
+github.com/containers/storage v1.16.0 h1:sD+s7BmiNBh61CuHN3j8PXGCwMtV9zPVJETAlshIf3w=
+github.com/containers/storage v1.16.0/go.mod h1:nqN09JSi1/RSI1UAUwDYXPRiGSlq5FPbNkN/xb0TfG0=
+github.com/containers/storage v1.16.1 h1:gVLVqbqaoyopLJbcQ9PQdsnm8SzVy6Vw24fofwMgkE0=
+github.com/containers/storage v1.16.1/go.mod h1:toFp72SLn/iyJ6YbrnrZ0bW63aH2Qw3dA8JVwL4ADPo=
+github.com/containers/storage v1.16.2 h1:S77Y+lmJcnGoPEZB2OOrTrRGyjT8viDCGyhVNNz78h8=
+github.com/containers/storage v1.16.2/go.mod h1:/RNmsK01ajCL+VtMSi3W8kHzpBwN+Q5gLYWgfw5wlMg=
+github.com/containers/storage v1.16.3 h1:bctiz1I+0TIivtXbrVmy02ZYlOA+IjKIJMzAMTBifj8=
+github.com/containers/storage v1.16.3/go.mod h1:dNTv0+BaebIAOGgH34dPtwGPR+Km2fObcfOlFxYFwA0=
+github.com/containers/storage v1.16.4 h1:+pEL9A1i11qy1j/MYvh8Y5vs79BBfA+hslyJq1iPOGc=
+github.com/containers/storage v1.16.4/go.mod h1:SdysZeLKJOvfHYysUWg9OZUC3gdZWi5b2b7NC18VpPE=
+github.com/containers/storage v1.16.5 h1:eHeWEhUEWX3VMIG1Vn1rEjfRoLHUQev3cwtA5zd89wk=
+github.com/containers/storage v1.16.5/go.mod h1:SdysZeLKJOvfHYysUWg9OZUC3gdZWi5b2b7NC18VpPE=
+github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
+github.com/coreos/go-iptables v0.4.5/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmekav8Dbxlm1MU=
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
+github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f h1:JOrtw2xFKzlg+cbHpyrpLDmnN1HqhBfnX7WDiW7eG2c=
github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
+github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
+github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
+github.com/cri-o/ocicni v0.1.1-0.20190920040751-deac903fd99b/go.mod h1:ZOuIEOp/3MB1eCBWANnNxM3zUA3NWh76wSRCsnKAg2c=
github.com/cyphar/filepath-securejoin v0.2.2 h1:jCwT2GTP+PY5nBz3c/YL5PAIbusElVrPujOBSCj8xRg=
github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4=
+github.com/d2g/dhcp4 v0.0.0-20170904100407-a1d1b6c41b1c/go.mod h1:Ct2BUK8SB0YC1SMSibvLzxjeJLnrYEVLULFNiHY9YfQ=
+github.com/d2g/dhcp4client v1.0.0/go.mod h1:j0hNfjhrt2SxUOw55nL0ATM/z4Yt3t2Kd1mW34z5W5s=
+github.com/d2g/dhcp4server v0.0.0-20181031114812-7d4a0a7f59a5/go.mod h1:Eo87+Kg/IX2hfWJfwxMzLyuSZyxSoAug2nGa1G2QAi8=
+github.com/d2g/hardwareaddr v0.0.0-20190221164911-e7d9fbe030e4/go.mod h1:bMl4RjIciD2oAxI7DmWRx6gbeqrkoLqv3MV0vzNad+I=
github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/dgrijalva/jwt-go v0.0.0-20160705203006-01aeca54ebda/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
+github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
+github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
github.com/docker/distribution v0.0.0-20170817175659-5f6282db7d65/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
github.com/docker/distribution v2.7.1+incompatible h1:a5mlkVzth6W5A4fOsS3D2EO5BUmsJpcB+cRlLU7cSug=
github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
@@ -118,6 +203,8 @@ github.com/docker/docker v1.4.2-0.20190927142053-ada3c14355ce h1:H3csZuxZESJeeEi
github.com/docker/docker v1.4.2-0.20190927142053-ada3c14355ce/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/docker v1.4.2-0.20191101170500-ac7306503d23 h1:oqgGT9O61YAYvI41EBsLePOr+LE6roB0xY4gpkZuFSE=
github.com/docker/docker v1.4.2-0.20191101170500-ac7306503d23/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
+github.com/docker/docker v1.4.2-0.20191219165747-a9416c67da9f h1:Sm8iD2lifO31DwXfkGzq8VgA7rwxPjRsYmeo0K/dF9Y=
+github.com/docker/docker v1.4.2-0.20191219165747-a9416c67da9f/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/docker-credential-helpers v0.6.0/go.mod h1:WRaJzqw3CTB9bk10avuGsjVBZsD05qeibJ1/TYlvc0Y=
github.com/docker/docker-credential-helpers v0.6.1 h1:Dq4iIfcM7cNtddhLVWe9h4QDjsi4OER3Z8voPu/I52g=
github.com/docker/docker-credential-helpers v0.6.1/go.mod h1:WRaJzqw3CTB9bk10avuGsjVBZsD05qeibJ1/TYlvc0Y=
@@ -135,12 +222,18 @@ github.com/docker/libnetwork v0.8.0-dev.2.0.20190625141545-5a177b73e316/go.mod h
github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7 h1:UhxFibDNY/bfvqU5CAUmr9zpesgbU6SWc8/B4mflAE4=
github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE=
github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM=
+github.com/docker/spdystream v0.0.0-20181023171402-6480d4af844c/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM=
+github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
+github.com/elazarl/goproxy v0.0.0-20190421051319-9d40249d3c2f/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
+github.com/elazarl/goproxy/ext v0.0.0-20190911111923-ecfe977594f1/go.mod h1:gNh8nYJoAm43RfaxurUnxr+N1PwuFV3ZMl/efxlIlY8=
github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
github.com/etcd-io/bbolt v1.3.3 h1:gSJmxrs37LgTqR/oyJBWok6k6SvXEUerFTbltIhXkBM=
github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw=
+github.com/evanphx/json-patch v0.0.0-20190203023257-5858425f7550/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
+github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwoZc+/fpc=
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsouza/go-dockerclient v1.4.4 h1:Sd5nD4wdAgiPxvrbYUzT2ZZNmPk3z+GGnZ+frvw8z04=
@@ -149,12 +242,17 @@ github.com/fsouza/go-dockerclient v1.5.0 h1:7OtayOe5HnoG+KWMHgyyPymwaodnB2IDYuVf
github.com/fsouza/go-dockerclient v1.5.0/go.mod h1:AqZZK/zFO3phxYxlTsAaeAMSdQ9mgHuhy+bjN034Qds=
github.com/fsouza/go-dockerclient v1.6.0 h1:f7j+AX94143JL1H3TiqSMkM4EcLDI0De1qD4GGn3Hig=
github.com/fsouza/go-dockerclient v1.6.0/go.mod h1:YWwtNPuL4XTX1SKJQk86cWPmmqwx+4np9qfPbb+znGc=
+github.com/fsouza/go-dockerclient v1.6.1 h1:qBvbtwBTpOYktncvxjFMHxJHuGG19lb2fvAFqfXeh7w=
+github.com/fsouza/go-dockerclient v1.6.1/go.mod h1:g2pGMa82+SdtAicFSpxGJc1Anx//HHssXyWLwMRxaqg=
+github.com/fsouza/go-dockerclient v1.6.3 h1:VS/I3mxieZVIeaWXd57JKvSjheELafUJYtblGg75RIQ=
+github.com/fsouza/go-dockerclient v1.6.3/go.mod h1:OiSy/IhZIF+zheikZkXK7LVpGzxWchJPJKGWhBqOK4M=
github.com/fullsailor/pkcs7 v0.0.0-20190404230743-d7302db945fa h1:RDBNVkRviHZtvDvId8XSGPu3rmpmSe+wKRcEWNgsfWU=
github.com/fullsailor/pkcs7 v0.0.0-20190404230743-d7302db945fa/go.mod h1:KnogPXtdwXqoenmZCw6S+25EAm2MkxbG0deNDu4cbSA=
github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/ghodss/yaml v0.0.0-20161207003320-04f313413ffd/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
+github.com/go-ini/ini v1.51.1/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
@@ -171,9 +269,12 @@ github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dp
github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
+github.com/godbus/dbus v0.0.0-20180201030542-885f9cc04c9c/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw=
github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e h1:BWhy2j3IXJhjCbC68FptL43tDKIq8FladmaTs3Xs7Z8=
github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4=
+github.com/gofrs/flock v0.7.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
github.com/gogo/protobuf v0.0.0-20170815085658-fcdc5011193f/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
+github.com/gogo/protobuf v0.0.0-20171007142547-342cbe0a0415/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d h1:3PaI8p3seN09VjbTYC/QWlUZdZ1qS1zGjy7LH2Wt07I=
@@ -181,6 +282,7 @@ github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d/go.mod h1:SlYgWuQ5
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
+github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
@@ -189,21 +291,38 @@ github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/google/btree v0.0.0-20160524151835-7d79101e329e/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
+github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1 h1:Xye71clBPdm5HgqGwUkwhbynsUJZhDbS20FvLhQ2izg=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
+github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
+github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI=
+github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI=
github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
+github.com/google/shlex v0.0.0-20181106134648-c34317bd91bf/go.mod h1:RpwtwJQFrIEPstU94h88MWPXP2ektJZ8cZ0YntAmXiE=
+github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/gnostic v0.0.0-20170426233943-68f4ded48ba9/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
+github.com/gophercloud/gophercloud v0.0.0-20190126172459-c818fa66e4c8/go.mod h1:3WdhXV3rUYy9p6AUW8d94kr+HS62Y4VL9mBnFxsD8q4=
github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
+github.com/gorilla/handlers v1.4.2/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ=
github.com/gorilla/mux v0.0.0-20170217192616-94e7d24fd285/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
github.com/gorilla/mux v1.7.3 h1:gnP5JzjVOuiZD07fKKToCAOjS0yOpj/qPETTXCCS6hw=
github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
+github.com/gorilla/mux v1.7.4 h1:VuZ8uybHlWmqV03+zRzdwKL4tUnIp1MAQtp1mIFE1bc=
+github.com/gorilla/mux v1.7.4/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
+github.com/gorilla/schema v1.1.0/go.mod h1:kgLaKoK1FELgZqMAVxx/5cbj0kT+57qxUrAlIO2eleU=
+github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/gotestyourself/gotestyourself v2.2.0+incompatible/go.mod h1:zZKM6oeNM8k+FRljX1mnzVYeS8wiGgQyvST1/GafPbY=
+github.com/gregjones/httpcache v0.0.0-20170728041850-787624de3eb7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
+github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
+github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
+github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
github.com/hashicorp/errwrap v0.0.0-20141028054710-7554cd9344ce/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
@@ -225,13 +344,24 @@ github.com/imdario/mergo v0.3.8 h1:CGgOkSJeqMRmt0D9XLWExdT4m4F1vd3FV3VPt+0VxkQ=
github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
+github.com/insomniacslk/dhcp v0.0.0-20190712084813-dc1a53400564/go.mod h1:CfMdguCK66I5DAUJgGKyNz8aB6vO5dZzkm9Xep6WGvw=
github.com/ishidawataru/sctp v0.0.0-20180918013207-6e2cb1366111 h1:NAAiV9ass6VReWFjuxqrMIq12WKlSULI6Gs3PxQghLA=
github.com/ishidawataru/sctp v0.0.0-20180918013207-6e2cb1366111/go.mod h1:DM4VvS+hD/kDi1U1QsX2fnZowwBhqD0Dk3bRPKF/Oc8=
+github.com/ishidawataru/sctp v0.0.0-20191218070446-00ab2ac2db07 h1:rw3IAne6CDuVFlZbPOkA7bhxlqawFh7RJJ+CejfMaxE=
+github.com/ishidawataru/sctp v0.0.0-20191218070446-00ab2ac2db07/go.mod h1:co9pwDoBCm1kGxawmb4sPq0cSIOOWNPT4KnHotMP1Zg=
+github.com/j-keck/arping v0.0.0-20160618110441-2cf9dc699c56/go.mod h1:ymszkNOg6tORTn+6F6j+Jc8TOr5osrynvN6ivFWZ2GA=
+github.com/jamescun/tuntap v0.0.0-20190712092105-cb1fb277045c/go.mod h1:zzwpsgcYhzzIP5WyF8g9ivCv38cY9uAV9Gu0m3lThhE=
+github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
github.com/json-iterator/go v0.0.0-20180612202835-f2b4162afba3/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
+github.com/json-iterator/go v0.0.0-20180701071628-ab8a2e0c74be/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.7 h1:KfgG9LzI+pYjr4xvmz/5H4FXjokeP+rlHLhv3iH62Fo=
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
+github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
+github.com/juju/errors v0.0.0-20180806074554-22422dad46e1/go.mod h1:W54LbzXuIE0boCoNJfwqpmkKJ1O4TCTZMetAt6jGk7Q=
+github.com/juju/loggo v0.0.0-20190526231331-6e530bcce5d8/go.mod h1:vgyd7OREkbtVEN/8IXZe5Ooef3LQePvuBm9UWj6ZL8U=
+github.com/juju/testing v0.0.0-20190613124551-e81189438503/go.mod h1:63prj8cnj0tU0S9OHjGJn+b1h0ZghCndfnbQolrYTwA=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
@@ -248,10 +378,22 @@ github.com/klauspost/compress v1.9.3 h1:hkFELABwacUEgBfiguNeQydKv3M9pawBq8o24Ypw
github.com/klauspost/compress v1.9.3/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
github.com/klauspost/compress v1.9.4 h1:xhvAeUPQ2drNUhKtrGdTGNvV9nNafHMUkRyLkzxJoB4=
github.com/klauspost/compress v1.9.4/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
+github.com/klauspost/compress v1.9.7 h1:hYW1gP94JUmAhBtJ+LNz5My+gBobDxPR1iVuKug26aA=
+github.com/klauspost/compress v1.9.7/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
+github.com/klauspost/compress v1.9.8 h1:VMAMUUOh+gaxKTMk+zqbjsSjsIcUcL/LF4o63i82QyA=
+github.com/klauspost/compress v1.9.8/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
+github.com/klauspost/compress v1.10.0 h1:92XGj1AcYzA6UrVdd4qIIBrT8OroryvRvdmg/IfmC7Y=
+github.com/klauspost/compress v1.10.0/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
+github.com/klauspost/compress v1.10.2 h1:Znfn6hXZAHaLPNnlqUYRrBSReFHYybslgv4PTiyz6P0=
+github.com/klauspost/compress v1.10.2/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
+github.com/klauspost/compress v1.10.3 h1:OP96hzwJVBIHYU52pVTI6CczrxPvrGfgqF9N5eTO0Q8=
+github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
github.com/klauspost/cpuid v1.2.1 h1:vJi+O/nMdFt0vqm8NZBI6wzALWdA2X+egi0ogNyrC/w=
github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
github.com/klauspost/pgzip v1.2.1 h1:oIPZROsWuPHpOdMVWLuJZXwgjhrW8r1yEX8UqMyeNHM=
github.com/klauspost/pgzip v1.2.1/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
+github.com/klauspost/pgzip v1.2.2 h1:8d4I0LDiieuGngsqlqOih9ker/NS0LX4V0i+EhiFWg0=
+github.com/klauspost/pgzip v1.2.2/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s=
@@ -270,16 +412,25 @@ github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN
github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
github.com/mattn/go-isatty v0.0.4 h1:bnP0vzxcAdeI1zdubAl5PjU6zsERjGZb7raWodagDYs=
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
+github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
+github.com/mattn/go-shellwords v1.0.3/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o=
github.com/mattn/go-shellwords v1.0.5 h1:JhhFTIOslh5ZsPrpa3Wdg8bF0WI3b44EMblmU9wIsXc=
github.com/mattn/go-shellwords v1.0.5/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o=
github.com/mattn/go-shellwords v1.0.6 h1:9Jok5pILi5S1MnDirGVTufYGtksUs/V2BWUP3ZkeUUI=
github.com/mattn/go-shellwords v1.0.6/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o=
+github.com/mattn/go-shellwords v1.0.7 h1:KqhVjVZomx2puPACkj9vrGFqnp42Htvo9SEAWePHKOs=
+github.com/mattn/go-shellwords v1.0.7/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o=
+github.com/mattn/go-shellwords v1.0.9 h1:eaB5JspOwiKKcHdqcjbfe5lA9cNn/4NRRtddXJCimqk=
+github.com/mattn/go-shellwords v1.0.9/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y=
+github.com/mattn/go-shellwords v1.0.10 h1:Y7Xqm8piKOO3v10Thp7Z36h4FYFjt5xB//6XvOrs2Gw=
+github.com/mattn/go-shellwords v1.0.10/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y=
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/mistifyio/go-zfs v2.1.1+incompatible h1:gAMO1HM9xBRONLHHYnu5iFsOJUiJdNZo6oqSENd4eW8=
github.com/mistifyio/go-zfs v2.1.1+incompatible/go.mod h1:8AuVvqP/mXw1px98n46wfvcGfQ4ci2FwoAjKYxuo3Z4=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
+github.com/moby/vpnkit v0.3.1-0.20190720080441-7dd3dcce7d3d/go.mod h1:KyjUrL9cb6ZSNNAUwZfqRjhwwgJ3BJN+kXh0t43WTUQ=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
@@ -287,14 +438,24 @@ github.com/modern-go/reflect2 v0.0.0-20180320133207-05fbef0ca5da/go.mod h1:bx2lN
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
+github.com/morikuni/aec v0.0.0-20170113033406-39771216ff4c h1:nXxl5PrvVm2L/wCy8dQu6DMTwH4oIuGN8GJDAlqDdVE=
github.com/morikuni/aec v0.0.0-20170113033406-39771216ff4c/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
+github.com/mrtazz/checkmake v0.0.0-20191009095831-03dd76b964dd/go.mod h1:YBPKCT1PrhoFU743gPdtJNp+LmM0QlGMWME1J+FJtQI=
+github.com/mrunalp/fileutils v0.0.0-20171103030105-7d4729fb3618/go.mod h1:x8F1gnqOkIEiO4rqoeEEEqQbo7HjGMTvyoq3gej4iT0=
github.com/mtrmac/gpgme v0.0.0-20170102180018-b2432428689c h1:xa+eQWKuJ9MbB9FBL/eoNvDFvveAkz2LQoz8PzX7Q/4=
github.com/mtrmac/gpgme v0.0.0-20170102180018-b2432428689c/go.mod h1:GhAqVMEWnTcW2dxoD/SO3n2enrgWl3y6Dnx4m59GvcA=
+github.com/mtrmac/gpgme v0.1.1 h1:a5ISnvahzTzBH0m/klhehN68N+9+/jLwhpPFtH3oPAQ=
+github.com/mtrmac/gpgme v0.1.1/go.mod h1:GYYHnGSuS7HK3zVS2n3y73y0okK/BeKzwnn5jgiVFNI=
+github.com/mtrmac/gpgme v0.1.2 h1:dNOmvYmsrakgW7LcgiprD0yfRuQQe8/C8F6Z+zogO3s=
+github.com/mtrmac/gpgme v0.1.2/go.mod h1:GYYHnGSuS7HK3zVS2n3y73y0okK/BeKzwnn5jgiVFNI=
github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
+github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
+github.com/olekukonko/tablewriter v0.0.4/go.mod h1:zq6QwlOf5SlnkVbMSr5EoBv3636FWnp+qbPhuoO21uA=
+github.com/onsi/ginkgo v0.0.0-20151202141238-7f8ab55aaf3b/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.6.0 h1:Ix8l273rp3QzYgXSR+c8d1fTG7UPgYkOSELPhiY/YGw=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
@@ -308,7 +469,11 @@ github.com/onsi/ginkgo v1.10.3 h1:OoxbjfXVZyod1fmWYhI7SEyaD8B00ynP3T+D5GiyHOY=
github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.11.0 h1:JAKSXpt1YjtLA7YpPiqO9ss6sNXEsPfSGdwN0UHqzrw=
github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
+github.com/onsi/ginkgo v1.12.0 h1:Iw5WCbBcaAAd0fpRb1c9r5YCylv4XDoCSigm1zLevwU=
+github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg=
+github.com/onsi/gomega v0.0.0-20151007035656-2152b45fa28a/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
+github.com/onsi/gomega v0.0.0-20190113212917-5533ce8a0da3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/onsi/gomega v1.5.0 h1:izbySO9zDPmjJ8rDjLvkA2zJHIo+HkYXHnf7eN7SSyo=
github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME=
@@ -317,6 +482,8 @@ github.com/onsi/gomega v1.7.1 h1:K0jcRCwNQM3vFGh1ppMtDh/+7ApJrjldlX8fA0jDTLQ=
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/onsi/gomega v1.8.1 h1:C5Dqfs/LeauYDX0jJXIe2SWmwCbGzx9yF8C8xy3Lh34=
github.com/onsi/gomega v1.8.1/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA=
+github.com/onsi/gomega v1.9.0 h1:R1uwffexN6Pr340GtYRIdZmAiN4J+iw6WG4wog1DUXg=
+github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA=
github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
github.com/opencontainers/go-digest v1.0.0-rc1 h1:WzifXhOVOEOuFYOJAW6aQqW0TooG2iki3E3Ii+WN7gQ=
github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
@@ -325,6 +492,7 @@ github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zM
github.com/opencontainers/image-spec v1.0.2-0.20190823105129-775207bd45b6 h1:yN8BPXVwMBAm3Cuvh1L5XE8XpvYRMdsVLd82ILprhUU=
github.com/opencontainers/image-spec v1.0.2-0.20190823105129-775207bd45b6/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
github.com/opencontainers/runc v0.0.0-20190115041553-12f6a991201f/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
+github.com/opencontainers/runc v0.0.0-20190425234816-dae70e8efea4/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
github.com/opencontainers/runc v1.0.0-rc8 h1:dDCFes8Hj1r/i5qnypONo5jdOme/8HWZC/aNDyhECt0=
github.com/opencontainers/runc v1.0.0-rc8/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
@@ -342,6 +510,14 @@ github.com/opencontainers/selinux v1.2.2 h1:Kx9J6eDG5/24A6DtUquGSpJQ+m2MUTahn4Ft
github.com/opencontainers/selinux v1.2.2/go.mod h1:+BLncwf63G4dgOzykXAxcmnFlUaOlkDdmw/CqsW6pjs=
github.com/opencontainers/selinux v1.3.0 h1:xsI95WzPZu5exzA6JzkLSfdr/DilzOhCJOqGe5TgR0g=
github.com/opencontainers/selinux v1.3.0/go.mod h1:+BLncwf63G4dgOzykXAxcmnFlUaOlkDdmw/CqsW6pjs=
+github.com/opencontainers/selinux v1.3.1 h1:dn2Rc3wTEvTB6iVqoFrKKeMb0uZ38ZheeyMu2h5C1TI=
+github.com/opencontainers/selinux v1.3.1/go.mod h1:yTcKuYAh6R95iDpefGLQaPaRwJFwyzAJufJyiTt7s0g=
+github.com/opencontainers/selinux v1.3.2 h1:DR4lL9SYVjgcTZKEZIncvDU06fKSc/eygjmNGOA3E1s=
+github.com/opencontainers/selinux v1.3.2/go.mod h1:yTcKuYAh6R95iDpefGLQaPaRwJFwyzAJufJyiTt7s0g=
+github.com/opencontainers/selinux v1.3.3 h1:RX0wAeqtvVSYQcr017X3pFXPkLEtB6V4NjRD7gVQgg4=
+github.com/opencontainers/selinux v1.3.3/go.mod h1:yTcKuYAh6R95iDpefGLQaPaRwJFwyzAJufJyiTt7s0g=
+github.com/opencontainers/selinux v1.4.0 h1:cpiX/2wWIju/6My60T6/z9CxNG7c8xTQyEmA9fChpUo=
+github.com/opencontainers/selinux v1.4.0/go.mod h1:yTcKuYAh6R95iDpefGLQaPaRwJFwyzAJufJyiTt7s0g=
github.com/openshift/api v0.0.0-20200106203948-7ab22a2c8316 h1:enQG2QUGwug4fR1yM6hL0Fjzx6Km/exZY6RbSPwMu3o=
github.com/openshift/api v0.0.0-20200106203948-7ab22a2c8316/go.mod h1:dv+J0b/HWai0QnMVb37/H0v36klkLBi2TNpPeWDxX10=
github.com/openshift/api v3.9.1-0.20190810003144-27fb16909b15+incompatible h1:s55wx8JIG/CKnewev892HifTBrtKzMdvgB3rm4rxC2s=
@@ -350,14 +526,22 @@ github.com/openshift/imagebuilder v1.1.0 h1:oT704SkwMEzmIMU/+Uv1Wmvt+p10q3v2WuYM
github.com/openshift/imagebuilder v1.1.0/go.mod h1:9aJRczxCH0mvT6XQ+5STAQaPWz7OsWcU5/mRkt8IWeo=
github.com/openshift/imagebuilder v1.1.1 h1:KAUR31p8UBJdfVO42azWgb+LeMAed2zaKQ19e0C0X2I=
github.com/openshift/imagebuilder v1.1.1/go.mod h1:9aJRczxCH0mvT6XQ+5STAQaPWz7OsWcU5/mRkt8IWeo=
+github.com/openshift/imagebuilder v1.1.2 h1:vCO8hZQR/4uzo+j0PceBH5aKFcvCDM43UzUGOYQN+Go=
+github.com/openshift/imagebuilder v1.1.2/go.mod h1:9aJRczxCH0mvT6XQ+5STAQaPWz7OsWcU5/mRkt8IWeo=
+github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
github.com/ostreedev/ostree-go v0.0.0-20190702140239-759a8c1ac913 h1:TnbXhKzrTOyuvWrjI8W6pcoI9XPbLHFXCdN2dtUw7Rw=
github.com/ostreedev/ostree-go v0.0.0-20190702140239-759a8c1ac913/go.mod h1:J6OG6YJVEWopen4avK3VNQSnALmmjvniMmni/YFYAwc=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
+github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
+github.com/pkg/errors v0.0.0-20190227000051-27936f6d90f9/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.0 h1:J8lpUdobwIeCI7OiSxHqEwJUKvJwicL5+3v1oe2Yb4k=
github.com/pkg/errors v0.9.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
+github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pkg/profile v1.4.0/go.mod h1:NWz/XGvpEW1FyYQ7fCx4dqYBLlfTcE+A9FLAkNKqjFE=
github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
@@ -366,24 +550,37 @@ github.com/pquerna/ffjson v0.0.0-20181028064349-e517b90714f7/go.mod h1:YARuvh7BU
github.com/pquerna/ffjson v0.0.0-20190813045741-dac163c6c0a9 h1:kyf9snWXHvQc+yxE9imhdI8YAm4oKeZISlaAR+x73zs=
github.com/pquerna/ffjson v0.0.0-20190813045741-dac163c6c0a9/go.mod h1:YARuvh7BUWHNhzDq2OM5tzR2RiCcN2D7sapiKyCel/M=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
+github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
github.com/prometheus/client_golang v1.1.0 h1:BQ53HtBmfOitExawJ6LokA4x8ov/z0SYYb0+HxJfRI8=
github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90 h1:S/YWwWx/RA8rT8tKFRuGUZhuA90OyIBpPCXkcbwU8DE=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
+github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
+github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.6.0 h1:kRhiuYSXR3+uv2IbVbZhUxK5zVD/2pp3Gd2PpvPkpEo=
github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc=
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
+github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.0.3 h1:CTwfnzjQ+8dS6MhHHu4YswVAD99sL2wjPqP+VkURmKE=
github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=
github.com/prometheus/procfs v0.0.5 h1:3+auTFlqw+ZaQYJARz6ArODtkaIwtvBTx3N2NehQlL8=
github.com/prometheus/procfs v0.0.5/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=
+github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
github.com/remyoudompheng/bigfft v0.0.0-20170806203942-52369c62f446/go.mod h1:uYEyJGbgTkfkS4+E/PavXkNJcbFIpEtjt2B0KDQ5+9M=
+github.com/rhatdan/common v0.0.3-0.20200203010855-77d72c3e2feb h1:pABQ1OA6mO8XrdHran0oaTEvSb2aZpM+bI8+NfcjALQ=
+github.com/rhatdan/common v0.0.3-0.20200203010855-77d72c3e2feb/go.mod h1:ss8uGpUsaDE4DPmaVFOjzKrlgf5eUnSAWL+d/PYGaoM=
+github.com/rhatdan/common v0.0.3-0.20200208104512-837f7aa36449 h1:3uEI2WT7ZUWIKbbyKjm7etLgSSMOmdiJ4cqksVnuV9A=
+github.com/rhatdan/common v0.0.3-0.20200208104512-837f7aa36449/go.mod h1:ss8uGpUsaDE4DPmaVFOjzKrlgf5eUnSAWL+d/PYGaoM=
+github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
+github.com/rogpeppe/go-charset v0.0.0-20180617210344-2471d30d28b4/go.mod h1:qgYeAmZ5ZIpBWTGllZSQnw97Dj+woV0toclVaRGI8pc=
+github.com/rootless-containers/rootlesskit v0.7.2/go.mod h1:r9YL5mKRIdnwcYk4G8E5CSc9MDeFtgYmhfE4CSvDGYA=
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
+github.com/safchain/ethtool v0.0.0-20190326074333-42ed695e3de8/go.mod h1:Z0q5wiBQGYcxhMZ6gUqHn6pYNLypFAvaL3UvgZLR0U4=
github.com/saschagrunert/storage v1.12.3-0.20191015073819-a34ddea087da h1:5aEGhStFh+0r/t0kT0utSi5C6MIMHBgMHkeIu1JUvfA=
github.com/saschagrunert/storage v1.12.3-0.20191015073819-a34ddea087da/go.mod h1:imKnA8Ozb99yPWt64WPrtNOR0v0HKQZFH4oLV45N22k=
github.com/saschagrunert/storage v1.12.3-0.20191018073047-1d43d5290f84 h1:iBs6FOO2GpFpdaa3WC4XhqHI6S2LE7RTlgn8LodsXVo=
@@ -410,27 +607,39 @@ github.com/saschagrunert/storage v1.12.3-0.20191204101521-aca03d333c53 h1:CBWb8W
github.com/saschagrunert/storage v1.12.3-0.20191204101521-aca03d333c53/go.mod h1:/Lild6FqQu2HwAVjVC9d5EAls3Mqwoxx67XpnR4UgEY=
github.com/seccomp/containers-golang v0.0.0-20180629143253-cdfdaa7543f4 h1:rOG9oHVIndNR14f3HRyBy9UPQYmIPniWqTU1TDdHhq4=
github.com/seccomp/containers-golang v0.0.0-20180629143253-cdfdaa7543f4/go.mod h1:f/98/SnvAzhAEFQJ3u836FePXvcbE8BS0YGMQNn4mhA=
+github.com/seccomp/containers-golang v0.0.0-20190312124753-8ca8945ccf5f h1:OtU/w6sBKmXYaw2KEODxjcYi3oPSyyslhgGFgIJVGAI=
+github.com/seccomp/containers-golang v0.0.0-20190312124753-8ca8945ccf5f/go.mod h1:f/98/SnvAzhAEFQJ3u836FePXvcbE8BS0YGMQNn4mhA=
github.com/seccomp/libseccomp-golang v0.9.1 h1:NJjM5DNFOs0s3kYE1WUOr6G8V97sdt46rlXTMfXGWBo=
github.com/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvWlF4P2Ca7zGrPiEpWo=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
+github.com/sirupsen/logrus v0.0.0-20190403091019-9b3cdde74fbe/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
+github.com/sirupsen/logrus v1.0.6/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
+github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
+github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
+github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cobra v0.0.5 h1:f0B+LkLX6DtmRH1isoNA9VTtNUK9K8xYd28JNNfOv/s=
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
+github.com/spf13/cobra v0.0.6 h1:breEStsVwemnKh2/s6gMvSdMEkwW0sK8vGStnlVBMCs=
+github.com/spf13/cobra v0.0.6/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
+github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
+github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48=
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
github.com/stretchr/testify v0.0.0-20151208002404-e3a8ff8ce365/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
@@ -438,26 +647,42 @@ github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
+github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
+github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2 h1:b6uOv7YOFK0TYG7HtkIgExQo+2RdLuwRft63jn2HWj8=
github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
github.com/tchap/go-patricia v2.3.0+incompatible h1:GkY4dP3cEfEASBPPkWd+AmjYxhmDkqO9/zg7R0lSQRs=
github.com/tchap/go-patricia v2.3.0+incompatible/go.mod h1:bmLyhP68RS6kStMGxByiQ23RP/odRBOTVjwp2cDyi6I=
+github.com/theckman/go-flock v0.7.1/go.mod h1:kjuth3y9VJ2aNlkNEO99G/8lp9fMIKaGyBmh84IBheM=
+github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
+github.com/u-root/u-root v5.0.0+incompatible/go.mod h1:RYkpo8pTHrNjW08opNd/U6p/RJE7K0D8fXO0d47+3YY=
+github.com/uber/jaeger-client-go v2.22.1+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk=
+github.com/uber/jaeger-lib v0.0.0-20190122222657-d036253de8f5/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U=
+github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
github.com/ulikunitz/xz v0.5.6 h1:jGHAfXawEGZQ3blwU5wnWKQJvAraT7Ftq9EXjnXYgt8=
github.com/ulikunitz/xz v0.5.6/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8=
github.com/urfave/cli v0.0.0-20171014202726-7bc6a0acffa5/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
+github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
+github.com/varlink/go v0.0.0-20190502142041-0f1d566d194b/go.mod h1:YHaw8N660ESgMgLOZfLQqT1htFItynAUxMesFBho52s=
github.com/vbatts/tar-split v0.11.1 h1:0Odu65rhcZ3JZaPHxl7tCI3V/C/Q9Zf82UFravl02dE=
github.com/vbatts/tar-split v0.11.1/go.mod h1:LEuURwDEiWjRjwu46yU3KVGuUdVv/dcnpcEPSzR8z6g=
github.com/vbauerster/mpb v3.4.0+incompatible h1:mfiiYw87ARaeRW6x5gWwYRUawxaW1tLAD8IceomUCNw=
github.com/vbauerster/mpb v3.4.0+incompatible/go.mod h1:zAHG26FUhVKETRu+MWqYXcI70POlC6N8up9p1dID7SU=
github.com/vbauerster/mpb/v4 v4.11.1 h1:ZOYQSVHgmeanXsbyC44aDg76tBGCS/54Rk8VkL8dJGA=
github.com/vbauerster/mpb/v4 v4.11.1/go.mod h1:vMLa1J/ZKC83G2lB/52XpqT+ZZtFG4aZOdKhmpRL1uM=
+github.com/vbauerster/mpb/v4 v4.11.2 h1:ynkUoKzi65DZ1UsQPx7sgi/KN6G9f7br+Us2nKm35AM=
+github.com/vbauerster/mpb/v4 v4.11.2/go.mod h1:jIuIRCltGJUnm6DCyPVkwjlLUk4nHTH+m4eD14CdFF0=
+github.com/vishvananda/netlink v0.0.0-20181108222139-023a6dafdcdf/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk=
github.com/vishvananda/netlink v1.0.0 h1:bqNY2lgheFIu1meHUFSH3d7vG93AFyqg3oGbJCOJgSM=
github.com/vishvananda/netlink v1.0.0/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk=
+github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE=
+github.com/vishvananda/netns v0.0.0-20180720170159-13995c7128cc/go.mod h1:ZjcWmFBXmLKZu9Nxj3WKYEafiSqer2rnvPr0en9UNpI=
github.com/vishvananda/netns v0.0.0-20190625233234-7109fa855b0f h1:nBX3nTcmxEtHSERBJaIo1Qa26VwRaopnZmfDQUXsF4I=
github.com/vishvananda/netns v0.0.0-20190625233234-7109fa855b0f/go.mod h1:ZjcWmFBXmLKZu9Nxj3WKYEafiSqer2rnvPr0en9UNpI=
+github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU=
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c=
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
github.com/xeipuuv/gojsonpointer v0.0.0-20190809123943-df4f5c81cb3b h1:6cLsL+2FW6dRAdl5iMtHgRogVCff0QpRi9653YmdcJA=
@@ -465,18 +690,27 @@ github.com/xeipuuv/gojsonpointer v0.0.0-20190809123943-df4f5c81cb3b/go.mod h1:N2
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0=
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
github.com/xeipuuv/gojsonschema v0.0.0-20180618132009-1d523034197f/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs=
+github.com/xeipuuv/gojsonschema v0.0.0-20190816131739-be0936907f66 h1:F6RPtD6im1kY4bmLByRlOLOZwsPP7mw7cxR1v2CotL0=
github.com/xeipuuv/gojsonschema v0.0.0-20190816131739-be0936907f66/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
github.com/xeipuuv/gojsonschema v1.1.0 h1:ngVtJC9TY/lg0AA/1k48FYhBrhRoFlEmWzsehpNAaZg=
github.com/xeipuuv/gojsonschema v1.1.0/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs=
+github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
+go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
go.etcd.io/bbolt v1.3.3 h1:MUGmc65QhB3pIlaQ5bB4LwqSj6GIonVJXpZiaKNyaKk=
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
go.opencensus.io v0.22.0 h1:C9hSCOW830chIVkdja34wa6Ky+IzWllkUinR+BtRZd4=
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
+go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
+go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
+go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
+golang.org/x/crypto v0.0.0-20181009213950-7c1a557ab941/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
+golang.org/x/crypto v0.0.0-20181025213731-e84da0312774/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4 h1:HuIa8hRrWRSrqYzx1qI49NNxhdi2PrY7gxVSq1JjLDc=
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
@@ -484,6 +718,8 @@ golang.org/x/crypto v0.0.0-20190927123631-a832865fa7ad h1:5E5raQxcv+6CZ11RrBYQe5
golang.org/x/crypto v0.0.0-20190927123631-a832865fa7ad/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191112222119-e1110fd1c708 h1:pXVtWnwHkrWD9ru3sDxY/qFK/bfc0egRovX91EjWjf4=
golang.org/x/crypto v0.0.0-20191112222119-e1110fd1c708/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975 h1:/Tl7pH94bvbAAHBdZJT947M/+gp0+CqQXDtMRC0fseo=
+golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190312203227-4b39c73a6495/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@@ -496,11 +732,17 @@ golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73r
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190206173232-65e2d4e15006/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
+golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190628185345-da137c7871d7 h1:rTIdg5QFRR7XCaK4LCjBiPbx8j4DQRpdYMnGn/bJUEU=
@@ -509,6 +751,8 @@ golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLL
golang.org/x/net v0.0.0-20191004110552-13f9640d40b9 h1:rjwSpXsdiK0dV8/Naq3kAw9ymfAeJIyd0upUIElB+lI=
golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
+golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
+golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 h1:YUO/7uOKsKeq9UokNS62b8FYywz3ker1l1vDZRCRefw=
@@ -520,6 +764,7 @@ golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5h
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -527,14 +772,18 @@ golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894 h1:Cz4ceDQGXuKRnVBDTS23GTn/pU5OE2C0WrNTOYK1Uuc=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190425145619-16072639606e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190514135907-3a4b5fb9f71f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb h1:fgwFCsaw9buMuxNd6+DQfAuSFqbNiQZpcgJQAgJsK6k=
golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190710143415-6ec70d6a5542 h1:6ZQFf1D2YYDDI7eSwW8adlkkavTB9sw5I24FVtEvNUQ=
golang.org/x/sys v0.0.0-20190710143415-6ec70d6a5542/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190712062909-fae7ac547cb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3 h1:4y9KwBHBgBNwDbtu44R5o1fdOCQUEXhbk/P4A9WmJq0=
golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -543,13 +792,18 @@ golang.org/x/sys v0.0.0-20190902133755-9109b7679e13/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3 h1:7TYNF4UdlohbFwpNH04CoPMp1cHUZgO1Ebq5r2hIjfo=
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191113165036-4c7a9d0fe056/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191127021746-63cb32ae39b2 h1:/J2nHFg1MTqaRLFO7M+J78ASNsJoz3r0cvHBPQ77fsE=
golang.org/x/sys v0.0.0-20191127021746-63cb32ae39b2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.1-0.20181227161524-e6919f6577db/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
+golang.org/x/time v0.0.0-20161028155119-f51c12702a4d/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
+golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190921001708-c4c64cad1fd0 h1:xQwXv67TxFo9nC1GJFyab5eq/5B590r6RlnL/G8Sz7w=
golang.org/x/time v0.0.0-20190921001708-c4c64cad1fd0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
@@ -563,26 +817,35 @@ golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
+golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190920225731-5eefd052ad72/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7 h1:9zdDQZ7Thm29KFXgAX/+yaf3eVbP7djjWp/dXAppNCc=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
+golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gonum.org/v1/gonum v0.0.0-20190331200053-3d26580ed485/go.mod h1:2ltnJ7xHfj0zHS40VVPYEAAMTa3ZGguvHGBSJeRWqE0=
gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw=
gonum.org/v1/netlib v0.0.0-20190331212654-76723241ea4e/go.mod h1:kS+toOQn6AQKjmKJ7gzohV1XkqsFehRA2FbsbkopSuQ=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
+google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
+google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20180831171423-11092d34479b h1:lohp5blsw53GBXtLyLNaTXPXS9pJ1tiTw61ZHUoE9Qw=
google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb h1:i1Ppqkc3WQXikh8bXiwHqAN5Rv3/qDCcRk0/Otx73BY=
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
+google.golang.org/genproto v0.0.0-20190620144150-6af8c5fc6601 h1:9VBRTdmgQxbs6HE0sUnMrSWNePppAJU07NYvX5dIB04=
+google.golang.org/genproto v0.0.0-20190620144150-6af8c5fc6601/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
+google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
google.golang.org/grpc v1.22.0 h1:J0UbZOIrCAl+fpTOf8YLs4dJo8L/owV4LYVtAXQoPkw=
google.golang.org/grpc v1.22.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.24.0 h1:vb/1TCsVn3DcJlQ0Gs1yB1pKI6Do2/QNwxdKqmc/b0s=
google.golang.org/grpc v1.24.0/go.mod h1:XDChyiUovWa60DnaeDeZmSW86xtLtjtZbwvSiRnRtcA=
+gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
@@ -591,46 +854,65 @@ gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogR
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
+gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo=
gopkg.in/inf.v0 v0.9.0 h1:3zYtXIO92bvsdS3ggAdA8Gb4Azj0YU+TVY1uGYNFA8o=
gopkg.in/inf.v0 v0.9.0/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
+gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA=
+gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
gopkg.in/square/go-jose.v2 v2.3.1 h1:SK5KegNXmKmqE342YYN2qPHEnUYeoMiXXl1poUlI+o4=
gopkg.in/square/go-jose.v2 v2.3.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
+gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
+gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gotest.tools v0.0.0-20190624233834-05ebafbffc79/go.mod h1:R//lfYlUuTOTfblYI3lGoAAAebUdzjvbmQsuB7Ykd90=
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
+k8s.io/api v0.0.0-20190620084959-7cf5895f2711/go.mod h1:TBhBqb1AWbBQbW3XRusr7n7E4v2+5ZY8r8sAMnyFC5A=
k8s.io/api v0.0.0-20190813020757-36bff7324fb7 h1:4uJOjRn9kWq4AqJRE8+qzmAy+lJd9rh8TY455dNef4U=
k8s.io/api v0.0.0-20190813020757-36bff7324fb7/go.mod h1:3Iy+myeAORNCLgjd/Xu9ebwN7Vh59Bw0vh9jhoX+V58=
k8s.io/api v0.17.0 h1:H9d/lw+VkZKEVIUc8F3wgiQ+FUXTTr21M87jXLU7yqM=
k8s.io/api v0.17.0/go.mod h1:npsyOePkeP0CPwyGfXDHxvypiYMJxBWAMpQxCaJ4ZxI=
+k8s.io/api v0.17.2 h1:NF1UFXcKN7/OOv1uxdRz3qfra8AHsPav5M93hlV9+Dc=
+k8s.io/api v0.17.2/go.mod h1:BS9fjjLc4CMuqfSO8vgbHPKMt5+SF0ET6u/RVDihTo4=
+k8s.io/apimachinery v0.0.0-20190612205821-1799e75a0719/go.mod h1:I4A+glKBHiTgiEjQiCCQfCAIcIMFGt291SmsvcrFzJA=
k8s.io/apimachinery v0.0.0-20190809020650-423f5d784010 h1:pyoq062NftC1y/OcnbSvgolyZDJ8y4fmUPWMkdA6gfU=
k8s.io/apimachinery v0.0.0-20190809020650-423f5d784010/go.mod h1:Waf/xTS2FGRrgXCkO5FP3XxTOWh0qLf2QhL1qFZZ/R8=
k8s.io/apimachinery v0.17.0 h1:xRBnuie9rXcPxUkDizUsGvPf1cnlZCFu210op7J7LJo=
k8s.io/apimachinery v0.17.0/go.mod h1:b9qmWdKlLuU9EBh+06BtLcSf/Mu89rWL33naRxs1uZg=
+k8s.io/apimachinery v0.17.2 h1:hwDQQFbdRlpnnsR64Asdi55GyCaIP/3WQpMmbNBeWr4=
+k8s.io/apimachinery v0.17.2/go.mod h1:b9qmWdKlLuU9EBh+06BtLcSf/Mu89rWL33naRxs1uZg=
+k8s.io/client-go v0.0.0-20170217214107-bcde30fb7eae h1:B3EgNIqpnsZRu7Tms/u6i23BcsxtEKAqXrHt45OqNuw=
k8s.io/client-go v0.0.0-20170217214107-bcde30fb7eae/go.mod h1:7vJpHMYJwNQCWgzmNV+VYUl1zCObLyodBc8nIyt8L5s=
k8s.io/client-go v0.0.0-20181219152756-3dd551c0f083 h1:+Qf/nITucAbm09aIdxvoA+7X0BwaXmQGVoR8k7Ynk9o=
k8s.io/client-go v0.0.0-20181219152756-3dd551c0f083/go.mod h1:7vJpHMYJwNQCWgzmNV+VYUl1zCObLyodBc8nIyt8L5s=
+k8s.io/client-go v0.0.0-20190620085101-78d2af792bab h1:E8Fecph0qbNsAbijJJQryKu4Oi9QTp5cVpjTE+nqg6g=
+k8s.io/client-go v0.0.0-20190620085101-78d2af792bab/go.mod h1:E95RaSlHr79aHaX0aGSwcPNfygDiPKOVXdmivCIZT0k=
k8s.io/code-generator v0.17.0/go.mod h1:DVmfPQgxQENqDIzVR2ddLXMH34qeszkKSdH/N+s+38s=
k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
k8s.io/gengo v0.0.0-20190822140433-26a664648505/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
+k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
k8s.io/klog v0.3.1 h1:RVgyDHY/kFKtLqh67NvEWIgkMneNoIrdkN0CxDSQc68=
k8s.io/klog v0.3.1/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8=
k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I=
+k8s.io/kube-openapi v0.0.0-20190228160746-b3a7cee44a30/go.mod h1:BXM9ceUBTj2QnfH2MK1odQs778ajze1RxcmP6S8RVVc=
k8s.io/kube-openapi v0.0.0-20190709113604-33be087ad058/go.mod h1:nfDlWeOsu3pUf4yWGL+ERqohP4YsZcBJXWMK+gkzOA4=
k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a/go.mod h1:1TqjTSzOxsLGIKfj0lK8EeCP7K1iUG65v09OM0/WG5E=
k8s.io/kubernetes v1.13.0/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk=
+k8s.io/utils v0.0.0-20190221042446-c2654d5206da/go.mod h1:8k8uAuAQ0rXslZKaEWd0c3oVhZz7sSzSiPnVZayjIX0=
+k8s.io/utils v0.0.0-20190607212802-c55fbcfc754a/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew=
modernc.org/cc v1.0.0/go.mod h1:1Sk4//wdnYJiUIxnW8ddKpaOJCF37yAdqYnkxUpaYxw=
modernc.org/golex v1.0.0/go.mod h1:b/QX9oBD/LhixY6NDh+IdGv17hgB+51fET1i2kPSmvk=
modernc.org/mathutil v1.0.0/go.mod h1:wU0vUrJsVWBZ4P6e7xtFJEhFSNsfRLJ8H458uRjg03k=
diff --git a/vendor/github.com/containers/buildah/image.go b/vendor/github.com/containers/buildah/image.go
index d333442b8..94e97d870 100644
--- a/vendor/github.com/containers/buildah/image.go
+++ b/vendor/github.com/containers/buildah/image.go
@@ -627,7 +627,7 @@ func (i *containerImageSource) GetBlob(ctx context.Context, blob types.BlobInfo,
logrus.Debugf("error checking for layer %q in %q: %v", blob.Digest.String(), path, err)
}
}
- if err != nil {
+ if err != nil || layerFile == nil {
logrus.Debugf("error reading layer %q: %v", blob.Digest.String(), err)
return nil, -1, errors.Wrapf(err, "error opening file %q to buffer layer blob", filepath.Join(i.path, blob.Digest.String()))
}
diff --git a/vendor/github.com/containers/buildah/imagebuildah/build.go b/vendor/github.com/containers/buildah/imagebuildah/build.go
index 484eb4efd..e113871c7 100644
--- a/vendor/github.com/containers/buildah/imagebuildah/build.go
+++ b/vendor/github.com/containers/buildah/imagebuildah/build.go
@@ -11,13 +11,14 @@ import (
"os/exec"
"path/filepath"
"strings"
+ "time"
"github.com/containers/buildah"
+ "github.com/containers/common/pkg/config"
"github.com/containers/image/v5/docker/reference"
"github.com/containers/image/v5/types"
"github.com/containers/storage"
"github.com/containers/storage/pkg/archive"
- "github.com/opencontainers/runc/libcontainer/configs"
specs "github.com/opencontainers/runtime-spec/specs-go"
"github.com/openshift/imagebuilder"
"github.com/pkg/errors"
@@ -66,7 +67,7 @@ type BuildOptions struct {
// RuntimeArgs adds global arguments for the runtime.
RuntimeArgs []string
// TransientMounts is a list of mounts that won't be kept in the image.
- TransientMounts []Mount
+ TransientMounts []string
// Compression specifies the type of compression which is applied to
// layer blobs. The default is to not use compression, but
// archive.Gzip is recommended.
@@ -156,10 +157,21 @@ type BuildOptions struct {
ForceRmIntermediateCtrs bool
// BlobDirectory is a directory which we'll use for caching layer blobs.
BlobDirectory string
- // Target the targeted FROM in the Dockerfile to build
+ // Target the targeted FROM in the Dockerfile to build.
Target string
- // Devices are the additional devices to add to the containers
- Devices []configs.Device
+ // Devices are the additional devices to add to the containers.
+ Devices []string
+ // SignBy is the fingerprint of a GPG key to use for signing images.
+ SignBy string
+ // Architecture specifies the target architecture of the image to be built.
+ Architecture string
+ // OS is the specifies the operating system of the image to be built.
+ OS string
+ // MaxPullPushRetries is the maximum number of attempts we'll make to pull or push any one
+ // image from or to an external registry if the first attempt fails.
+ MaxPullPushRetries int
+ // PullPushRetryDelay is how long to wait before retrying a pull or push attempt.
+ PullPushRetryDelay time.Duration
}
// BuildDockerfiles parses a set of one or more Dockerfiles (which may be
@@ -250,6 +262,11 @@ func BuildDockerfiles(ctx context.Context, store storage.Store, options BuildOpt
return "", nil, errors.Wrapf(err, "error creating build executor")
}
b := imagebuilder.NewBuilder(options.Args)
+ defaultContainerConfig, err := config.Default()
+ if err != nil {
+ return "", nil, errors.Wrapf(err, "failed to get container config")
+ }
+ b.Env = append(defaultContainerConfig.GetDefaultEnv(), b.Env...)
stages, err := imagebuilder.NewStages(mainNode, b)
if err != nil {
return "", nil, errors.Wrap(err, "error reading multiple stages")
diff --git a/vendor/github.com/containers/buildah/imagebuildah/executor.go b/vendor/github.com/containers/buildah/imagebuildah/executor.go
index 35fc3d63d..846900656 100644
--- a/vendor/github.com/containers/buildah/imagebuildah/executor.go
+++ b/vendor/github.com/containers/buildah/imagebuildah/executor.go
@@ -9,9 +9,12 @@ import (
"sort"
"strconv"
"strings"
+ "time"
"github.com/containers/buildah"
+ "github.com/containers/buildah/pkg/parse"
"github.com/containers/buildah/util"
+ "github.com/containers/common/pkg/config"
"github.com/containers/image/v5/docker/reference"
is "github.com/containers/image/v5/storage"
"github.com/containers/image/v5/transports"
@@ -91,17 +94,46 @@ type Executor struct {
excludes []string
unusedArgs map[string]struct{}
buildArgs map[string]string
- addCapabilities []string
- dropCapabilities []string
+ capabilities []string
devices []configs.Device
+ signBy string
+ architecture string
+ os string
+ maxPullPushRetries int
+ retryPullPushDelay time.Duration
}
// NewExecutor creates a new instance of the imagebuilder.Executor interface.
func NewExecutor(store storage.Store, options BuildOptions, mainNode *parser.Node) (*Executor, error) {
+ defaultContainerConfig, err := config.Default()
+ if err != nil {
+ return nil, errors.Wrapf(err, "failed to get container config")
+ }
+
excludes, err := imagebuilder.ParseDockerignore(options.ContextDirectory)
if err != nil {
return nil, err
}
+ capabilities := defaultContainerConfig.Capabilities("", options.AddCapabilities, options.DropCapabilities)
+
+ devices := []configs.Device{}
+ for _, device := range append(defaultContainerConfig.Containers.Devices, options.Devices...) {
+ dev, err := parse.DeviceFromPath(device)
+ if err != nil {
+ return nil, err
+ }
+ devices = append(dev, devices...)
+ }
+
+ transientMounts := []Mount{}
+ for _, volume := range append(defaultContainerConfig.Containers.Volumes, options.TransientMounts...) {
+ mount, err := parse.Volume(volume)
+ if err != nil {
+ return nil, err
+ }
+
+ transientMounts = append([]Mount{Mount(mount)}, transientMounts...)
+ }
exec := Executor{
store: store,
@@ -113,7 +145,7 @@ func NewExecutor(store storage.Store, options BuildOptions, mainNode *parser.Nod
quiet: options.Quiet,
runtime: options.Runtime,
runtimeArgs: options.RuntimeArgs,
- transientMounts: options.TransientMounts,
+ transientMounts: transientMounts,
compression: options.Compression,
output: options.Output,
outputFormat: options.OutputFormat,
@@ -147,10 +179,14 @@ func NewExecutor(store storage.Store, options BuildOptions, mainNode *parser.Nod
rootfsMap: make(map[string]bool),
blobDirectory: options.BlobDirectory,
unusedArgs: make(map[string]struct{}),
- buildArgs: options.Args,
- addCapabilities: options.AddCapabilities,
- dropCapabilities: options.DropCapabilities,
- devices: options.Devices,
+ buildArgs: copyStringStringMap(options.Args),
+ capabilities: capabilities,
+ devices: devices,
+ signBy: options.SignBy,
+ architecture: options.Architecture,
+ os: options.OS,
+ maxPullPushRetries: options.MaxPullPushRetries,
+ retryPullPushDelay: options.PullPushRetryDelay,
}
if exec.err == nil {
exec.err = os.Stderr
@@ -527,7 +563,7 @@ func (b *Executor) Build(ctx context.Context, stages imagebuilder.Stages) (image
if err := cleanup(); err != nil {
return "", nil, err
}
-
+ logrus.Debugf("printing final image id %q", imageID)
if b.iidfile != "" {
if err = ioutil.WriteFile(b.iidfile, []byte(imageID), 0644); err != nil {
return imageID, ref, errors.Wrapf(err, "failed to write image ID to file %q", b.iidfile)
@@ -537,7 +573,6 @@ func (b *Executor) Build(ctx context.Context, stages imagebuilder.Stages) (image
return imageID, ref, errors.Wrapf(err, "failed to write image ID to stdout")
}
}
-
return imageID, ref, nil
}
diff --git a/vendor/github.com/containers/buildah/imagebuildah/stage_executor.go b/vendor/github.com/containers/buildah/imagebuildah/stage_executor.go
index b54caf3ef..8e49395a4 100644
--- a/vendor/github.com/containers/buildah/imagebuildah/stage_executor.go
+++ b/vendor/github.com/containers/buildah/imagebuildah/stage_executor.go
@@ -12,6 +12,7 @@ import (
"github.com/containers/buildah"
buildahdocker "github.com/containers/buildah/docker"
+ "github.com/containers/buildah/pkg/chrootuser"
"github.com/containers/buildah/util"
cp "github.com/containers/image/v5/copy"
"github.com/containers/image/v5/docker/reference"
@@ -237,7 +238,13 @@ func (s *StageExecutor) volumeCacheRestore() error {
if err := os.Chmod(archivedPath, st.Mode()); err != nil {
return errors.Wrapf(err, "error restoring permissions on %q", archivedPath)
}
- if err := os.Chown(archivedPath, 0, 0); err != nil {
+ uid := 0
+ gid := 0
+ if st.Sys() != nil {
+ uid = util.UID(st)
+ gid = util.GID(st)
+ }
+ if err := os.Chown(archivedPath, uid, gid); err != nil {
return errors.Wrapf(err, "error setting ownership on %q", archivedPath)
}
if err := os.Chtimes(archivedPath, st.ModTime(), st.ModTime()); err != nil {
@@ -253,7 +260,7 @@ func (s *StageExecutor) volumeCacheRestore() error {
// don't care about the details of where in the filesystem the content actually
// goes, because we're not actually going to add it here, so this is less
// involved than Copy().
-func (s *StageExecutor) digestSpecifiedContent(node *parser.Node, argValues []string) (string, error) {
+func (s *StageExecutor) digestSpecifiedContent(node *parser.Node, argValues []string, envValues []string) (string, error) {
// No instruction: done.
if node == nil {
return "", nil
@@ -298,10 +305,11 @@ func (s *StageExecutor) digestSpecifiedContent(node *parser.Node, argValues []st
}
}
+ varValues := append(argValues, envValues...)
for _, src := range srcs {
// If src has an argument within it, resolve it to its
// value. Otherwise just return the value found.
- name, err := imagebuilder.ProcessWord(src, argValues)
+ name, err := imagebuilder.ProcessWord(src, varValues)
if err != nil {
return "", errors.Wrapf(err, "unable to resolve source %q", src)
}
@@ -315,8 +323,12 @@ func (s *StageExecutor) digestSpecifiedContent(node *parser.Node, argValues []st
} else {
// Source is not a URL, so it's a location relative to
// the all-content-comes-from-below-this-directory
- // directory.
+ // directory. Also raise an error if the src escapes
+ // the context directory.
contextSrc, err := securejoin.SecureJoin(contextDir, src)
+ if err == nil && strings.HasPrefix(src, "../") {
+ err = errors.New("escaping context directory error")
+ }
if err != nil {
return "", errors.Wrapf(err, "forbidden path for %q, it is outside of the build context %q", src, contextDir)
}
@@ -345,7 +357,7 @@ func (s *StageExecutor) digestSpecifiedContent(node *parser.Node, argValues []st
// If destination.Value has an argument within it, resolve it to its
// value. Otherwise just return the value found.
- destValue, destErr := imagebuilder.ProcessWord(destination.Value, argValues)
+ destValue, destErr := imagebuilder.ProcessWord(destination.Value, varValues)
if destErr != nil {
return "", errors.Wrapf(destErr, "unable to resolve destination %q", destination.Value)
}
@@ -434,8 +446,12 @@ func (s *StageExecutor) Copy(excludes []string, copies ...imagebuilder.Copy) err
// Treat the source, which is not a URL, as a
// location relative to the
// all-content-comes-from-below-this-directory
- // directory.
+ // directory. Also raise an error if the src
+ // escapes the context directory.
srcSecure, err := securejoin.SecureJoin(contextDir, src)
+ if err == nil && strings.HasPrefix(src, "../") {
+ err = errors.New("escaping context directory error")
+ }
if err != nil {
return errors.Wrapf(err, "forbidden path for %q, it is outside of the build context %q", src, contextDir)
}
@@ -452,6 +468,11 @@ func (s *StageExecutor) Copy(excludes []string, copies ...imagebuilder.Copy) err
Excludes: copyExcludes,
IDMappingOptions: idMappingOptions,
}
+ // If we've a tar file, it will create a directory using the name of the tar
+ // file if we don't blank it out.
+ if strings.HasSuffix(srcName, ".tar") || strings.HasSuffix(srcName, ".gz") {
+ srcName = ""
+ }
if err := s.builder.Add(filepath.Join(copy.Dest, srcName), copy.Download, options, srcSecure); err != nil {
return err
}
@@ -605,9 +626,10 @@ func (s *StageExecutor) prepare(ctx context.Context, stage imagebuilder.Stage, f
CommonBuildOpts: s.executor.commonBuildOptions,
DefaultMountsFilePath: s.executor.defaultMountsFilePath,
Format: s.executor.outputFormat,
- AddCapabilities: s.executor.addCapabilities,
- DropCapabilities: s.executor.dropCapabilities,
+ Capabilities: s.executor.capabilities,
Devices: s.executor.devices,
+ MaxPullRetries: s.executor.maxPullPushRetries,
+ PullRetryDelay: s.executor.retryPullPushDelay,
}
// Check and see if the image is a pseudonym for the end result of a
@@ -771,8 +793,12 @@ func (s *StageExecutor) Execute(ctx context.Context, stage imagebuilder.Stage, b
}
}
logImageID := func(imgID string) {
+ if len(imgID) > 11 {
+ imgID = imgID[0:11]
+ }
if s.executor.iidfile == "" {
- fmt.Fprintf(s.executor.out, "%s\n", imgID)
+
+ fmt.Fprintf(s.executor.out, "--> %s\n", imgID)
}
}
@@ -869,7 +895,7 @@ func (s *StageExecutor) Execute(ctx context.Context, stage imagebuilder.Stage, b
return "", nil, errors.Wrapf(err, "error building at STEP \"%s\"", step.Message)
}
// In case we added content, retrieve its digest.
- addedContentDigest, err := s.digestSpecifiedContent(node, ib.Arguments())
+ addedContentDigest, err := s.digestSpecifiedContent(node, ib.Arguments(), ib.Config().Env)
if err != nil {
return "", nil, err
}
@@ -918,7 +944,7 @@ func (s *StageExecutor) Execute(ctx context.Context, stage imagebuilder.Stage, b
// cached images so far, look for one that matches what we
// expect to produce for this instruction.
if checkForLayers && !(s.executor.squash && lastInstruction && lastStage) {
- addedContentDigest, err := s.digestSpecifiedContent(node, ib.Arguments())
+ addedContentDigest, err := s.digestSpecifiedContent(node, ib.Arguments(), ib.Config().Env)
if err != nil {
return "", nil, err
}
@@ -976,7 +1002,7 @@ func (s *StageExecutor) Execute(ctx context.Context, stage imagebuilder.Stage, b
return "", nil, errors.Wrapf(err, "error building at STEP \"%s\"", step.Message)
}
// In case we added content, retrieve its digest.
- addedContentDigest, err := s.digestSpecifiedContent(node, ib.Arguments())
+ addedContentDigest, err := s.digestSpecifiedContent(node, ib.Arguments(), ib.Config().Env)
if err != nil {
return "", nil, err
}
@@ -1013,7 +1039,6 @@ func (s *StageExecutor) Execute(ctx context.Context, stage imagebuilder.Stage, b
}
}
}
-
return imgID, ref, nil
}
@@ -1132,6 +1157,8 @@ func (s *StageExecutor) commit(ctx context.Context, ib *imagebuilder.Builder, cr
}
s.builder.SetHostname(config.Hostname)
s.builder.SetDomainname(config.Domainname)
+ s.builder.SetArchitecture(s.executor.architecture)
+ s.builder.SetOS(s.executor.os)
s.builder.SetUser(config.User)
s.builder.ClearPorts()
for p := range config.ExposedPorts {
@@ -1204,6 +1231,9 @@ func (s *StageExecutor) commit(ctx context.Context, ib *imagebuilder.Builder, cr
Squash: s.executor.squash,
EmptyLayer: emptyLayer,
BlobDirectory: s.executor.blobDirectory,
+ SignBy: s.executor.signBy,
+ MaxRetries: s.executor.maxPullPushRetries,
+ RetryDelay: s.executor.retryPullPushDelay,
}
imgID, _, manifestDigest, err := s.builder.Commit(ctx, imageRef, options)
if err != nil {
@@ -1225,9 +1255,22 @@ func (s *StageExecutor) EnsureContainerPath(path string) error {
if err != nil {
return errors.Wrapf(err, "error ensuring container path %q", path)
}
- _, err = os.Lstat(targetPath)
+
+ _, err = os.Stat(targetPath)
if err != nil && os.IsNotExist(err) {
err = os.MkdirAll(targetPath, 0755)
+ if err != nil {
+ return errors.Wrapf(err, "error creating directory path %q", targetPath)
+ }
+ // get the uid and gid so that we can set the correct permissions on the
+ // working directory
+ uid, gid, _, err := chrootuser.GetUser(s.mountPoint, s.builder.User())
+ if err != nil {
+ return errors.Wrapf(err, "error getting uid and gid for user %q", s.builder.User())
+ }
+ if err = os.Chown(targetPath, int(uid), int(gid)); err != nil {
+ return errors.Wrapf(err, "error setting ownership on %q", targetPath)
+ }
}
if err != nil {
return errors.Wrapf(err, "error ensuring container path %q", path)
diff --git a/vendor/github.com/containers/buildah/imagebuildah/util.go b/vendor/github.com/containers/buildah/imagebuildah/util.go
index 520b92e3f..29ea60970 100644
--- a/vendor/github.com/containers/buildah/imagebuildah/util.go
+++ b/vendor/github.com/containers/buildah/imagebuildah/util.go
@@ -165,3 +165,11 @@ func convertMounts(mounts []Mount) []specs.Mount {
}
return specmounts
}
+
+func copyStringStringMap(m map[string]string) map[string]string {
+ n := map[string]string{}
+ for k, v := range m {
+ n[k] = v
+ }
+ return n
+}
diff --git a/vendor/github.com/containers/buildah/info.go b/vendor/github.com/containers/buildah/info.go
index 1e6d6b746..a40af08ed 100644
--- a/vendor/github.com/containers/buildah/info.go
+++ b/vendor/github.com/containers/buildah/info.go
@@ -12,7 +12,6 @@ import (
"time"
"github.com/containers/buildah/util"
- "github.com/containers/common/pkg/cgroups"
"github.com/containers/common/pkg/unshare"
"github.com/containers/storage"
"github.com/containers/storage/pkg/system"
@@ -48,7 +47,7 @@ func hostInfo() map[string]interface{} {
info["cpus"] = runtime.NumCPU()
info["rootless"] = unshare.IsRootless()
- unified, err := cgroups.IsCgroup2UnifiedMode()
+ unified, err := util.IsCgroup2UnifiedMode()
if err != nil {
logrus.Error(err, "err reading cgroups mode")
}
diff --git a/vendor/github.com/containers/buildah/install.md b/vendor/github.com/containers/buildah/install.md
index 91522f64f..b5e1abda0 100644
--- a/vendor/github.com/containers/buildah/install.md
+++ b/vendor/github.com/containers/buildah/install.md
@@ -4,12 +4,87 @@
## Installing packaged versions of buildah
+#### [Amazon Linux 2](https://aws.amazon.com/amazon-linux-2/)
+
+The [Kubic project](https://build.opensuse.org/project/show/devel:kubic:libcontainers:stable)
+provides updated packages for CentOS 7 which can be used unmodified on Amazon Linux 2.
+
+```bash
+cd /etc/yum.repos.d/
+sudo wget https://download.opensuse.org/repositories/devel:kubic:libcontainers:stable/CentOS_7/devel:kubic:libcontainers:stable.repo
+sudo yum -y install buildah
+```
+
### [Arch Linux](https://www.archlinux.org)
```bash
sudo pacman -S buildah
```
+#### [CentOS](https://www.centos.org)
+
+Buildah is available in the default Extras repos for CentOS 7 and in
+the AppStream repo for CentOS 8 and Stream, however the available version often
+lags the upstream release.
+
+```bash
+sudo yum -y install buildah
+```
+
+The [Kubic project](https://build.opensuse.org/project/show/devel:kubic:libcontainers:stable)
+provides updated packages for CentOS 7, 8 and Stream.
+
+```bash
+# CentOS 7
+cd /etc/yum.repos.d/
+sudo wget https://download.opensuse.org/repositories/devel:kubic:libcontainers:stable/CentOS_7/devel:kubic:libcontainers:stable.repo
+sudo yum -y install buildah
+
+# CentOS 8
+sudo dnf -y module disable container-tools
+sudo dnf -y install 'dnf-command(copr)'
+sudo dnf -y copr enable rhcontainerbot/container-selinux
+cd /etc/yum.repos.d
+sudo wget https://download.opensuse.org/repositories/devel:kubic:libcontainers:stable/CentOS_8/devel:kubic:libcontainers:stable.repo
+sudo dnf -y install buildah
+
+# CentOS Stream
+sudo dnf -y module disable container-tools
+sudo dnf -y install 'dnf-command(copr)'
+sudo dnf -y copr enable rhcontainerbot/container-selinux
+cd /etc/yum.repos.d
+sudo wget https://download.opensuse.org/repositories/devel:kubic:libcontainers:stable/CentOS_8_Stream/devel:kubic:libcontainers:stable.repo
+sudo dnf -y install buildah
+```
+
+
+#### [Debian](https://debian.org)
+
+The buildah package is [being worked on](https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=928083)
+for inclusion in the default Debian repos.
+
+Alternatively, the [Kubic project](https://build.opensuse.org/project/show/devel:kubic:libcontainers:stable)
+provides packages for Debian 10, testing and unstable.
+
+```bash
+# Debian Unstable/Sid
+echo 'deb http://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/Debian_Unstable/ /' > /etc/apt/sources.list.d/devel:kubic:libcontainers:stable.list
+wget -nv https://download.opensuse.org/repositories/devel:kubic:libcontainers:stable/Debian_Unstable/Release.key -O Release.key
+
+# Debian Testing
+echo 'deb http://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/Debian_Testing/ /' > /etc/apt/sources.list.d/devel:kubic:libcontainers:stable.list
+wget -nv https://download.opensuse.org/repositories/devel:kubic:libcontainers:stable/Debian_Testing/Release.key -O Release.key
+
+# Debian 10
+echo 'deb http://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/Debian_10/ /' > /etc/apt/sources.list.d/devel:kubic:libcontainers:stable.list
+wget -nv https://download.opensuse.org/repositories/devel:kubic:libcontainers:stable/Debian_10/Release.key -O Release.key
+
+sudo apt-key add - < Release.key
+sudo apt-get update -qq
+sudo apt-get -qq -y install buildah
+```
+
+
### [Fedora](https://www.fedoraproject.org), [CentOS](https://www.centos.org)
```bash
@@ -26,7 +101,7 @@ Not Available. Must be installed via package layering.
rpm-ostree install buildah
-Note: `[podman](https://podman.io) build` is available by default.
+Note: [`podman`](https://podman.io) build is available by default.
### [Gentoo](https://www.gentoo.org)
@@ -53,6 +128,19 @@ sudo subscription-manager repos --enable=rhel-7-server-extras-rpms
sudo yum -y install buildah
```
+#### [Raspbian](https://raspbian.org)
+
+The Kubic project provides packages for Raspbian 10.
+
+```bash
+# Raspbian 10
+echo 'deb http://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/Raspbian_10/ /' > /etc/apt/sources.list.d/devel:kubic:libcontainers:stable.list
+wget -nv https://download.opensuse.org/repositories/devel:kubic:libcontainers:stable/Raspbian_10/Release.key -O Release.key
+sudo apt-key add - < Release.key
+sudo apt-get update -qq
+sudo apt-get -qq -y install buildah
+```
+
### [RHEL8 Beta](https://www.redhat.com/en/blog/powering-its-future-while-preserving-present-introducing-red-hat-enterprise-linux-8-beta?intcmp=701f2000001Cz6OAAS)
```bash
@@ -62,10 +150,13 @@ sudo yum module install -y buildah
### [Ubuntu](https://www.ubuntu.com)
+The Kubic project provides packages for Ubuntu 18.04, 19.04 and 19.10 (it should also work with direct derivatives like Pop!\_OS).
+
```bash
-sudo apt-get update -qq
-sudo apt-get install -qq -y software-properties-common
-sudo add-apt-repository -y ppa:projectatomic/ppa
+. /etc/os-release
+sudo sh -c "echo 'deb http://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/x${ID^}_${VERSION_ID}/ /' > /etc/apt/sources.list.d/devel:kubic:libcontainers:stable.list"
+wget -nv https://download.opensuse.org/repositories/devel:kubic:libcontainers:stable/x${ID^}_${VERSION_ID}/Release.key -O Release.key
+sudo apt-key add - < Release.key
sudo apt-get update -qq
sudo apt-get -qq -y install buildah
```
@@ -107,9 +198,9 @@ named `containernetworking-cni`). If not, they will need to be installed,
for example using:
```
git clone https://github.com/containernetworking/plugins
- ( cd ./plugins; ./build.sh )
- mkdir -p /opt/cni/bin
- install -v ./plugins/bin/* /opt/cni/bin
+ ( cd ./plugins; ./build_linux.sh )
+ sudo mkdir -p /opt/cni/bin
+ sudo install -v ./plugins/bin/* /opt/cni/bin
```
The CNI library needs to be configured so that it will know which plugins to
@@ -233,13 +324,13 @@ The build steps for Buildah on SUSE / openSUSE are the same as for Fedora, above
In Ubuntu zesty and xenial, you can use these commands:
```
- apt-get -y install software-properties-common
- add-apt-repository -y ppa:alexlarsson/flatpak
- add-apt-repository -y ppa:gophers/archive
- apt-add-repository -y ppa:projectatomic/ppa
- apt-get -y -qq update
- apt-get -y install bats btrfs-tools git libapparmor-dev libdevmapper-dev libglib2.0-dev libgpgme11-dev libseccomp-dev libselinux1-dev skopeo-containers go-md2man
- apt-get -y install golang-1.12
+ sudo apt-get -y install software-properties-common
+ sudo add-apt-repository -y ppa:alexlarsson/flatpak
+ sudo add-apt-repository -y ppa:gophers/archive
+ sudo apt-add-repository -y ppa:projectatomic/ppa
+ sudo apt-get -y -qq update
+ sudo apt-get -y install bats btrfs-tools git libapparmor-dev libdevmapper-dev libglib2.0-dev libgpgme11-dev libseccomp-dev libselinux1-dev skopeo-containers go-md2man
+ sudo apt-get -y install golang-1.12
```
Then to install Buildah on Ubuntu follow the steps in this example:
@@ -249,7 +340,7 @@ Then to install Buildah on Ubuntu follow the steps in this example:
export GOPATH=`pwd`
git clone https://github.com/containers/buildah ./src/github.com/containers/buildah
cd ./src/github.com/containers/buildah
- PATH=/usr/lib/go-1.10/bin:$PATH make runc all SECURITYTAGS="apparmor seccomp"
+ PATH=/usr/lib/go-1.12/bin:$PATH make runc all SECURITYTAGS="apparmor seccomp"
sudo make install install.runc
buildah --help
```
@@ -260,11 +351,11 @@ To install the required dependencies, you can use those commands, tested under D
```
gpg --recv-keys 0x018BA5AD9DF57A4448F0E6CF8BECF1637AD8C79D
-gpg --export 0x018BA5AD9DF57A4448F0E6CF8BECF1637AD8C79D >> /usr/share/keyrings/projectatomic-ppa.gpg
-echo 'deb [signed-by=/usr/share/keyrings/projectatomic-ppa.gpg] http://ppa.launchpad.net/projectatomic/ppa/ubuntu zesty main' > /etc/apt/sources.list.d/projectatomic-ppa.list
-apt update
-apt -y install -t stretch-backports golang
-apt -y install bats btrfs-tools git libapparmor-dev libdevmapper-dev libglib2.0-dev libgpgme11-dev libseccomp-dev libselinux1-dev skopeo-containers go-md2man
+sudo gpg --export 0x018BA5AD9DF57A4448F0E6CF8BECF1637AD8C79D >> /usr/share/keyrings/projectatomic-ppa.gpg
+sudo echo 'deb [signed-by=/usr/share/keyrings/projectatomic-ppa.gpg] http://ppa.launchpad.net/projectatomic/ppa/ubuntu zesty main' > /etc/apt/sources.list.d/projectatomic-ppa.list
+sudo apt update
+sudo apt -y install -t stretch-backports golang
+sudo apt -y install bats btrfs-tools git libapparmor-dev libdevmapper-dev libglib2.0-dev libgpgme11-dev libseccomp-dev libselinux1-dev skopeo-containers go-md2man
```
The build steps on Debian are otherwise the same as Ubuntu, above.
diff --git a/vendor/github.com/containers/buildah/manifests/copy.go b/vendor/github.com/containers/buildah/manifests/copy.go
new file mode 100644
index 000000000..7e651a46c
--- /dev/null
+++ b/vendor/github.com/containers/buildah/manifests/copy.go
@@ -0,0 +1,15 @@
+package manifests
+
+import (
+ "github.com/containers/image/v5/signature"
+)
+
+var (
+ // storageAllowedPolicyScopes overrides the policy for local storage
+ // to ensure that we can read images from it.
+ storageAllowedPolicyScopes = signature.PolicyTransportScopes{
+ "": []signature.PolicyRequirement{
+ signature.NewPRInsecureAcceptAnything(),
+ },
+ }
+)
diff --git a/vendor/github.com/containers/buildah/manifests/manifests.go b/vendor/github.com/containers/buildah/manifests/manifests.go
new file mode 100644
index 000000000..0fe7e477b
--- /dev/null
+++ b/vendor/github.com/containers/buildah/manifests/manifests.go
@@ -0,0 +1,397 @@
+package manifests
+
+import (
+ "context"
+ "encoding/json"
+ stderrors "errors"
+ "io"
+
+ "github.com/containers/buildah/pkg/manifests"
+ "github.com/containers/buildah/pkg/supplemented"
+ cp "github.com/containers/image/v5/copy"
+ "github.com/containers/image/v5/docker/reference"
+ "github.com/containers/image/v5/image"
+ "github.com/containers/image/v5/manifest"
+ "github.com/containers/image/v5/signature"
+ is "github.com/containers/image/v5/storage"
+ "github.com/containers/image/v5/transports"
+ "github.com/containers/image/v5/transports/alltransports"
+ "github.com/containers/image/v5/types"
+ "github.com/containers/storage"
+ digest "github.com/opencontainers/go-digest"
+ v1 "github.com/opencontainers/image-spec/specs-go/v1"
+ "github.com/pkg/errors"
+ "github.com/sirupsen/logrus"
+)
+
+const instancesData = "instances.json"
+
+// ErrListImageUnknown is returned when we attempt to create an image reference
+// for a List that has not yet been saved to an image.
+var ErrListImageUnknown = stderrors.New("unable to determine which image holds the manifest list")
+
+type list struct {
+ manifests.List
+ instances map[digest.Digest]string
+}
+
+// List is a manifest list or image index, either created using Create(), or
+// loaded from local storage using LoadFromImage().
+type List interface {
+ manifests.List
+ SaveToImage(store storage.Store, imageID string, names []string, mimeType string) (string, error)
+ Reference(store storage.Store, multiple cp.ImageListSelection, instances []digest.Digest) (types.ImageReference, error)
+ Push(ctx context.Context, dest types.ImageReference, options PushOptions) (reference.Canonical, digest.Digest, error)
+ Add(ctx context.Context, sys *types.SystemContext, ref types.ImageReference, all bool) (digest.Digest, error)
+}
+
+// PushOptions includes various settings which are needed for pushing the
+// manifest list and its instances.
+type PushOptions struct {
+ Store storage.Store
+ SystemContext *types.SystemContext // github.com/containers/image/types.SystemContext
+ ImageListSelection cp.ImageListSelection // set to either CopySystemImage, CopyAllImages, or CopySpecificImages
+ Instances []digest.Digest // instances to copy if ImageListSelection == CopySpecificImages
+ ReportWriter io.Writer // will be used to log the writing of the list and any blobs
+ SignBy string // fingerprint of GPG key to use to sign images
+ RemoveSignatures bool // true to discard signatures in images
+ ManifestType string // the format to use when saving the list - possible options are oci, v2s1, and v2s2
+}
+
+// Create creates a new list containing information about the specified image,
+// computing its manifest's digest, and retrieving OS and architecture
+// information from its configuration blob. Returns the new list, and the
+// instanceDigest for the initial image.
+func Create() List {
+ return &list{
+ List: manifests.Create(),
+ instances: make(map[digest.Digest]string),
+ }
+}
+
+// LoadFromImage reads the manifest list or image index, and additional
+// information about where the various instances that it contains live, from an
+// image record with the specified ID in local storage.
+func LoadFromImage(store storage.Store, image string) (string, List, error) {
+ img, err := store.Image(image)
+ if err != nil {
+ return "", nil, errors.Wrapf(err, "error locating image %q for loading manifest list", image)
+ }
+ manifestBytes, err := store.ImageBigData(img.ID, storage.ImageDigestManifestBigDataNamePrefix)
+ if err != nil {
+ return "", nil, errors.Wrapf(err, "error locating image %q for loading manifest list", image)
+ }
+ manifestList, err := manifests.FromBlob(manifestBytes)
+ if err != nil {
+ return "", nil, err
+ }
+ list := &list{
+ List: manifestList,
+ instances: make(map[digest.Digest]string),
+ }
+ instancesBytes, err := store.ImageBigData(img.ID, instancesData)
+ if err != nil {
+ return "", nil, errors.Wrapf(err, "error locating image %q for loading instance list", image)
+ }
+ if err := json.Unmarshal(instancesBytes, &list.instances); err != nil {
+ return "", nil, errors.Wrapf(err, "error decoding instance list for image %q", image)
+ }
+ list.instances[""] = img.ID
+ return img.ID, list, err
+}
+
+// SaveToImage saves the manifest list or image index as the manifest of an
+// Image record with the specified names in local storage, generating a random
+// image ID if none is specified. It also stores information about where the
+// images whose manifests are included in the list can be found.
+func (l *list) SaveToImage(store storage.Store, imageID string, names []string, mimeType string) (string, error) {
+ manifestBytes, err := l.List.Serialize(mimeType)
+ if err != nil {
+ return "", err
+ }
+ instancesBytes, err := json.Marshal(&l.instances)
+ if err != nil {
+ return "", err
+ }
+ img, err := store.CreateImage(imageID, names, "", "", &storage.ImageOptions{})
+ if err == nil || errors.Cause(err) == storage.ErrDuplicateID {
+ created := (err == nil)
+ if created {
+ imageID = img.ID
+ l.instances[""] = img.ID
+ }
+ err := store.SetImageBigData(imageID, storage.ImageDigestManifestBigDataNamePrefix, manifestBytes, manifest.Digest)
+ if err != nil {
+ if created {
+ if _, err2 := store.DeleteImage(img.ID, true); err2 != nil {
+ logrus.Errorf("error deleting image %q after failing to save manifest for it", img.ID)
+ }
+ }
+ return "", errors.Wrapf(err, "error saving manifest list to image %q", imageID)
+ }
+ err = store.SetImageBigData(imageID, instancesData, instancesBytes, nil)
+ if err != nil {
+ if created {
+ if _, err2 := store.DeleteImage(img.ID, true); err2 != nil {
+ logrus.Errorf("error deleting image %q after failing to save instance locations for it", img.ID)
+ }
+ }
+ return "", errors.Wrapf(err, "error saving instance list to image %q", imageID)
+ }
+ return imageID, nil
+ }
+ return "", errors.Wrapf(err, "error creating image to hold manifest list")
+}
+
+// Reference returns an image reference for the composite image being built
+// in the list, or an error if the list has never been saved to a local image.
+func (l *list) Reference(store storage.Store, multiple cp.ImageListSelection, instances []digest.Digest) (types.ImageReference, error) {
+ if l.instances[""] == "" {
+ return nil, errors.Wrap(ErrListImageUnknown, "error building reference to list")
+ }
+ s, err := is.Transport.ParseStoreReference(store, l.instances[""])
+ if err != nil {
+ return nil, errors.Wrapf(err, "error creating ImageReference from image %q", l.instances[""])
+ }
+ references := make([]types.ImageReference, 0, len(l.instances))
+ whichInstances := make([]digest.Digest, 0, len(l.instances))
+ switch multiple {
+ case cp.CopyAllImages, cp.CopySystemImage:
+ for instance := range l.instances {
+ if instance != "" {
+ whichInstances = append(whichInstances, instance)
+ }
+ }
+ case cp.CopySpecificImages:
+ for instance := range l.instances {
+ for _, allowed := range instances {
+ if instance == allowed {
+ whichInstances = append(whichInstances, instance)
+ }
+ }
+ }
+ }
+ for _, instance := range whichInstances {
+ imageName := l.instances[instance]
+ ref, err := alltransports.ParseImageName(imageName)
+ if err != nil {
+ return nil, errors.Wrapf(err, "error creating ImageReference from image %q", imageName)
+ }
+ references = append(references, ref)
+ }
+ return supplemented.Reference(s, references, multiple, instances), nil
+}
+
+// Push saves the manifest list and whichever blobs are needed to a destination location.
+func (l *list) Push(ctx context.Context, dest types.ImageReference, options PushOptions) (reference.Canonical, digest.Digest, error) {
+ // Load the system signing policy.
+ pushPolicy, err := signature.DefaultPolicy(options.SystemContext)
+ if err != nil {
+ return nil, "", errors.Wrapf(err, "error obtaining default signature policy")
+ }
+
+ // Override the settings for local storage to make sure that we can always read the source "image".
+ pushPolicy.Transports[is.Transport.Name()] = storageAllowedPolicyScopes
+
+ policyContext, err := signature.NewPolicyContext(pushPolicy)
+ if err != nil {
+ return nil, "", errors.Wrapf(err, "error creating new signature policy context")
+ }
+ defer func() {
+ if err2 := policyContext.Destroy(); err2 != nil {
+ logrus.Errorf("error destroying signature policy context: %v", err2)
+ }
+ }()
+
+ // If we were given a media type that corresponds to a multiple-images
+ // type, reset it to a valid corresponding single-image type, since we
+ // already expect the image library to infer the list type from the
+ // image type that we're telling it to force.
+ singleImageManifestType := options.ManifestType
+ switch singleImageManifestType {
+ case v1.MediaTypeImageIndex:
+ singleImageManifestType = v1.MediaTypeImageManifest
+ case manifest.DockerV2ListMediaType:
+ singleImageManifestType = manifest.DockerV2Schema2MediaType
+ }
+
+ // Build a source reference for our list and grab bag full of blobs.
+ src, err := l.Reference(options.Store, options.ImageListSelection, options.Instances)
+ if err != nil {
+ return nil, "", err
+ }
+ copyOptions := &cp.Options{
+ ImageListSelection: options.ImageListSelection,
+ Instances: options.Instances,
+ SourceCtx: options.SystemContext,
+ DestinationCtx: options.SystemContext,
+ ReportWriter: options.ReportWriter,
+ RemoveSignatures: options.RemoveSignatures,
+ SignBy: options.SignBy,
+ ForceManifestMIMEType: singleImageManifestType,
+ }
+
+ // Copy whatever we were asked to copy.
+ manifestBytes, err := cp.Image(ctx, policyContext, dest, src, copyOptions)
+ if err != nil {
+ return nil, "", err
+ }
+ manifestDigest, err := manifest.Digest(manifestBytes)
+ if err != nil {
+ return nil, "", err
+ }
+ return nil, manifestDigest, nil
+}
+
+// Add adds information about the specified image to the list, computing the
+// image's manifest's digest, retrieving OS and architecture information from
+// the image's configuration, and recording the image's reference so that it
+// can be found at push-time. Returns the instanceDigest for the image. If
+// the reference points to an image list, either all instances are added (if
+// "all" is true), or the instance which matches "sys" (if "all" is false) will
+// be added.
+func (l *list) Add(ctx context.Context, sys *types.SystemContext, ref types.ImageReference, all bool) (digest.Digest, error) {
+ src, err := ref.NewImageSource(ctx, sys)
+ if err != nil {
+ return "", errors.Wrapf(err, "error setting up to read manifest and configuration from %q", transports.ImageName(ref))
+ }
+ defer src.Close()
+
+ type instanceInfo struct {
+ instanceDigest *digest.Digest
+ OS, Architecture, OSVersion, Variant string
+ Features, OSFeatures, Annotations []string
+ Size int64
+ }
+ var instanceInfos []instanceInfo
+ var manifestDigest digest.Digest
+
+ primaryManifestBytes, primaryManifestType, err := src.GetManifest(ctx, nil)
+ if err != nil {
+ return "", errors.Wrapf(err, "error reading manifest from %q", transports.ImageName(ref))
+ }
+
+ if manifest.MIMETypeIsMultiImage(primaryManifestType) {
+ lists, err := manifests.FromBlob(primaryManifestBytes)
+ if err != nil {
+ return "", errors.Wrapf(err, "error parsing manifest list in %q", transports.ImageName(ref))
+ }
+ if all {
+ for i, instance := range lists.OCIv1().Manifests {
+ platform := instance.Platform
+ if platform == nil {
+ platform = &v1.Platform{}
+ }
+ instanceDigest := instance.Digest
+ instanceInfo := instanceInfo{
+ instanceDigest: &instanceDigest,
+ OS: platform.OS,
+ Architecture: platform.Architecture,
+ OSVersion: platform.OSVersion,
+ Variant: platform.Variant,
+ Features: append([]string{}, lists.Docker().Manifests[i].Platform.Features...),
+ OSFeatures: append([]string{}, platform.OSFeatures...),
+ Size: instance.Size,
+ }
+ instanceInfos = append(instanceInfos, instanceInfo)
+ }
+ } else {
+ list, err := manifest.ListFromBlob(primaryManifestBytes, primaryManifestType)
+ if err != nil {
+ return "", errors.Wrapf(err, "error parsing manifest list in %q", transports.ImageName(ref))
+ }
+ instanceDigest, err := list.ChooseInstance(sys)
+ if err != nil {
+ return "", errors.Wrapf(err, "error selecting image from manifest list in %q", transports.ImageName(ref))
+ }
+ added := false
+ for i, instance := range lists.OCIv1().Manifests {
+ if instance.Digest != instanceDigest {
+ continue
+ }
+ platform := instance.Platform
+ if platform == nil {
+ platform = &v1.Platform{}
+ }
+ instanceInfo := instanceInfo{
+ instanceDigest: &instanceDigest,
+ OS: platform.OS,
+ Architecture: platform.Architecture,
+ OSVersion: platform.OSVersion,
+ Variant: platform.Variant,
+ Features: append([]string{}, lists.Docker().Manifests[i].Platform.Features...),
+ OSFeatures: append([]string{}, platform.OSFeatures...),
+ Size: instance.Size,
+ }
+ instanceInfos = append(instanceInfos, instanceInfo)
+ added = true
+ }
+ if !added {
+ instanceInfo := instanceInfo{
+ instanceDigest: &instanceDigest,
+ }
+ instanceInfos = append(instanceInfos, instanceInfo)
+ }
+ }
+ } else {
+ instanceInfo := instanceInfo{
+ instanceDigest: nil,
+ }
+ instanceInfos = append(instanceInfos, instanceInfo)
+ }
+
+ for _, instanceInfo := range instanceInfos {
+ if instanceInfo.OS == "" || instanceInfo.Architecture == "" {
+ img, err := image.FromUnparsedImage(ctx, sys, image.UnparsedInstance(src, instanceInfo.instanceDigest))
+ if err != nil {
+ return "", errors.Wrapf(err, "error reading configuration blob from %q", transports.ImageName(ref))
+ }
+ config, err := img.OCIConfig(ctx)
+ if err != nil {
+ return "", errors.Wrapf(err, "error reading info about config blob from %q", transports.ImageName(ref))
+ }
+ if instanceInfo.OS == "" {
+ instanceInfo.OS = config.OS
+ }
+ if instanceInfo.Architecture == "" {
+ instanceInfo.Architecture = config.Architecture
+ }
+ }
+ manifestBytes, manifestType, err := src.GetManifest(ctx, instanceInfo.instanceDigest)
+ if err != nil {
+ return "", errors.Wrapf(err, "error reading manifest from %q, instance %q", transports.ImageName(ref), instanceInfo.instanceDigest)
+ }
+ if instanceInfo.instanceDigest == nil {
+ manifestDigest, err = manifest.Digest(manifestBytes)
+ if err != nil {
+ return "", errors.Wrapf(err, "error computing digest of manifest from %q", transports.ImageName(ref))
+ }
+ instanceInfo.instanceDigest = &manifestDigest
+ instanceInfo.Size = int64(len(manifestBytes))
+ } else {
+ if manifestDigest == "" {
+ manifestDigest = *instanceInfo.instanceDigest
+ }
+ }
+ err = l.List.AddInstance(*instanceInfo.instanceDigest, instanceInfo.Size, manifestType, instanceInfo.OS, instanceInfo.Architecture, instanceInfo.OSVersion, instanceInfo.OSFeatures, instanceInfo.Variant, instanceInfo.Features, instanceInfo.Annotations)
+ if err != nil {
+ return "", errors.Wrapf(err, "error adding instance with digest %q", *instanceInfo.instanceDigest)
+ }
+ if _, ok := l.instances[*instanceInfo.instanceDigest]; !ok {
+ l.instances[*instanceInfo.instanceDigest] = transports.ImageName(ref)
+ }
+ }
+
+ return manifestDigest, nil
+}
+
+// Remove filters out any instances in the list which match the specified digest.
+func (l *list) Remove(instanceDigest digest.Digest) error {
+ err := l.List.Remove(instanceDigest)
+ if err == nil {
+ if _, needToDelete := l.instances[instanceDigest]; needToDelete {
+ delete(l.instances, instanceDigest)
+ }
+ }
+ return err
+}
diff --git a/vendor/github.com/containers/buildah/new.go b/vendor/github.com/containers/buildah/new.go
index da6b357bf..a6b6899e0 100644
--- a/vendor/github.com/containers/buildah/new.go
+++ b/vendor/github.com/containers/buildah/new.go
@@ -34,6 +34,8 @@ func pullAndFindImage(ctx context.Context, store storage.Store, srcRef types.Ima
Store: store,
SystemContext: options.SystemContext,
BlobDirectory: options.BlobDirectory,
+ MaxRetries: options.MaxPullRetries,
+ RetryDelay: options.PullRetryDelay,
}
ref, err := pullImage(ctx, store, srcRef, pullOptions, sc)
if err != nil {
@@ -398,14 +400,13 @@ func newBuilder(ctx context.Context, store storage.Store, options BuilderOptions
UIDMap: uidmap,
GIDMap: gidmap,
},
- AddCapabilities: copyStringSlice(options.AddCapabilities),
- DropCapabilities: copyStringSlice(options.DropCapabilities),
- CommonBuildOpts: options.CommonBuildOpts,
- TopLayer: topLayer,
- Args: options.Args,
- Format: options.Format,
- TempVolumes: map[string]bool{},
- Devices: options.Devices,
+ Capabilities: copyStringSlice(options.Capabilities),
+ CommonBuildOpts: options.CommonBuildOpts,
+ TopLayer: topLayer,
+ Args: options.Args,
+ Format: options.Format,
+ TempVolumes: map[string]bool{},
+ Devices: options.Devices,
}
if options.Mount {
diff --git a/vendor/github.com/containers/buildah/pkg/cli/common.go b/vendor/github.com/containers/buildah/pkg/cli/common.go
index 4c2d29c06..9cd3b65f1 100644
--- a/vendor/github.com/containers/buildah/pkg/cli/common.go
+++ b/vendor/github.com/containers/buildah/pkg/cli/common.go
@@ -11,7 +11,9 @@ import (
"strings"
"github.com/containers/buildah"
+ "github.com/containers/buildah/pkg/parse"
"github.com/containers/buildah/util"
+ "github.com/containers/common/pkg/config"
"github.com/opencontainers/runtime-spec/specs-go"
"github.com/pkg/errors"
"github.com/spf13/pflag"
@@ -45,6 +47,7 @@ type NameSpaceResults struct {
// BudResults represents the results for Bud flags
type BudResults struct {
Annotation []string
+ Arch string
Authfile string
BuildArg []string
CacheFrom string
@@ -60,6 +63,7 @@ type BudResults struct {
Logfile string
Loglevel int
NoCache bool
+ OS string
Platform string
Pull bool
PullAlways bool
@@ -69,6 +73,7 @@ type BudResults struct {
Runtime string
RuntimeFlags []string
SignaturePolicy string
+ SignBy string
Squash bool
Tag []string
Target string
@@ -143,6 +148,7 @@ func GetLayerFlags(flags *LayerResults) pflag.FlagSet {
// GetBudFlags returns common bud flags
func GetBudFlags(flags *BudResults) pflag.FlagSet {
fs := pflag.FlagSet{}
+ fs.StringVar(&flags.Arch, "arch", runtime.GOARCH, "set the ARCH of the image to the provided value instead of the architecture of the host")
fs.StringArrayVar(&flags.Annotation, "annotation", []string{}, "Set metadata for an image (default [])")
fs.StringVar(&flags.Authfile, "authfile", GetDefaultAuthFile(), "path of the authentication file.")
fs.StringArrayVar(&flags.BuildArg, "build-arg", []string{}, "`argument=value` to supply to the builder")
@@ -159,7 +165,8 @@ func GetBudFlags(flags *BudResults) pflag.FlagSet {
fs.BoolVar(&flags.NoCache, "no-cache", false, "Do not use existing cached images for the container build. Build from the start with a new set of cached layers.")
fs.StringVar(&flags.Logfile, "logfile", "", "log to `file` instead of stdout/stderr")
fs.IntVar(&flags.Loglevel, "loglevel", 0, "adjust logging level (range from -2 to 3)")
- fs.StringVar(&flags.Platform, "platform", "", "CLI compatibility: no action or effect")
+ fs.StringVar(&flags.OS, "os", runtime.GOOS, "set the OS to the provided value instead of the current operating system of the host")
+ fs.StringVar(&flags.Platform, "platform", parse.DefaultPlatform(), "set the OS/ARCH to the provided value instead of the current operating system and architecture of the host (for example `linux/arm`)")
fs.BoolVar(&flags.Pull, "pull", true, "pull the image from the registry if newer or not present in store, if false, only pull the image if not present")
fs.BoolVar(&flags.PullAlways, "pull-always", false, "pull the image even if the named image is present in store")
fs.BoolVar(&flags.PullNever, "pull-never", false, "do not pull the image, use the image present in store if available")
@@ -167,16 +174,22 @@ func GetBudFlags(flags *BudResults) pflag.FlagSet {
fs.BoolVar(&flags.Rm, "rm", true, "Remove intermediate containers after a successful build")
// "runtime" definition moved to avoid name collision in podman build. Defined in cmd/buildah/bud.go.
fs.StringSliceVar(&flags.RuntimeFlags, "runtime-flag", []string{}, "add global flags for the container runtime")
+ fs.StringVar(&flags.SignBy, "sign-by", "", "sign the image using a GPG key with the specified `FINGERPRINT`")
fs.StringVar(&flags.SignaturePolicy, "signature-policy", "", "`pathname` of signature policy file (not usually used)")
- fs.BoolVar(&flags.Squash, "squash", false, "Squash newly built layers into a single new layer.")
+ fs.BoolVar(&flags.Squash, "squash", false, "squash newly built layers into a single new layer")
fs.StringArrayVarP(&flags.Tag, "tag", "t", []string{}, "tagged `name` to apply to the built image")
fs.StringVar(&flags.Target, "target", "", "set the target build stage to build")
fs.BoolVar(&flags.TLSVerify, "tls-verify", true, "require HTTPS and verify certificates when accessing the registry")
return fs
}
-func GetFromAndBudFlags(flags *FromAndBudResults, usernsResults *UserNSResults, namespaceResults *NameSpaceResults) pflag.FlagSet {
+func GetFromAndBudFlags(flags *FromAndBudResults, usernsResults *UserNSResults, namespaceResults *NameSpaceResults) (pflag.FlagSet, error) {
fs := pflag.FlagSet{}
+ defaultContainerConfig, err := config.Default()
+ if err != nil {
+ return fs, errors.Wrapf(err, "failed to get container config")
+ }
+
fs.StringSliceVar(&flags.AddHost, "add-host", []string{}, "add a custom host-to-IP mapping (`host:ip`) (default [])")
fs.StringVar(&flags.BlobCache, "blob-cache", "", "assume image blobs in the specified directory will be available for pushing")
if err := fs.MarkHidden("blob-cache"); err != nil {
@@ -190,10 +203,10 @@ func GetFromAndBudFlags(flags *FromAndBudResults, usernsResults *UserNSResults,
fs.Uint64VarP(&flags.CPUShares, "cpu-shares", "c", 0, "CPU shares (relative weight)")
fs.StringVar(&flags.CPUSetCPUs, "cpuset-cpus", "", "CPUs in which to allow execution (0-3, 0,1)")
fs.StringVar(&flags.CPUSetMems, "cpuset-mems", "", "memory nodes (MEMs) in which to allow execution (0-3, 0,1). Only effective on NUMA systems.")
- fs.StringArrayVar(&flags.Devices, "device", []string{}, "Additional devices to be used within containers (default [])")
- fs.StringSliceVar(&flags.DNSSearch, "dns-search", []string{}, "Set custom DNS search domains")
- fs.StringSliceVar(&flags.DNSServers, "dns", []string{}, "Set custom DNS servers or disable it completely by setting it to 'none', which prevents the automatic creation of `/etc/resolv.conf`.")
- fs.StringSliceVar(&flags.DNSOptions, "dns-option", []string{}, "Set custom DNS options")
+ fs.StringArrayVar(&flags.Devices, "device", defaultContainerConfig.Containers.Devices, "Additional devices to be used within containers (default [])")
+ fs.StringSliceVar(&flags.DNSSearch, "dns-search", defaultContainerConfig.Containers.DNSSearches, "Set custom DNS search domains")
+ fs.StringSliceVar(&flags.DNSServers, "dns", defaultContainerConfig.Containers.DNSServers, "Set custom DNS servers or disable it completely by setting it to 'none', which prevents the automatic creation of `/etc/resolv.conf`.")
+ fs.StringSliceVar(&flags.DNSOptions, "dns-option", defaultContainerConfig.Containers.DNSOptions, "Set custom DNS options")
fs.BoolVar(&flags.HTTPProxy, "http-proxy", true, "pass through HTTP Proxy environment variables")
fs.StringVar(&flags.Isolation, "isolation", DefaultIsolation(), "`type` of process isolation to use. Use BUILDAH_ISOLATION environment variable to override.")
fs.StringVarP(&flags.Memory, "memory", "m", "", "memory limit (format: <number>[<unit>], where unit = b, k, m or g)")
@@ -207,9 +220,9 @@ func GetFromAndBudFlags(flags *FromAndBudResults, usernsResults *UserNSResults,
panic(fmt.Sprintf("error marking override-arch as hidden: %v", err))
}
fs.StringArrayVar(&flags.SecurityOpt, "security-opt", []string{}, "security options (default [])")
- fs.StringVar(&flags.ShmSize, "shm-size", "65536k", "size of '/dev/shm'. The format is `<number><unit>`.")
- fs.StringSliceVar(&flags.Ulimit, "ulimit", []string{}, "ulimit options (default [])")
- fs.StringArrayVarP(&flags.Volumes, "volume", "v", []string{}, "bind mount a volume into the container (default [])")
+ fs.StringVar(&flags.ShmSize, "shm-size", defaultContainerConfig.Containers.ShmSize, "size of '/dev/shm'. The format is `<number><unit>`.")
+ fs.StringSliceVar(&flags.Ulimit, "ulimit", defaultContainerConfig.Containers.DefaultUlimits, "ulimit options")
+ fs.StringArrayVarP(&flags.Volumes, "volume", "v", defaultContainerConfig.Containers.Volumes, "bind mount a volume into the container")
// Add in the usernamespace and namespaceflags
usernsFlags := GetUserNSFlags(usernsResults)
@@ -217,7 +230,7 @@ func GetFromAndBudFlags(flags *FromAndBudResults, usernsResults *UserNSResults,
fs.AddFlagSet(&usernsFlags)
fs.AddFlagSet(&namespaceFlags)
- return fs
+ return fs, nil
}
// UseLayers returns true if BUILDAH_LAYERS is set to "1" or "true"
diff --git a/vendor/github.com/containers/buildah/pkg/manifests/errors.go b/vendor/github.com/containers/buildah/pkg/manifests/errors.go
new file mode 100644
index 000000000..8398d7efc
--- /dev/null
+++ b/vendor/github.com/containers/buildah/pkg/manifests/errors.go
@@ -0,0 +1,16 @@
+package manifests
+
+import (
+ "errors"
+)
+
+var (
+ // ErrDigestNotFound is returned when we look for an image instance
+ // with a particular digest in a list or index, and fail to find it.
+ ErrDigestNotFound = errors.New("no image instance matching the specified digest was found in the list or index")
+ // ErrManifestTypeNotSupported is returned when we attempt to parse a
+ // manifest with a known MIME type as a list or index, or when we attempt
+ // to serialize a list or index to a manifest with a MIME type that we
+ // don't know how to encode.
+ ErrManifestTypeNotSupported = errors.New("manifest type not supported")
+)
diff --git a/vendor/github.com/containers/buildah/pkg/manifests/manifests.go b/vendor/github.com/containers/buildah/pkg/manifests/manifests.go
new file mode 100644
index 000000000..ea9495ee7
--- /dev/null
+++ b/vendor/github.com/containers/buildah/pkg/manifests/manifests.go
@@ -0,0 +1,493 @@
+package manifests
+
+import (
+ "encoding/json"
+ "os"
+
+ "github.com/containers/image/v5/manifest"
+ digest "github.com/opencontainers/go-digest"
+ imgspec "github.com/opencontainers/image-spec/specs-go"
+ v1 "github.com/opencontainers/image-spec/specs-go/v1"
+ "github.com/pkg/errors"
+)
+
+// List is a generic interface for manipulating a manifest list or an image
+// index.
+type List interface {
+ AddInstance(manifestDigest digest.Digest, manifestSize int64, manifestType, os, architecture, osVersion string, osFeatures []string, variant string, features []string, annotations []string) error
+ Remove(instanceDigest digest.Digest) error
+
+ SetURLs(instanceDigest digest.Digest, urls []string) error
+ URLs(instanceDigest digest.Digest) ([]string, error)
+
+ SetAnnotations(instanceDigest *digest.Digest, annotations map[string]string) error
+ Annotations(instanceDigest *digest.Digest) (map[string]string, error)
+
+ SetOS(instanceDigest digest.Digest, os string) error
+ OS(instanceDigest digest.Digest) (string, error)
+
+ SetArchitecture(instanceDigest digest.Digest, arch string) error
+ Architecture(instanceDigest digest.Digest) (string, error)
+
+ SetOSVersion(instanceDigest digest.Digest, osVersion string) error
+ OSVersion(instanceDigest digest.Digest) (string, error)
+
+ SetVariant(instanceDigest digest.Digest, variant string) error
+ Variant(instanceDigest digest.Digest) (string, error)
+
+ SetFeatures(instanceDigest digest.Digest, features []string) error
+ Features(instanceDigest digest.Digest) ([]string, error)
+
+ SetOSFeatures(instanceDigest digest.Digest, osFeatures []string) error
+ OSFeatures(instanceDigest digest.Digest) ([]string, error)
+
+ Serialize(mimeType string) ([]byte, error)
+ Instances() []digest.Digest
+ OCIv1() *v1.Index
+ Docker() *manifest.Schema2List
+
+ findDocker(instanceDigest digest.Digest) (*manifest.Schema2ManifestDescriptor, error)
+ findOCIv1(instanceDigest digest.Digest) (*v1.Descriptor, error)
+}
+
+type list struct {
+ docker manifest.Schema2List
+ oci v1.Index
+}
+
+// OCIv1 returns the list as a Docker schema 2 list. The returned structure should NOT be modified.
+func (l *list) Docker() *manifest.Schema2List {
+ return &l.docker
+}
+
+// OCIv1 returns the list as an OCI image index. The returned structure should NOT be modified.
+func (l *list) OCIv1() *v1.Index {
+ return &l.oci
+}
+
+// Create creates a new list.
+func Create() List {
+ return &list{
+ docker: manifest.Schema2List{
+ SchemaVersion: 2,
+ MediaType: manifest.DockerV2ListMediaType,
+ },
+ oci: v1.Index{
+ Versioned: imgspec.Versioned{SchemaVersion: 2},
+ },
+ }
+}
+
+// AddInstance adds an entry for the specified manifest digest, with assorted
+// additional information specified in parameters, to the list or index.
+func (l *list) AddInstance(manifestDigest digest.Digest, manifestSize int64, manifestType, osName, architecture, osVersion string, osFeatures []string, variant string, features []string, annotations []string) error {
+ if err := l.Remove(manifestDigest); err != nil && !os.IsNotExist(errors.Cause(err)) {
+ return err
+ }
+
+ schema2platform := manifest.Schema2PlatformSpec{
+ Architecture: architecture,
+ OS: osName,
+ OSVersion: osVersion,
+ OSFeatures: osFeatures,
+ Variant: variant,
+ Features: features,
+ }
+ l.docker.Manifests = append(l.docker.Manifests, manifest.Schema2ManifestDescriptor{
+ Schema2Descriptor: manifest.Schema2Descriptor{
+ MediaType: manifestType,
+ Size: manifestSize,
+ Digest: manifestDigest,
+ },
+ Platform: schema2platform,
+ })
+
+ ociv1platform := v1.Platform{
+ Architecture: architecture,
+ OS: osName,
+ OSVersion: osVersion,
+ OSFeatures: osFeatures,
+ Variant: variant,
+ }
+ l.oci.Manifests = append(l.oci.Manifests, v1.Descriptor{
+ MediaType: manifestType,
+ Size: manifestSize,
+ Digest: manifestDigest,
+ Platform: &ociv1platform,
+ })
+
+ return nil
+}
+
+// Remove filters out any instances in the list which match the specified digest.
+func (l *list) Remove(instanceDigest digest.Digest) error {
+ err := errors.Wrapf(os.ErrNotExist, "no instance matching digest %q found in manifest list", instanceDigest)
+ newDockerManifests := make([]manifest.Schema2ManifestDescriptor, 0, len(l.docker.Manifests))
+ for i := range l.docker.Manifests {
+ if l.docker.Manifests[i].Digest != instanceDigest {
+ newDockerManifests = append(newDockerManifests, l.docker.Manifests[i])
+ } else {
+ err = nil
+ }
+ }
+ l.docker.Manifests = newDockerManifests
+ newOCIv1Manifests := make([]v1.Descriptor, 0, len(l.oci.Manifests))
+ for i := range l.oci.Manifests {
+ if l.oci.Manifests[i].Digest != instanceDigest {
+ newOCIv1Manifests = append(newOCIv1Manifests, l.oci.Manifests[i])
+ } else {
+ err = nil
+ }
+ }
+ l.oci.Manifests = newOCIv1Manifests
+ return err
+}
+
+func (l *list) findDocker(instanceDigest digest.Digest) (*manifest.Schema2ManifestDescriptor, error) {
+ for i := range l.docker.Manifests {
+ if l.docker.Manifests[i].Digest == instanceDigest {
+ return &l.docker.Manifests[i], nil
+ }
+ }
+ return nil, errors.Wrapf(ErrDigestNotFound, "no Docker manifest matching digest %q was found in list", instanceDigest.String())
+}
+
+func (l *list) findOCIv1(instanceDigest digest.Digest) (*v1.Descriptor, error) {
+ for i := range l.oci.Manifests {
+ if l.oci.Manifests[i].Digest == instanceDigest {
+ return &l.oci.Manifests[i], nil
+ }
+ }
+ return nil, errors.Wrapf(ErrDigestNotFound, "no OCI manifest matching digest %q was found in list", instanceDigest.String())
+}
+
+// SetURLs sets the URLs where the manifest might also be found.
+func (l *list) SetURLs(instanceDigest digest.Digest, urls []string) error {
+ oci, err := l.findOCIv1(instanceDigest)
+ if err != nil {
+ return err
+ }
+ docker, err := l.findDocker(instanceDigest)
+ if err != nil {
+ return err
+ }
+ oci.URLs = append([]string{}, urls...)
+ docker.URLs = append([]string{}, urls...)
+ return nil
+}
+
+// URLs retrieves the locations from which this object might possibly be downloaded.
+func (l *list) URLs(instanceDigest digest.Digest) ([]string, error) {
+ oci, err := l.findOCIv1(instanceDigest)
+ if err != nil {
+ return nil, err
+ }
+ return append([]string{}, oci.URLs...), nil
+}
+
+// SetAnnotations sets annotations on the image index, or on a specific manifest.
+// The field is specific to the OCI image index format, and is not present in Docker manifest lists.
+func (l *list) SetAnnotations(instanceDigest *digest.Digest, annotations map[string]string) error {
+ a := &l.oci.Annotations
+ if instanceDigest != nil {
+ oci, err := l.findOCIv1(*instanceDigest)
+ if err != nil {
+ return err
+ }
+ a = &oci.Annotations
+ }
+ (*a) = make(map[string]string)
+ for k, v := range annotations {
+ (*a)[k] = v
+ }
+ return nil
+}
+
+// Annotations retrieves the annotations which have been set on the image index, or on one instance.
+// The field is specific to the OCI image index format, and is not present in Docker manifest lists.
+func (l *list) Annotations(instanceDigest *digest.Digest) (map[string]string, error) {
+ a := l.oci.Annotations
+ if instanceDigest != nil {
+ oci, err := l.findOCIv1(*instanceDigest)
+ if err != nil {
+ return nil, err
+ }
+ a = oci.Annotations
+ }
+ annotations := make(map[string]string)
+ for k, v := range a {
+ annotations[k] = v
+ }
+ return annotations, nil
+}
+
+// SetOS sets the OS field in the platform information associated with the instance with the specified digest.
+func (l *list) SetOS(instanceDigest digest.Digest, os string) error {
+ docker, err := l.findDocker(instanceDigest)
+ if err != nil {
+ return err
+ }
+ oci, err := l.findOCIv1(instanceDigest)
+ if err != nil {
+ return err
+ }
+ docker.Platform.OS = os
+ oci.Platform.OS = os
+ return nil
+}
+
+// OS retrieves the OS field in the platform information associated with the instance with the specified digest.
+func (l *list) OS(instanceDigest digest.Digest) (string, error) {
+ oci, err := l.findOCIv1(instanceDigest)
+ if err != nil {
+ return "", err
+ }
+ return oci.Platform.OS, nil
+}
+
+// SetArchitecture sets the Architecture field in the platform information associated with the instance with the specified digest.
+func (l *list) SetArchitecture(instanceDigest digest.Digest, arch string) error {
+ docker, err := l.findDocker(instanceDigest)
+ if err != nil {
+ return err
+ }
+ oci, err := l.findOCIv1(instanceDigest)
+ if err != nil {
+ return err
+ }
+ docker.Platform.Architecture = arch
+ oci.Platform.Architecture = arch
+ return nil
+}
+
+// Architecture retrieves the Architecture field in the platform information associated with the instance with the specified digest.
+func (l *list) Architecture(instanceDigest digest.Digest) (string, error) {
+ oci, err := l.findOCIv1(instanceDigest)
+ if err != nil {
+ return "", err
+ }
+ return oci.Platform.Architecture, nil
+}
+
+// SetOSVersion sets the OSVersion field in the platform information associated with the instance with the specified digest.
+func (l *list) SetOSVersion(instanceDigest digest.Digest, osVersion string) error {
+ docker, err := l.findDocker(instanceDigest)
+ if err != nil {
+ return err
+ }
+ oci, err := l.findOCIv1(instanceDigest)
+ if err != nil {
+ return err
+ }
+ docker.Platform.OSVersion = osVersion
+ oci.Platform.OSVersion = osVersion
+ return nil
+}
+
+// OSVersion retrieves the OSVersion field in the platform information associated with the instance with the specified digest.
+func (l *list) OSVersion(instanceDigest digest.Digest) (string, error) {
+ oci, err := l.findOCIv1(instanceDigest)
+ if err != nil {
+ return "", err
+ }
+ return oci.Platform.OSVersion, nil
+}
+
+// SetVariant sets the Variant field in the platform information associated with the instance with the specified digest.
+func (l *list) SetVariant(instanceDigest digest.Digest, variant string) error {
+ docker, err := l.findDocker(instanceDigest)
+ if err != nil {
+ return err
+ }
+ oci, err := l.findOCIv1(instanceDigest)
+ if err != nil {
+ return err
+ }
+ docker.Platform.Variant = variant
+ oci.Platform.Variant = variant
+ return nil
+}
+
+// Variant retrieves the Variant field in the platform information associated with the instance with the specified digest.
+func (l *list) Variant(instanceDigest digest.Digest) (string, error) {
+ oci, err := l.findOCIv1(instanceDigest)
+ if err != nil {
+ return "", err
+ }
+ return oci.Platform.Variant, nil
+}
+
+// SetFeatures sets the features list in the platform information associated with the instance with the specified digest.
+// The field is specific to the Docker manifest list format, and is not present in OCI's image indexes.
+func (l *list) SetFeatures(instanceDigest digest.Digest, features []string) error {
+ docker, err := l.findDocker(instanceDigest)
+ if err != nil {
+ return err
+ }
+ docker.Platform.Features = append([]string{}, features...)
+ // no OCI equivalent
+ return nil
+}
+
+// Features retrieves the features list from the platform information associated with the instance with the specified digest.
+// The field is specific to the Docker manifest list format, and is not present in OCI's image indexes.
+func (l *list) Features(instanceDigest digest.Digest) ([]string, error) {
+ docker, err := l.findDocker(instanceDigest)
+ if err != nil {
+ return nil, err
+ }
+ return append([]string{}, docker.Platform.Features...), nil
+}
+
+// SetOSFeatures sets the OS features list in the platform information associated with the instance with the specified digest.
+func (l *list) SetOSFeatures(instanceDigest digest.Digest, osFeatures []string) error {
+ docker, err := l.findDocker(instanceDigest)
+ if err != nil {
+ return err
+ }
+ oci, err := l.findOCIv1(instanceDigest)
+ if err != nil {
+ return err
+ }
+ docker.Platform.OSFeatures = append([]string{}, osFeatures...)
+ oci.Platform.OSFeatures = append([]string{}, osFeatures...)
+ return nil
+}
+
+// OSFeatures retrieves the OS features list from the platform information associated with the instance with the specified digest.
+func (l *list) OSFeatures(instanceDigest digest.Digest) ([]string, error) {
+ oci, err := l.findOCIv1(instanceDigest)
+ if err != nil {
+ return nil, err
+ }
+ return append([]string{}, oci.Platform.OSFeatures...), nil
+}
+
+// FromBlob builds a list from an encoded manifest list or image index.
+func FromBlob(manifestBytes []byte) (List, error) {
+ manifestType := manifest.GuessMIMEType(manifestBytes)
+ list := &list{
+ docker: manifest.Schema2List{
+ SchemaVersion: 2,
+ MediaType: manifest.DockerV2ListMediaType,
+ },
+ oci: v1.Index{
+ Versioned: imgspec.Versioned{SchemaVersion: 2},
+ },
+ }
+ switch manifestType {
+ default:
+ return nil, errors.Wrapf(ErrManifestTypeNotSupported, "unable to load manifest list: unsupported format %q", manifestType)
+ case manifest.DockerV2ListMediaType:
+ if err := json.Unmarshal(manifestBytes, &list.docker); err != nil {
+ return nil, errors.Wrapf(err, "unable to parse Docker manifest list from image")
+ }
+ for _, m := range list.docker.Manifests {
+ list.oci.Manifests = append(list.oci.Manifests, v1.Descriptor{
+ MediaType: m.Schema2Descriptor.MediaType,
+ Size: m.Schema2Descriptor.Size,
+ Digest: m.Schema2Descriptor.Digest,
+ Platform: &v1.Platform{
+ Architecture: m.Platform.Architecture,
+ OS: m.Platform.OS,
+ OSVersion: m.Platform.OSVersion,
+ OSFeatures: m.Platform.OSFeatures,
+ Variant: m.Platform.Variant,
+ },
+ })
+ }
+ case v1.MediaTypeImageIndex:
+ if err := json.Unmarshal(manifestBytes, &list.oci); err != nil {
+ return nil, errors.Wrapf(err, "unable to parse OCIv1 manifest list")
+ }
+ for _, m := range list.oci.Manifests {
+ platform := m.Platform
+ if platform == nil {
+ platform = &v1.Platform{}
+ }
+ list.docker.Manifests = append(list.docker.Manifests, manifest.Schema2ManifestDescriptor{
+ Schema2Descriptor: manifest.Schema2Descriptor{
+ MediaType: m.MediaType,
+ Size: m.Size,
+ Digest: m.Digest,
+ },
+ Platform: manifest.Schema2PlatformSpec{
+ Architecture: platform.Architecture,
+ OS: platform.OS,
+ OSVersion: platform.OSVersion,
+ OSFeatures: platform.OSFeatures,
+ Variant: platform.Variant,
+ },
+ })
+ }
+ }
+ return list, nil
+}
+
+func (l *list) preferOCI() bool {
+ // If we have any data that's only in the OCI format, use that.
+ for _, m := range l.oci.Manifests {
+ if len(m.URLs) > 0 {
+ return true
+ }
+ if len(m.Annotations) > 0 {
+ return true
+ }
+ }
+ // If we have any data that's only in the Docker format, use that.
+ for _, m := range l.docker.Manifests {
+ if len(m.Platform.Features) > 0 {
+ return false
+ }
+ }
+ // If we have no manifests, remember that the Docker format is
+ // explicitly typed, so use that. Otherwise, default to using the OCI
+ // format.
+ return len(l.docker.Manifests) != 0
+}
+
+// Serialize encodes the list using the specified format, or by selecting one
+// which it thinks is appropriate.
+func (l *list) Serialize(mimeType string) ([]byte, error) {
+ var manifestBytes []byte
+ switch mimeType {
+ case "":
+ if l.preferOCI() {
+ manifest, err := json.Marshal(&l.oci)
+ if err != nil {
+ return nil, errors.Wrapf(err, "error marshalling OCI image index")
+ }
+ manifestBytes = manifest
+ } else {
+ manifest, err := json.Marshal(&l.docker)
+ if err != nil {
+ return nil, errors.Wrapf(err, "error marshalling Docker manifest list")
+ }
+ manifestBytes = manifest
+ }
+ case v1.MediaTypeImageIndex:
+ manifest, err := json.Marshal(&l.oci)
+ if err != nil {
+ return nil, errors.Wrapf(err, "error marshalling OCI image index")
+ }
+ manifestBytes = manifest
+ case manifest.DockerV2ListMediaType:
+ manifest, err := json.Marshal(&l.docker)
+ if err != nil {
+ return nil, errors.Wrapf(err, "error marshalling Docker manifest list")
+ }
+ manifestBytes = manifest
+ default:
+ return nil, errors.Wrapf(ErrManifestTypeNotSupported, "serializing list to type %q not implemented", mimeType)
+ }
+ return manifestBytes, nil
+}
+
+// Instances returns the list of image instances mentioned in this list.
+func (l *list) Instances() []digest.Digest {
+ instances := make([]digest.Digest, 0, len(l.oci.Manifests))
+ for _, instance := range l.oci.Manifests {
+ instances = append(instances, instance.Digest)
+ }
+ return instances
+}
diff --git a/vendor/github.com/containers/buildah/pkg/parse/parse.go b/vendor/github.com/containers/buildah/pkg/parse/parse.go
index d05f8075a..027ed103c 100644
--- a/vendor/github.com/containers/buildah/pkg/parse/parse.go
+++ b/vendor/github.com/containers/buildah/pkg/parse/parse.go
@@ -9,6 +9,7 @@ import (
"net"
"os"
"path/filepath"
+ "runtime"
"strconv"
"strings"
"unicode"
@@ -51,8 +52,6 @@ func CommonBuildOptions(c *cobra.Command) (*buildah.CommonBuildOptions, error) {
err error
)
- defaultLimits := getDefaultProcessLimits()
-
memVal, _ := c.Flags().GetString("memory")
if memVal != "" {
memoryLimit, err = units.RAMInBytes(memVal)
@@ -79,24 +78,33 @@ func CommonBuildOptions(c *cobra.Command) (*buildah.CommonBuildOptions, error) {
}
noDNS = false
- dnsServers, _ := c.Flags().GetStringSlice("dns")
- for _, server := range dnsServers {
- if strings.ToLower(server) == "none" {
- noDNS = true
+ dnsServers := []string{}
+ if c.Flag("dns").Changed {
+ dnsServers, _ = c.Flags().GetStringSlice("dns")
+ for _, server := range dnsServers {
+ if strings.ToLower(server) == "none" {
+ noDNS = true
+ }
+ }
+ if noDNS && len(dnsServers) > 1 {
+ return nil, errors.Errorf("invalid --dns, --dns=none may not be used with any other --dns options")
}
- }
- if noDNS && len(dnsServers) > 1 {
- return nil, errors.Errorf("invalid --dns, --dns=none may not be used with any other --dns options")
}
- dnsSearch, _ := c.Flags().GetStringSlice("dns-search")
- if noDNS && len(dnsSearch) > 0 {
- return nil, errors.Errorf("invalid --dns-search, --dns-search may not be used with --dns=none")
+ dnsSearch := []string{}
+ if c.Flag("dns-search").Changed {
+ dnsSearch, _ = c.Flags().GetStringSlice("dns-search")
+ if noDNS && len(dnsSearch) > 0 {
+ return nil, errors.Errorf("invalid --dns-search, --dns-search may not be used with --dns=none")
+ }
}
- dnsOptions, _ := c.Flags().GetStringSlice("dns-option")
- if noDNS && len(dnsOptions) > 0 {
- return nil, errors.Errorf("invalid --dns-option, --dns-option may not be used with --dns=none")
+ dnsOptions := []string{}
+ if c.Flag("dns-search").Changed {
+ dnsOptions, _ = c.Flags().GetStringSlice("dns-option")
+ if noDNS && len(dnsOptions) > 0 {
+ return nil, errors.Errorf("invalid --dns-option, --dns-option may not be used with --dns=none")
+ }
}
if _, err := units.FromHumanSize(c.Flag("shm-size").Value.String()); err != nil {
@@ -110,7 +118,12 @@ func CommonBuildOptions(c *cobra.Command) (*buildah.CommonBuildOptions, error) {
cpuQuota, _ := c.Flags().GetInt64("cpu-quota")
cpuShares, _ := c.Flags().GetUint64("cpu-shares")
httpProxy, _ := c.Flags().GetBool("http-proxy")
- ulimit, _ := c.Flags().GetStringSlice("ulimit")
+
+ ulimit := []string{}
+ if c.Flag("ulimit").Changed {
+ ulimit, _ = c.Flags().GetStringSlice("ulimit")
+ }
+
commonOpts := &buildah.CommonBuildOptions{
AddHost: addHost,
CgroupParent: c.Flag("cgroup-parent").Value.String(),
@@ -126,7 +139,7 @@ func CommonBuildOptions(c *cobra.Command) (*buildah.CommonBuildOptions, error) {
Memory: memoryLimit,
MemorySwap: memorySwap,
ShmSize: c.Flag("shm-size").Value.String(),
- Ulimit: append(defaultLimits, ulimit...),
+ Ulimit: ulimit,
Volumes: volumes,
}
securityOpts, _ := c.Flags().GetStringArray("security-opt")
@@ -600,6 +613,46 @@ func getAuthFile(authfile string) string {
return os.Getenv("REGISTRY_AUTH_FILE")
}
+// PlatformFromOptions parses the operating system (os) and architecture (arch)
+// from the provided command line options.
+func PlatformFromOptions(c *cobra.Command) (os, arch string, err error) {
+ os = runtime.GOOS
+ arch = runtime.GOARCH
+
+ if selectedOS, err := c.Flags().GetString("os"); err == nil && selectedOS != runtime.GOOS {
+ os = selectedOS
+ }
+ if selectedArch, err := c.Flags().GetString("arch"); err == nil && selectedArch != runtime.GOARCH {
+ arch = selectedArch
+ }
+
+ if pf, err := c.Flags().GetString("platform"); err == nil && pf != DefaultPlatform() {
+ selectedOS, selectedArch, err := parsePlatform(pf)
+ if err != nil {
+ return "", "", errors.Wrap(err, "unable to parse platform")
+ }
+ arch = selectedArch
+ os = selectedOS
+ }
+
+ return os, arch, nil
+}
+
+const platformSep = "/"
+
+// DefaultPlatform returns the standard platform for the current system
+func DefaultPlatform() string {
+ return runtime.GOOS + platformSep + runtime.GOARCH
+}
+
+func parsePlatform(platform string) (os, arch string, err error) {
+ split := strings.Split(platform, platformSep)
+ if len(split) != 2 {
+ return "", "", errors.Errorf("invalid platform syntax for %q (use OS/ARCH)", platform)
+ }
+ return split[0], split[1], nil
+}
+
func parseCreds(creds string) (string, string) {
if creds == "" {
return "", ""
@@ -858,8 +911,7 @@ func defaultIsolation() (buildah.Isolation, error) {
}
// IsolationOption parses the --isolation flag.
-func IsolationOption(c *cobra.Command) (buildah.Isolation, error) {
- isolation, _ := c.Flags().GetString("isolation")
+func IsolationOption(isolation string) (buildah.Isolation, error) {
if isolation != "" {
switch strings.ToLower(isolation) {
case "oci":
diff --git a/vendor/github.com/containers/buildah/pkg/parse/parse_unix.go b/vendor/github.com/containers/buildah/pkg/parse/parse_unix.go
index 906236cc3..33dc565d9 100644
--- a/vendor/github.com/containers/buildah/pkg/parse/parse_unix.go
+++ b/vendor/github.com/containers/buildah/pkg/parse/parse_unix.go
@@ -3,7 +3,6 @@
package parse
import (
- "fmt"
"os"
"path/filepath"
@@ -11,29 +10,16 @@ import (
"github.com/opencontainers/runc/libcontainer/configs"
"github.com/opencontainers/runc/libcontainer/devices"
"github.com/pkg/errors"
- "golang.org/x/sys/unix"
)
-func getDefaultProcessLimits() []string {
- rlim := unix.Rlimit{Cur: 1048576, Max: 1048576}
- defaultLimits := []string{}
- if err := unix.Setrlimit(unix.RLIMIT_NOFILE, &rlim); err == nil {
- defaultLimits = append(defaultLimits, fmt.Sprintf("nofile=%d:%d", rlim.Cur, rlim.Max))
- }
- if err := unix.Setrlimit(unix.RLIMIT_NPROC, &rlim); err == nil {
- defaultLimits = append(defaultLimits, fmt.Sprintf("nproc=%d:%d", rlim.Cur, rlim.Max))
- }
- return defaultLimits
-}
-
func DeviceFromPath(device string) ([]configs.Device, error) {
var devs []configs.Device
src, dst, permissions, err := Device(device)
if err != nil {
return nil, err
}
- if unshare.IsRootless() {
- return nil, errors.Errorf("Renaming device %s to %s is not a supported in rootless containers", src, dst)
+ if unshare.IsRootless() && src != dst {
+ return nil, errors.Errorf("Renaming device %s to %s is not supported in rootless containers", src, dst)
}
srcInfo, err := os.Stat(src)
if err != nil {
diff --git a/vendor/github.com/containers/buildah/pkg/parse/parse_unsupported.go b/vendor/github.com/containers/buildah/pkg/parse/parse_unsupported.go
index 51138f860..61734bc11 100644
--- a/vendor/github.com/containers/buildah/pkg/parse/parse_unsupported.go
+++ b/vendor/github.com/containers/buildah/pkg/parse/parse_unsupported.go
@@ -12,6 +12,6 @@ func getDefaultProcessLimits() []string {
return []string{}
}
-func DeviceFromPath(device string) (configs.Device, error) {
- return configs.Device{}, fmt.Errorf("devices not supported")
+func DeviceFromPath(device string) ([]configs.Device, error) {
+ return []configs.Device{}, fmt.Errorf("devices not supported")
}
diff --git a/vendor/github.com/containers/buildah/pkg/supplemented/errors.go b/vendor/github.com/containers/buildah/pkg/supplemented/errors.go
new file mode 100644
index 000000000..6de679b50
--- /dev/null
+++ b/vendor/github.com/containers/buildah/pkg/supplemented/errors.go
@@ -0,0 +1,17 @@
+package supplemented
+
+import (
+ "errors"
+
+ "github.com/containers/buildah/pkg/manifests"
+)
+
+var (
+ // ErrDigestNotFound is returned when we look for an image instance
+ // with a particular digest in a list or index, and fail to find it.
+ ErrDigestNotFound = manifests.ErrDigestNotFound
+ // ErrBlobNotFound is returned when try to figure out which supplemental
+ // image we should ask for a blob with the specified characteristics,
+ // based on the information in each of the supplemental images' manifests.
+ ErrBlobNotFound = errors.New("location of blob could not be determined")
+)
diff --git a/vendor/github.com/containers/buildah/pkg/supplemented/supplemented.go b/vendor/github.com/containers/buildah/pkg/supplemented/supplemented.go
new file mode 100644
index 000000000..5e3c6291a
--- /dev/null
+++ b/vendor/github.com/containers/buildah/pkg/supplemented/supplemented.go
@@ -0,0 +1,400 @@
+package supplemented
+
+import (
+ "container/list"
+ "context"
+ "io"
+
+ cp "github.com/containers/image/v5/copy"
+ "github.com/containers/image/v5/image"
+ "github.com/containers/image/v5/manifest"
+ "github.com/containers/image/v5/transports"
+ "github.com/containers/image/v5/types"
+ multierror "github.com/hashicorp/go-multierror"
+ digest "github.com/opencontainers/go-digest"
+ "github.com/pkg/errors"
+ "github.com/sirupsen/logrus"
+)
+
+// supplementedImageReference groups multiple references together.
+type supplementedImageReference struct {
+ types.ImageReference
+ references []types.ImageReference
+ multiple cp.ImageListSelection
+ instances []digest.Digest
+}
+
+// supplementedImageSource represents an image, plus all of the blobs of other images.
+type supplementedImageSource struct {
+ types.ImageSource
+ reference types.ImageReference
+ manifest []byte // The manifest list or image index.
+ manifestType string // The MIME type of the manifest list or image index.
+ sourceDefaultInstances map[types.ImageSource]digest.Digest // The default manifest instances of open ImageSource objects.
+ sourceInstancesByInstance map[digest.Digest]types.ImageSource // A map from manifest instance digests to open ImageSource objects.
+ instancesByBlobDigest map[digest.Digest]digest.Digest // A map from blob digests to manifest instance digests.
+}
+
+// Reference groups one reference and some number of additional references
+// together as a group. The first reference's default instance will be treated
+// as the default instance of the resulting reference, with the other
+// references' instances made available as instances for their respective
+// digests.
+func Reference(ref types.ImageReference, supplemental []types.ImageReference, multiple cp.ImageListSelection, instances []digest.Digest) types.ImageReference {
+ if len(instances) > 0 {
+ i := make([]digest.Digest, len(instances))
+ copy(i, instances)
+ instances = i
+ }
+ return &supplementedImageReference{
+ ImageReference: ref,
+ references: append([]types.ImageReference{}, supplemental...),
+ multiple: multiple,
+ instances: instances,
+ }
+}
+
+// NewImage returns a new higher-level view of the image.
+func (s *supplementedImageReference) NewImage(ctx context.Context, sys *types.SystemContext) (types.ImageCloser, error) {
+ src, err := s.NewImageSource(ctx, sys)
+ if err != nil {
+ return nil, errors.Wrapf(err, "error building a new Image using an ImageSource")
+ }
+ return image.FromSource(ctx, sys, src)
+}
+
+// NewImageSource opens the referenced images, scans their manifests for
+// instances, and builds mappings from each blob mentioned in them to their
+// instances.
+func (s *supplementedImageReference) NewImageSource(ctx context.Context, sys *types.SystemContext) (iss types.ImageSource, err error) {
+ sources := make(map[digest.Digest]types.ImageSource)
+ defaultInstances := make(map[types.ImageSource]digest.Digest)
+ instances := make(map[digest.Digest]digest.Digest)
+ var sis *supplementedImageSource
+
+ // Open the default instance for reading.
+ top, err := s.ImageReference.NewImageSource(ctx, sys)
+ if err != nil {
+ return nil, errors.Wrapf(err, "error opening %q as image source", transports.ImageName(s.ImageReference))
+ }
+
+ defer func() {
+ if err != nil {
+ if iss != nil {
+ // The composite source has been created. Use its Close method.
+ if err2 := iss.Close(); err2 != nil {
+ logrus.Errorf("error opening image: %v", err2)
+ }
+ } else if top != nil {
+ // The composite source has not been created, but the top was already opened. Close it.
+ if err2 := top.Close(); err2 != nil {
+ logrus.Errorf("error opening image: %v", err2)
+ }
+ }
+ }
+ }()
+
+ var addSingle, addMulti func(manifestBytes []byte, manifestType string, src types.ImageSource) error
+ type manifestToRead struct {
+ src types.ImageSource
+ instance *digest.Digest
+ }
+ manifestsToRead := list.New()
+
+ addSingle = func(manifestBytes []byte, manifestType string, src types.ImageSource) error {
+ // Mark this instance as being associated with this ImageSource.
+ manifestDigest, err := manifest.Digest(manifestBytes)
+ if err != nil {
+ return errors.Wrapf(err, "error computing digest over manifest %q", string(manifestBytes))
+ }
+ sources[manifestDigest] = src
+
+ // Parse the manifest as a single image.
+ man, err := manifest.FromBlob(manifestBytes, manifestType)
+ if err != nil {
+ return errors.Wrapf(err, "error parsing manifest %q", string(manifestBytes))
+ }
+
+ // Log the config blob's digest and the blobs of its layers as associated with this manifest.
+ config := man.ConfigInfo()
+ if config.Digest != "" {
+ instances[config.Digest] = manifestDigest
+ logrus.Debugf("blob %q belongs to %q", config.Digest, manifestDigest)
+ }
+
+ layers := man.LayerInfos()
+ for _, layer := range layers {
+ instances[layer.Digest] = manifestDigest
+ logrus.Debugf("layer %q belongs to %q", layer.Digest, manifestDigest)
+ }
+
+ return nil
+ }
+
+ addMulti = func(manifestBytes []byte, manifestType string, src types.ImageSource) error {
+ // Mark this instance as being associated with this ImageSource.
+ manifestDigest, err := manifest.Digest(manifestBytes)
+ if err != nil {
+ return errors.Wrapf(err, "error computing manifest digest")
+ }
+ sources[manifestDigest] = src
+
+ // Parse the manifest as a list of images.
+ list, err := manifest.ListFromBlob(manifestBytes, manifestType)
+ if err != nil {
+ return errors.Wrapf(err, "error parsing manifest blob %q as a %q", string(manifestBytes), manifestType)
+ }
+
+ // Figure out which of its instances we want to look at.
+ var chaseInstances []digest.Digest
+ switch s.multiple {
+ case cp.CopySystemImage:
+ instance, err := list.ChooseInstance(sys)
+ if err != nil {
+ return errors.Wrapf(err, "error selecting appropriate instance from list")
+ }
+ chaseInstances = []digest.Digest{instance}
+ case cp.CopySpecificImages:
+ chaseInstances = s.instances
+ case cp.CopyAllImages:
+ chaseInstances = list.Instances()
+ }
+
+ // Queue these manifest instances for reading from this
+ // ImageSource later, if we don't stumble across them somewhere
+ // else first.
+ for _, instanceIterator := range chaseInstances {
+ instance := instanceIterator
+ next := &manifestToRead{
+ src: src,
+ instance: &instance,
+ }
+ if src == top {
+ // Prefer any other source.
+ manifestsToRead.PushBack(next)
+ } else {
+ // Prefer this source over the first ("main") one.
+ manifestsToRead.PushFront(next)
+ }
+ }
+ return nil
+ }
+
+ visitedReferences := make(map[types.ImageReference]struct{})
+ for i, ref := range append([]types.ImageReference{s.ImageReference}, s.references...) {
+ if _, visited := visitedReferences[ref]; visited {
+ continue
+ }
+ visitedReferences[ref] = struct{}{}
+
+ // Open this image for reading.
+ var src types.ImageSource
+ if ref == s.ImageReference {
+ src = top
+ } else {
+ src, err = ref.NewImageSource(ctx, sys)
+ if err != nil {
+ return nil, errors.Wrapf(err, "error opening %q as image source", transports.ImageName(ref))
+ }
+ }
+
+ // Read the default manifest for the image.
+ manifestBytes, manifestType, err := src.GetManifest(ctx, nil)
+ if err != nil {
+ return nil, errors.Wrapf(err, "error reading default manifest from image %q", transports.ImageName(ref))
+ }
+
+ // If this is the first image, mark it as our starting point.
+ if i == 0 {
+ sources[""] = src
+
+ sis = &supplementedImageSource{
+ ImageSource: top,
+ reference: s,
+ manifest: manifestBytes,
+ manifestType: manifestType,
+ sourceDefaultInstances: defaultInstances,
+ sourceInstancesByInstance: sources,
+ instancesByBlobDigest: instances,
+ }
+ iss = sis
+ }
+
+ // Record the digest of the ImageSource's default instance's manifest.
+ manifestDigest, err := manifest.Digest(manifestBytes)
+ if err != nil {
+ return nil, errors.Wrapf(err, "error computing digest of manifest from image %q", transports.ImageName(ref))
+ }
+ sis.sourceDefaultInstances[src] = manifestDigest
+
+ // If the ImageSource's default manifest is a list, parse each of its instances.
+ if manifest.MIMETypeIsMultiImage(manifestType) {
+ if err = addMulti(manifestBytes, manifestType, src); err != nil {
+ return nil, errors.Wrapf(err, "error adding multi-image %q", transports.ImageName(ref))
+ }
+ } else {
+ if err = addSingle(manifestBytes, manifestType, src); err != nil {
+ return nil, errors.Wrapf(err, "error adding single image %q", transports.ImageName(ref))
+ }
+ }
+ }
+
+ // Parse the rest of the instances.
+ for manifestsToRead.Front() != nil {
+ front := manifestsToRead.Front()
+ value := front.Value
+ manifestToRead, ok := value.(*manifestToRead)
+ if !ok {
+ panic("bug: wrong type looking for *manifestToRead in list?")
+ }
+ manifestsToRead.Remove(front)
+
+ // If we already read this manifest, no need to read it again.
+ if _, alreadyRead := sources[*manifestToRead.instance]; alreadyRead {
+ continue
+ }
+
+ // Read the instance's manifest.
+ manifestBytes, manifestType, err := manifestToRead.src.GetManifest(ctx, manifestToRead.instance)
+ if err != nil {
+ // if errors.Cause(err) == storage.ErrImageUnknown || os.IsNotExist(errors.Cause(err)) {
+ // Trust that we either don't need it, or that it's in another reference.
+ // continue
+ // }
+ return nil, errors.Wrapf(err, "error reading manifest for instance %q", manifestToRead.instance)
+ }
+
+ if manifest.MIMETypeIsMultiImage(manifestType) {
+ // Add the list's contents.
+ if err = addMulti(manifestBytes, manifestType, manifestToRead.src); err != nil {
+ return nil, errors.Wrapf(err, "error adding single image instance %q", manifestToRead.instance)
+ }
+ } else {
+ // Add the single image's contents.
+ if err = addSingle(manifestBytes, manifestType, manifestToRead.src); err != nil {
+ return nil, errors.Wrapf(err, "error adding single image instance %q", manifestToRead.instance)
+ }
+ }
+ }
+
+ return iss, nil
+}
+
+func (s *supplementedImageReference) DeleteImage(ctx context.Context, sys *types.SystemContext) error {
+ return errors.Errorf("deletion of images not implemented")
+}
+
+func (s *supplementedImageSource) Close() error {
+ var returnErr *multierror.Error
+ closed := make(map[types.ImageSource]struct{})
+ for _, sourceInstance := range s.sourceInstancesByInstance {
+ if _, closed := closed[sourceInstance]; closed {
+ continue
+ }
+ if err := sourceInstance.Close(); err != nil {
+ returnErr = multierror.Append(returnErr, err)
+ }
+ closed[sourceInstance] = struct{}{}
+ }
+ if returnErr == nil {
+ return nil
+ }
+ return returnErr.ErrorOrNil()
+}
+
+func (s *supplementedImageSource) GetManifest(ctx context.Context, instanceDigest *digest.Digest) ([]byte, string, error) {
+ requestInstanceDigest := instanceDigest
+ if instanceDigest == nil {
+ return s.manifest, s.manifestType, nil
+ }
+ if sourceInstance, ok := s.sourceInstancesByInstance[*instanceDigest]; ok {
+ if *instanceDigest == s.sourceDefaultInstances[sourceInstance] {
+ requestInstanceDigest = nil
+ }
+ return sourceInstance.GetManifest(ctx, requestInstanceDigest)
+ }
+ return nil, "", errors.Wrapf(ErrDigestNotFound, "error getting manifest for digest %q", *instanceDigest)
+}
+
+func (s *supplementedImageSource) GetBlob(ctx context.Context, blob types.BlobInfo, bic types.BlobInfoCache) (io.ReadCloser, int64, error) {
+ sourceInstance, ok := s.instancesByBlobDigest[blob.Digest]
+ if !ok {
+ return nil, -1, errors.Wrapf(ErrBlobNotFound, "error blob %q in known instances", blob.Digest)
+ }
+ src, ok := s.sourceInstancesByInstance[sourceInstance]
+ if !ok {
+ return nil, -1, errors.Wrapf(ErrDigestNotFound, "error getting image source for instance %q", sourceInstance)
+ }
+ return src.GetBlob(ctx, blob, bic)
+}
+
+func (s *supplementedImageSource) HasThreadSafeGetBlob() bool {
+ checked := make(map[types.ImageSource]struct{})
+ for _, sourceInstance := range s.sourceInstancesByInstance {
+ if _, checked := checked[sourceInstance]; checked {
+ continue
+ }
+ if !sourceInstance.HasThreadSafeGetBlob() {
+ return false
+ }
+ checked[sourceInstance] = struct{}{}
+ }
+ return true
+}
+
+func (s *supplementedImageSource) GetSignatures(ctx context.Context, instanceDigest *digest.Digest) ([][]byte, error) {
+ var (
+ src types.ImageSource
+ digest digest.Digest
+ )
+ requestInstanceDigest := instanceDigest
+ if instanceDigest == nil {
+ if sourceInstance, ok := s.sourceInstancesByInstance[""]; ok {
+ src = sourceInstance
+ }
+ } else {
+ digest = *instanceDigest
+ if sourceInstance, ok := s.sourceInstancesByInstance[*instanceDigest]; ok {
+ src = sourceInstance
+ }
+ if *instanceDigest == s.sourceDefaultInstances[src] {
+ requestInstanceDigest = nil
+ }
+ }
+ if src != nil {
+ return src.GetSignatures(ctx, requestInstanceDigest)
+ }
+ return nil, errors.Wrapf(ErrDigestNotFound, "error finding instance for instance digest %q to read signatures", digest)
+}
+
+func (s *supplementedImageSource) LayerInfosForCopy(ctx context.Context, instanceDigest *digest.Digest) ([]types.BlobInfo, error) {
+ var src types.ImageSource
+ requestInstanceDigest := instanceDigest
+ if instanceDigest == nil {
+ if sourceInstance, ok := s.sourceInstancesByInstance[""]; ok {
+ src = sourceInstance
+ }
+ } else {
+ if sourceInstance, ok := s.sourceInstancesByInstance[*instanceDigest]; ok {
+ src = sourceInstance
+ }
+ if *instanceDigest == s.sourceDefaultInstances[src] {
+ requestInstanceDigest = nil
+ }
+ }
+ if src != nil {
+ blobInfos, err := src.LayerInfosForCopy(ctx, requestInstanceDigest)
+ if err != nil {
+ return nil, errors.Wrapf(err, "error reading layer infos for copy from instance %q", instanceDigest)
+ }
+ var manifestDigest digest.Digest
+ if instanceDigest != nil {
+ manifestDigest = *instanceDigest
+ }
+ for _, blobInfo := range blobInfos {
+ s.instancesByBlobDigest[blobInfo.Digest] = manifestDigest
+ }
+ return blobInfos, nil
+ }
+ return nil, errors.Wrapf(ErrDigestNotFound, "error finding instance for instance digest %q to copy layers", *instanceDigest)
+}
diff --git a/vendor/github.com/containers/buildah/pull.go b/vendor/github.com/containers/buildah/pull.go
index 300f3b396..cbb98cbcf 100644
--- a/vendor/github.com/containers/buildah/pull.go
+++ b/vendor/github.com/containers/buildah/pull.go
@@ -3,12 +3,11 @@ package buildah
import (
"context"
"io"
-
"strings"
+ "time"
"github.com/containers/buildah/pkg/blobcache"
"github.com/containers/buildah/util"
- cp "github.com/containers/image/v5/copy"
"github.com/containers/image/v5/directory"
"github.com/containers/image/v5/docker"
dockerarchive "github.com/containers/image/v5/docker/archive"
@@ -49,6 +48,14 @@ type PullOptions struct {
// AllTags is a boolean value that determines if all tagged images
// will be downloaded from the repository. The default is false.
AllTags bool
+ // RemoveSignatures causes any existing signatures for the image to be
+ // discarded when pulling it.
+ RemoveSignatures bool
+ // MaxRetries is the maximum number of attempts we'll make to pull any
+ // one image from the external registry if the first attempt fails.
+ MaxRetries int
+ // RetryDelay is how long to wait before retrying a pull attempt.
+ RetryDelay time.Duration
}
func localImageNameForReference(ctx context.Context, store storage.Store, srcRef types.ImageReference) (string, error) {
@@ -63,6 +70,7 @@ func localImageNameForReference(ctx context.Context, store storage.Store, srcRef
if err != nil {
return "", errors.Wrapf(err, "error opening tarfile %q as a source image", file)
}
+ defer tarSource.Close()
manifest, err := tarSource.LoadTarManifest()
if err != nil {
return "", errors.Errorf("error retrieving manifest.json from tarfile %q: %v", file, err)
@@ -154,6 +162,8 @@ func Pull(ctx context.Context, imageName string, options PullOptions) (imageID s
SystemContext: systemContext,
BlobDirectory: options.BlobDirectory,
ReportWriter: options.ReportWriter,
+ MaxPullRetries: options.MaxRetries,
+ PullRetryDelay: options.RetryDelay,
}
storageRef, transport, img, err := resolveImage(ctx, systemContext, options.Store, boptions)
@@ -206,8 +216,13 @@ func Pull(ctx context.Context, imageName string, options PullOptions) (imageID s
} else {
imageID = img.ID
}
+ if errs == nil {
+ err = nil
+ } else {
+ err = errs.ErrorOrNil()
+ }
- return imageID, errs.ErrorOrNil()
+ return imageID, err
}
func pullImage(ctx context.Context, store storage.Store, srcRef types.ImageReference, options PullOptions, sc *types.SystemContext) (types.ImageReference, error) {
@@ -260,7 +275,7 @@ func pullImage(ctx context.Context, store storage.Store, srcRef types.ImageRefer
}()
logrus.Debugf("copying %q to %q", transports.ImageName(srcRef), destName)
- if _, err := cp.Image(ctx, policyContext, maybeCachedDestRef, srcRef, getCopyOptions(store, options.ReportWriter, sc, nil, "")); err != nil {
+ if _, err := retryCopyImage(ctx, policyContext, maybeCachedDestRef, srcRef, srcRef, "pull", getCopyOptions(store, options.ReportWriter, sc, nil, "", options.RemoveSignatures, ""), options.MaxRetries, options.RetryDelay); err != nil {
logrus.Debugf("error copying src image [%q] to dest image [%q] err: %v", transports.ImageName(srcRef), destName, err)
return nil, err
}
diff --git a/vendor/github.com/containers/buildah/run_linux.go b/vendor/github.com/containers/buildah/run_linux.go
index e7994e388..6e4d31d78 100644
--- a/vendor/github.com/containers/buildah/run_linux.go
+++ b/vendor/github.com/containers/buildah/run_linux.go
@@ -26,6 +26,8 @@ import (
"github.com/containers/buildah/pkg/overlay"
"github.com/containers/buildah/pkg/secrets"
"github.com/containers/buildah/util"
+ "github.com/containers/common/pkg/capabilities"
+ "github.com/containers/common/pkg/config"
"github.com/containers/common/pkg/unshare"
"github.com/containers/storage/pkg/idtools"
"github.com/containers/storage/pkg/ioutils"
@@ -89,7 +91,11 @@ func (b *Builder) Run(command []string, options RunOptions) error {
return err
}
- b.configureEnvironment(g, options)
+ defaultContainerConfig, err := config.Default()
+ if err != nil {
+ return errors.Wrapf(err, "failed to get container config")
+ }
+ b.configureEnvironment(g, options, defaultContainerConfig.Containers.Env)
if b.CommonBuildOpts == nil {
return errors.Errorf("Invalid format on container you must recreate the container")
@@ -291,8 +297,12 @@ func addCommonOptsToSpec(commonOpts *CommonBuildOptions, g *generate.Generator)
g.SetLinuxCgroupsPath(commonOpts.CgroupParent)
}
+ defaultContainerConfig, err := config.Default()
+ if err != nil {
+ return errors.Wrapf(err, "failed to get container config")
+ }
// Other process resource limits
- if err := addRlimits(commonOpts.Ulimit, g); err != nil {
+ if err := addRlimits(commonOpts.Ulimit, g, defaultContainerConfig.Containers.DefaultUlimits); err != nil {
return err
}
@@ -506,6 +516,11 @@ func (b *Builder) addNetworkConfig(rdir, hostPath string, chownOpts *idtools.IDP
nameservers := resolvconf.GetNameservers(contents, types.IP)
options := resolvconf.GetOptions(contents)
+ defaultContainerConfig, err := config.Default()
+ if err != nil {
+ return "", errors.Wrapf(err, "failed to get container config")
+ }
+ dnsSearch = append(defaultContainerConfig.Containers.DNSSearches, dnsSearch...)
if len(dnsSearch) > 0 {
search = dnsSearch
}
@@ -519,6 +534,7 @@ func (b *Builder) addNetworkConfig(rdir, hostPath string, chownOpts *idtools.IDP
}
}
+ dnsServers = append(defaultContainerConfig.Containers.DNSServers, dnsServers...)
if len(dnsServers) != 0 {
dns, err := getDNSIP(dnsServers)
if err != nil {
@@ -530,6 +546,7 @@ func (b *Builder) addNetworkConfig(rdir, hostPath string, chownOpts *idtools.IDP
}
}
+ dnsOptions = append(defaultContainerConfig.Containers.DNSOptions, dnsOptions...)
if len(dnsOptions) != 0 {
options = dnsOptions
}
@@ -661,6 +678,11 @@ func runUsingRuntime(isolation Isolation, options RunOptions, configureNetwork b
runtime := options.Runtime
if runtime == "" {
runtime = util.Runtime()
+
+ localRuntime := util.FindLocalRuntime(runtime)
+ if localRuntime != "" {
+ runtime = localRuntime
+ }
}
// Default to just passing down our stdio.
@@ -680,7 +702,9 @@ func runUsingRuntime(isolation Isolation, options RunOptions, configureNetwork b
return 1, errors.Wrapf(err, "error creating pipe for notifying to stop stdio")
}
finishedCopy := make(chan struct{})
+ var pargs []string
if spec.Process != nil {
+ pargs = spec.Process.Args
if spec.Process.Terminal {
copyConsole = true
// Create a listening socket for accepting the container's terminal's PTY master.
@@ -751,7 +775,7 @@ func runUsingRuntime(isolation Isolation, options RunOptions, configureNetwork b
logrus.Debugf("Running %q", create.Args)
err = create.Run()
if err != nil {
- return 1, errors.Wrapf(err, "error creating container for %v: %s", spec.Process.Args, runCollectOutput(errorFds, closeBeforeReadingErrorFds))
+ return 1, errors.Wrapf(err, "error creating container for %v: %s", pargs, runCollectOutput(errorFds, closeBeforeReadingErrorFds))
}
defer func() {
err2 := del.Run()
@@ -786,7 +810,7 @@ func runUsingRuntime(isolation Isolation, options RunOptions, configureNetwork b
}()
if configureNetwork {
- teardown, err := runConfigureNetwork(isolation, options, configureNetworks, pid, containerName, spec.Process.Args)
+ teardown, err := runConfigureNetwork(isolation, options, configureNetworks, pid, containerName, pargs)
if teardown != nil {
defer teardown()
}
@@ -1022,6 +1046,9 @@ func runConfigureNetwork(isolation Isolation, options RunOptions, configureNetwo
}
continue
}
+ if nc.Network == nil {
+ continue
+ }
cl, err := libcni.ConfListFromConf(nc)
if err != nil {
return nil, errors.Wrapf(err, "error converting networking configuration from file %q for %v", file, command)
@@ -1181,6 +1208,13 @@ func runCopyStdio(stdio *sync.WaitGroup, copyPipes bool, stdioPipe [][]int, copy
runCopyStdioPassData(copyPipes, stdioPipe, finishCopy, relayMap, relayBuffer, readDesc, writeDesc)
}
+func canRetry(err error) bool {
+ if errno, isErrno := err.(syscall.Errno); isErrno {
+ return errno == syscall.EINTR || errno == syscall.EAGAIN
+ }
+ return false
+}
+
func runCopyStdioPassData(copyPipes bool, stdioPipe [][]int, finishCopy []int, relayMap map[int]int, relayBuffer map[int]*bytes.Buffer, readDesc map[int]string, writeDesc map[int]string) {
closeStdin := false
@@ -1228,7 +1262,7 @@ func runCopyStdioPassData(copyPipes bool, stdioPipe [][]int, finishCopy []int, r
// If it's zero-length on our stdin and we're
// using pipes, it's an EOF, so close the stdin
// pipe's writing end.
- if n == 0 && copyPipes && int(pollFd.Fd) == unix.Stdin {
+ if n == 0 && !canRetry(err) && int(pollFd.Fd) == unix.Stdin {
removes[int(pollFd.Fd)] = struct{}{}
} else if n > 0 {
// Buffer the data in case we get blocked on where they need to go.
@@ -1421,8 +1455,13 @@ func runUsingRuntimeMain() {
if err := setChildProcess(); err != nil {
os.Exit(1)
}
+ var ospec *specs.Spec
+ if options.Spec != nil {
+ ospec = options.Spec
+ }
+
// Run the container, start to finish.
- status, err := runUsingRuntime(options.Isolation, options.Options, options.ConfigureNetwork, options.ConfigureNetworks, options.MoreCreateArgs, options.Spec, options.BundlePath, options.ContainerName)
+ status, err := runUsingRuntime(options.Isolation, options.Options, options.ConfigureNetwork, options.ConfigureNetworks, options.MoreCreateArgs, ospec, options.BundlePath, options.ContainerName)
if err != nil {
fmt.Fprintf(os.Stderr, "error running container: %v\n", err)
os.Exit(1)
@@ -1599,12 +1638,13 @@ func runSetupBoundFiles(bundlePath string, bindFiles map[string]string) (mounts
return mounts
}
-func addRlimits(ulimit []string, g *generate.Generator) error {
+func addRlimits(ulimit []string, g *generate.Generator, defaultUlimits []string) error {
var (
ul *units.Ulimit
err error
)
+ ulimit = append(defaultUlimits, ulimit...)
for _, u := range ulimit {
if ul, err = units.ParseUlimit(u); err != nil {
return errors.Wrapf(err, "ulimit option %q requires name=SOFT:HARD, failed to be parsed", u)
@@ -1799,21 +1839,27 @@ func setupCapDrop(g *generate.Generator, caps ...string) error {
return nil
}
-func setupCapabilities(g *generate.Generator, firstAdds, firstDrops, secondAdds, secondDrops []string) error {
+func setupCapabilities(g *generate.Generator, defaultCapabilities, adds, drops []string) error {
g.ClearProcessCapabilities()
- if err := setupCapAdd(g, util.DefaultCapabilities...); err != nil {
+ if err := setupCapAdd(g, defaultCapabilities...); err != nil {
return err
}
- if err := setupCapAdd(g, firstAdds...); err != nil {
- return err
+ for _, c := range adds {
+ if strings.ToLower(c) == "all" {
+ adds = capabilities.AllCapabilities()
+ break
+ }
}
- if err := setupCapDrop(g, firstDrops...); err != nil {
- return err
+ for _, c := range drops {
+ if strings.ToLower(c) == "all" {
+ g.ClearProcessCapabilities()
+ return nil
+ }
}
- if err := setupCapAdd(g, secondAdds...); err != nil {
+ if err := setupCapAdd(g, adds...); err != nil {
return err
}
- return setupCapDrop(g, secondDrops...)
+ return setupCapDrop(g, drops...)
}
// Search for a command that isn't given as an absolute path using the $PATH
@@ -1880,7 +1926,7 @@ func (b *Builder) configureUIDGID(g *generate.Generator, mountPoint string, opti
if err != nil {
return "", err
}
- if err := setupCapabilities(g, b.AddCapabilities, b.DropCapabilities, options.AddCapabilities, options.DropCapabilities); err != nil {
+ if err := setupCapabilities(g, b.Capabilities, options.AddCapabilities, options.DropCapabilities); err != nil {
return "", err
}
g.SetProcessUID(user.UID)
@@ -1899,8 +1945,9 @@ func (b *Builder) configureUIDGID(g *generate.Generator, mountPoint string, opti
return homeDir, nil
}
-func (b *Builder) configureEnvironment(g *generate.Generator, options RunOptions) {
+func (b *Builder) configureEnvironment(g *generate.Generator, options RunOptions, defaultEnv []string) {
g.ClearProcessEnv()
+
if b.CommonBuildOpts.HTTPProxy {
for _, envSpec := range []string{
"http_proxy",
@@ -1919,7 +1966,7 @@ func (b *Builder) configureEnvironment(g *generate.Generator, options RunOptions
}
}
- for _, envSpec := range append(b.Env(), options.Env...) {
+ for _, envSpec := range append(append(defaultEnv, b.Env()...), options.Env...) {
env := strings.SplitN(envSpec, "=", 2)
if len(env) > 1 {
g.AddProcessEnv(env[0], env[1])
diff --git a/vendor/github.com/containers/buildah/util/util.go b/vendor/github.com/containers/buildah/util/util.go
index 617af7b32..a358b7c54 100644
--- a/vendor/github.com/containers/buildah/util/util.go
+++ b/vendor/github.com/containers/buildah/util/util.go
@@ -7,14 +7,16 @@ import (
"os"
"path"
"strings"
+ "sync"
"syscall"
- "github.com/containers/common/pkg/cgroups"
+ "github.com/containers/common/pkg/config"
"github.com/containers/image/v5/docker/reference"
"github.com/containers/image/v5/pkg/sysregistriesv2"
"github.com/containers/image/v5/signature"
is "github.com/containers/image/v5/storage"
"github.com/containers/image/v5/transports"
+ "github.com/containers/image/v5/transports/alltransports"
"github.com/containers/image/v5/types"
"github.com/containers/storage"
"github.com/docker/distribution/registry/api/errcode"
@@ -209,6 +211,36 @@ func FindImage(store storage.Store, firstRegistry string, systemContext *types.S
return ref, img, nil
}
+// ResolveNameToReferences tries to create a list of possible references
+// (including their transports) from the provided image name.
+func ResolveNameToReferences(
+ store storage.Store,
+ systemContext *types.SystemContext,
+ image string,
+) (refs []types.ImageReference, err error) {
+ names, transport, _, err := ResolveName(image, "", systemContext, store)
+ if err != nil {
+ return nil, errors.Wrapf(err, "error parsing name %q", image)
+ }
+
+ if transport != DefaultTransport {
+ transport += ":"
+ }
+
+ for _, name := range names {
+ ref, err := alltransports.ParseImageName(transport + name)
+ if err != nil {
+ logrus.Debugf("error parsing reference to image %q: %v", name, err)
+ continue
+ }
+ refs = append(refs, ref)
+ }
+ if len(refs) == 0 {
+ return nil, errors.Errorf("error locating images with names %v", names)
+ }
+ return refs, nil
+}
+
// AddImageNames adds the specified names to the specified image.
func AddImageNames(store storage.Store, firstRegistry string, systemContext *types.SystemContext, image *storage.Image, addNames []string) error {
names, err := ExpandNames(addNames, firstRegistry, systemContext, store)
@@ -252,7 +284,7 @@ func Runtime() string {
}
// Need to switch default until runc supports cgroups v2
- if unified, _ := cgroups.IsCgroup2UnifiedMode(); unified {
+ if unified, _ := IsCgroup2UnifiedMode(); unified {
return "crun"
}
@@ -333,7 +365,7 @@ func GetHostIDs(uidmap, gidmap []specs.LinuxIDMapping, uid, gid uint32) (uint32,
// GetHostRootIDs uses ID mappings in spec to compute the host-level IDs that will
// correspond to UID/GID 0/0 in the container.
func GetHostRootIDs(spec *specs.Spec) (uint32, uint32, error) {
- if spec.Linux == nil {
+ if spec == nil || spec.Linux == nil {
return 0, 0, nil
}
return GetHostIDs(spec.Linux.UIDMappings, spec.Linux.GIDMappings, 0, 0)
@@ -395,3 +427,39 @@ func TruncateString(str string, to int) string {
}
return newStr
}
+
+var (
+ isUnifiedOnce sync.Once
+ isUnified bool
+ isUnifiedErr error
+)
+
+// fileExistsAndNotADir - Check to see if a file exists
+// and that it is not a directory.
+func fileExistsAndNotADir(path string) bool {
+ file, err := os.Stat(path)
+
+ if file == nil || err != nil || os.IsNotExist(err) {
+ return false
+ }
+ return !file.IsDir()
+}
+
+// FindLocalRuntime find the local runtime of the
+// system searching through the config file for
+// possible locations.
+func FindLocalRuntime(runtime string) string {
+ var localRuntime string
+ conf, err := config.Default()
+ if err != nil {
+ logrus.Debugf("Error loading container config when searching for local runtime.")
+ return localRuntime
+ }
+ for _, val := range conf.Engine.OCIRuntimes[runtime] {
+ if fileExistsAndNotADir(val) {
+ localRuntime = val
+ break
+ }
+ }
+ return localRuntime
+}
diff --git a/vendor/github.com/containers/buildah/util/util_linux.go b/vendor/github.com/containers/buildah/util/util_linux.go
new file mode 100644
index 000000000..1a13699df
--- /dev/null
+++ b/vendor/github.com/containers/buildah/util/util_linux.go
@@ -0,0 +1,29 @@
+package util
+
+import (
+ "os"
+ "syscall"
+
+ "golang.org/x/sys/unix"
+)
+
+// IsCgroup2UnifiedMode returns whether we are running in cgroup 2 cgroup2 mode.
+func IsCgroup2UnifiedMode() (bool, error) {
+ isUnifiedOnce.Do(func() {
+ var st syscall.Statfs_t
+ if err := syscall.Statfs("/sys/fs/cgroup", &st); err != nil {
+ isUnified, isUnifiedErr = false, err
+ } else {
+ isUnified, isUnifiedErr = st.Type == unix.CGROUP2_SUPER_MAGIC, nil
+ }
+ })
+ return isUnified, isUnifiedErr
+}
+
+func UID(st os.FileInfo) int {
+ return int(st.Sys().(*syscall.Stat_t).Uid)
+}
+
+func GID(st os.FileInfo) int {
+ return int(st.Sys().(*syscall.Stat_t).Gid)
+}
diff --git a/vendor/github.com/containers/buildah/util/util_unsupported.go b/vendor/github.com/containers/buildah/util/util_unsupported.go
new file mode 100644
index 000000000..8810536a6
--- /dev/null
+++ b/vendor/github.com/containers/buildah/util/util_unsupported.go
@@ -0,0 +1,20 @@
+// +build !linux
+
+package util
+
+import (
+ "os"
+)
+
+// IsCgroup2UnifiedMode returns whether we are running in cgroup 2 cgroup2 mode.
+func IsCgroup2UnifiedMode() (bool, error) {
+ return false, nil
+}
+
+func UID(st os.FileInfo) int {
+ return 0
+}
+
+func GID(st os.FileInfo) int {
+ return 0
+}
diff --git a/vendor/github.com/containers/common/pkg/capabilities/capabilities.go b/vendor/github.com/containers/common/pkg/capabilities/capabilities.go
new file mode 100644
index 000000000..a57c048bc
--- /dev/null
+++ b/vendor/github.com/containers/common/pkg/capabilities/capabilities.go
@@ -0,0 +1,142 @@
+package capabilities
+
+// Copyright 2013-2018 Docker, Inc.
+
+// NOTE: this package has been copied from github.com/docker/docker but been
+// changed significantly to fit the needs of libpod.
+
+import (
+ "strings"
+
+ "github.com/pkg/errors"
+ "github.com/syndtr/gocapability/capability"
+)
+
+var (
+ // Used internally and populated during init().
+ capabilityList []string
+
+ // ErrUnknownCapability is thrown when an unknown capability is processed.
+ ErrUnknownCapability = errors.New("unknown capability")
+
+ // ContainerImageLabels - label can indicate the required
+ // capabilities required by containers to run the container image.
+ ContainerImageLabels = []string{"io.containers.capabilities"}
+)
+
+// All is a special value used to add/drop all known capababilities.
+// Useful on the CLI for `--cap-add=all` etc.
+const All = "ALL"
+
+func init() {
+ last := capability.CAP_LAST_CAP
+ // hack for RHEL6 which has no /proc/sys/kernel/cap_last_cap
+ if last == capability.Cap(63) {
+ last = capability.CAP_BLOCK_SUSPEND
+ }
+ for _, cap := range capability.List() {
+ if cap > last {
+ continue
+ }
+ capabilityList = append(capabilityList, "CAP_"+strings.ToUpper(cap.String()))
+ }
+}
+
+// stringInSlice determines if a string is in a string slice, returns bool
+func stringInSlice(s string, sl []string) bool {
+ for _, i := range sl {
+ if i == s {
+ return true
+ }
+ }
+ return false
+}
+
+// AllCapabilities returns all known capabilities.
+func AllCapabilities() []string {
+ return capabilityList
+}
+
+// normalizeCapabilities normalizes caps by adding a "CAP_" prefix (if not yet
+// present).
+func normalizeCapabilities(caps []string) ([]string, error) {
+ normalized := make([]string, len(caps))
+ for i, c := range caps {
+ c = strings.ToUpper(c)
+ if c == All {
+ normalized = append(normalized, c)
+ continue
+ }
+ if !strings.HasPrefix(c, "CAP_") {
+ c = "CAP_" + c
+ }
+ if !stringInSlice(c, capabilityList) {
+ return nil, errors.Wrapf(ErrUnknownCapability, "%q", c)
+ }
+ normalized[i] = c
+ }
+ return normalized, nil
+}
+
+// ValidateCapabilities validates if caps only contains valid capabilities.
+func ValidateCapabilities(caps []string) error {
+ for _, c := range caps {
+ if !stringInSlice(c, capabilityList) {
+ return errors.Wrapf(ErrUnknownCapability, "%q", c)
+ }
+ }
+ return nil
+}
+
+// MergeCapabilities computes a set of capabilities by adding capapbitilities
+// to or dropping them from base.
+//
+// Note that "ALL" will cause all known capabilities to be added/dropped but
+// the ones specified to be dropped/added.
+func MergeCapabilities(base, adds, drops []string) ([]string, error) {
+ if len(adds) == 0 && len(drops) == 0 {
+ // Nothing to tweak; we're done
+ return base, nil
+ }
+
+ capDrop, err := normalizeCapabilities(drops)
+ if err != nil {
+ return nil, err
+ }
+ capAdd, err := normalizeCapabilities(adds)
+ if err != nil {
+ return nil, err
+ }
+
+ // Make sure that capDrop and capAdd are distinct sets.
+ for _, drop := range capDrop {
+ if stringInSlice(drop, capAdd) {
+ return nil, errors.Errorf("capability %q cannot be dropped and added", drop)
+ }
+ }
+
+ var caps []string
+
+ switch {
+ case stringInSlice(All, capAdd):
+ // Add all capabilities except ones on capDrop
+ for _, c := range capabilityList {
+ if !stringInSlice(c, capDrop) {
+ caps = append(caps, c)
+ }
+ }
+ case stringInSlice(All, capDrop):
+ // "Drop" all capabilities; use what's in capAdd instead
+ caps = capAdd
+ default:
+ // First drop some capabilities
+ for _, c := range base {
+ if !stringInSlice(c, capDrop) {
+ caps = append(caps, c)
+ }
+ }
+ // Then add the list of capabilities from capAdd
+ caps = append(caps, capAdd...)
+ }
+ return caps, nil
+}
diff --git a/vendor/github.com/containers/common/pkg/cgroups/blkio.go b/vendor/github.com/containers/common/pkg/cgroups/blkio.go
deleted file mode 100644
index bacd4eb93..000000000
--- a/vendor/github.com/containers/common/pkg/cgroups/blkio.go
+++ /dev/null
@@ -1,149 +0,0 @@
-package cgroups
-
-import (
- "bufio"
- "fmt"
- "os"
- "path/filepath"
- "strconv"
- "strings"
-
- spec "github.com/opencontainers/runtime-spec/specs-go"
- "github.com/pkg/errors"
-)
-
-type blkioHandler struct {
-}
-
-func getBlkioHandler() *blkioHandler {
- return &blkioHandler{}
-}
-
-// Apply set the specified constraints
-func (c *blkioHandler) Apply(ctr *CgroupControl, res *spec.LinuxResources) error {
- if res.BlockIO == nil {
- return nil
- }
- return fmt.Errorf("blkio apply function not implemented yet")
-}
-
-// Create the cgroup
-func (c *blkioHandler) Create(ctr *CgroupControl) (bool, error) {
- if ctr.cgroup2 {
- return false, nil
- }
- return ctr.createCgroupDirectory(Blkio)
-}
-
-// Destroy the cgroup
-func (c *blkioHandler) Destroy(ctr *CgroupControl) error {
- return rmDirRecursively(ctr.getCgroupv1Path(Blkio))
-}
-
-// Stat fills a metrics structure with usage stats for the controller
-func (c *blkioHandler) Stat(ctr *CgroupControl, m *Metrics) error {
- var ioServiceBytesRecursive []BlkIOEntry
-
- if ctr.cgroup2 {
- // more details on the io.stat file format:X https://facebookmicrosites.github.io/cgroup2/docs/io-controller.html
- values, err := readCgroup2MapFile(ctr, "io.stat")
- if err != nil {
- return err
- }
- for k, v := range values {
- d := strings.Split(k, ":")
- if len(d) != 2 {
- continue
- }
- minor, err := strconv.ParseUint(d[0], 10, 0)
- if err != nil {
- return err
- }
- major, err := strconv.ParseUint(d[1], 10, 0)
- if err != nil {
- return err
- }
-
- for _, item := range v {
- d := strings.Split(item, "=")
- if len(d) != 2 {
- continue
- }
- op := d[0]
-
- // Accommodate the cgroup v1 naming
- switch op {
- case "rbytes":
- op = "read"
- case "wbytes":
- op = "write"
- }
-
- value, err := strconv.ParseUint(d[1], 10, 0)
- if err != nil {
- return err
- }
-
- entry := BlkIOEntry{
- Op: op,
- Major: major,
- Minor: minor,
- Value: value,
- }
- ioServiceBytesRecursive = append(ioServiceBytesRecursive, entry)
- }
- }
- } else {
- BlkioRoot := ctr.getCgroupv1Path(Blkio)
-
- p := filepath.Join(BlkioRoot, "blkio.throttle.io_service_bytes_recursive")
- f, err := os.Open(p)
- if err != nil {
- if os.IsNotExist(err) {
- return nil
- }
- return errors.Wrapf(err, "open %s", p)
- }
- defer f.Close()
-
- scanner := bufio.NewScanner(f)
- for scanner.Scan() {
- line := scanner.Text()
- parts := strings.Fields(line)
- if len(parts) < 3 {
- continue
- }
- d := strings.Split(parts[0], ":")
- if len(d) != 2 {
- continue
- }
- minor, err := strconv.ParseUint(d[0], 10, 0)
- if err != nil {
- return err
- }
- major, err := strconv.ParseUint(d[1], 10, 0)
- if err != nil {
- return err
- }
-
- op := parts[1]
-
- value, err := strconv.ParseUint(parts[2], 10, 0)
- if err != nil {
- return err
- }
- entry := BlkIOEntry{
- Op: op,
- Major: major,
- Minor: minor,
- Value: value,
- }
- ioServiceBytesRecursive = append(ioServiceBytesRecursive, entry)
- }
- if err := scanner.Err(); err != nil {
- return errors.Wrapf(err, "parse %s", p)
- }
- }
- m.Blkio = BlkioMetrics{IoServiceBytesRecursive: ioServiceBytesRecursive}
- return nil
-}
diff --git a/vendor/github.com/containers/common/pkg/cgroups/cgroups.go b/vendor/github.com/containers/common/pkg/cgroups/cgroups.go
deleted file mode 100644
index f8a9022f4..000000000
--- a/vendor/github.com/containers/common/pkg/cgroups/cgroups.go
+++ /dev/null
@@ -1,564 +0,0 @@
-package cgroups
-
-import (
- "bufio"
- "fmt"
- "io/ioutil"
- "math"
- "os"
- "path/filepath"
- "strconv"
- "strings"
-
- "github.com/containers/common/pkg/unshare"
- systemdDbus "github.com/coreos/go-systemd/dbus"
- "github.com/godbus/dbus"
- spec "github.com/opencontainers/runtime-spec/specs-go"
- "github.com/pkg/errors"
- "github.com/sirupsen/logrus"
-)
-
-var (
- // ErrCgroupDeleted means the cgroup was deleted
- ErrCgroupDeleted = errors.New("cgroup deleted")
- // ErrCgroupV1Rootless means the cgroup v1 were attempted to be used in rootless environmen
- ErrCgroupV1Rootless = errors.New("no support for CGroups V1 in rootless environments")
-)
-
-// CgroupControl controls a cgroup hierarchy
-type CgroupControl struct {
- cgroup2 bool
- path string
- systemd bool
- // List of additional cgroup subsystems joined that
- // do not have a custom handler.
- additionalControllers []controller
-}
-
-// CPUUsage keeps stats for the CPU usage (unit: nanoseconds)
-type CPUUsage struct {
- Kernel uint64
- Total uint64
- PerCPU []uint64
-}
-
-// MemoryUsage keeps stats for the memory usage
-type MemoryUsage struct {
- Usage uint64
- Limit uint64
-}
-
-// CPUMetrics keeps stats for the CPU usage
-type CPUMetrics struct {
- Usage CPUUsage
-}
-
-// BlkIOEntry describes an entry in the blkio stats
-type BlkIOEntry struct {
- Op string
- Major uint64
- Minor uint64
- Value uint64
-}
-
-// BlkioMetrics keeps usage stats for the blkio cgroup controller
-type BlkioMetrics struct {
- IoServiceBytesRecursive []BlkIOEntry
-}
-
-// MemoryMetrics keeps usage stats for the memory cgroup controller
-type MemoryMetrics struct {
- Usage MemoryUsage
-}
-
-// PidsMetrics keeps usage stats for the pids cgroup controller
-type PidsMetrics struct {
- Current uint64
-}
-
-// Metrics keeps usage stats for the cgroup controllers
-type Metrics struct {
- CPU CPUMetrics
- Blkio BlkioMetrics
- Memory MemoryMetrics
- Pids PidsMetrics
-}
-
-type controller struct {
- name string
- symlink bool
-}
-
-type controllerHandler interface {
- Create(*CgroupControl) (bool, error)
- Apply(*CgroupControl, *spec.LinuxResources) error
- Destroy(*CgroupControl) error
- Stat(*CgroupControl, *Metrics) error
-}
-
-const (
- cgroupRoot = "/sys/fs/cgroup"
- _cgroup2SuperMagic = 0x63677270
- // CPU is the cpu controller
- CPU = "cpu"
- // CPUAcct is the cpuacct controller
- CPUAcct = "cpuacct"
- // CPUset is the cpuset controller
- CPUset = "cpuset"
- // Memory is the memory controller
- Memory = "memory"
- // Pids is the pids controller
- Pids = "pids"
- // Blkio is the blkio controller
- Blkio = "blkio"
-)
-
-var handlers map[string]controllerHandler
-
-func init() {
- handlers = make(map[string]controllerHandler)
- handlers[CPU] = getCPUHandler()
- handlers[CPUset] = getCpusetHandler()
- handlers[Memory] = getMemoryHandler()
- handlers[Pids] = getPidsHandler()
- handlers[Blkio] = getBlkioHandler()
-}
-
-// getAvailableControllers get the available controllers
-func getAvailableControllers(exclude map[string]controllerHandler, cgroup2 bool) ([]controller, error) {
- if cgroup2 {
- return nil, fmt.Errorf("getAvailableControllers not implemented yet for cgroup v2")
- }
-
- infos, err := ioutil.ReadDir(cgroupRoot)
- if err != nil {
- return nil, errors.Wrapf(err, "read directory %s", cgroupRoot)
- }
- var controllers []controller
- for _, i := range infos {
- name := i.Name()
- if _, found := exclude[name]; found {
- continue
- }
- c := controller{
- name: name,
- symlink: !i.IsDir(),
- }
- controllers = append(controllers, c)
- }
- return controllers, nil
-}
-
-// getCgroupv1Path is a helper function to get the cgroup v1 path
-func (c *CgroupControl) getCgroupv1Path(name string) string {
- return filepath.Join(cgroupRoot, name, c.path)
-}
-
-// createCgroupv2Path creates the cgroupv2 path and enables all the available controllers
-func createCgroupv2Path(path string) (Err error) {
- content, err := ioutil.ReadFile("/sys/fs/cgroup/cgroup.controllers")
- if err != nil {
- return errors.Wrapf(err, "read /sys/fs/cgroup/cgroup.controllers")
- }
- if !strings.HasPrefix(path, "/sys/fs/cgroup/") {
- return fmt.Errorf("invalid cgroup path %s", path)
- }
-
- res := ""
- for i, c := range strings.Split(strings.TrimSpace(string(content)), " ") {
- if i == 0 {
- res = fmt.Sprintf("+%s", c)
- } else {
- res = res + fmt.Sprintf(" +%s", c)
- }
- }
- resByte := []byte(res)
-
- current := "/sys/fs"
- elements := strings.Split(path, "/")
- for i, e := range elements[3:] {
- current = filepath.Join(current, e)
- if i > 0 {
- if err := os.Mkdir(current, 0755); err != nil {
- if !os.IsExist(err) {
- return errors.Wrapf(err, "mkdir %s", path)
- }
- } else {
- // If the directory was created, be sure it is not left around on errors.
- defer func() {
- if Err != nil {
- os.Remove(current)
- }
- }()
- }
- }
- // We enable the controllers for all the path components except the last one. It is not allowed to add
- // PIDs if there are already enabled controllers.
- if i < len(elements[3:])-1 {
- if err := ioutil.WriteFile(filepath.Join(current, "cgroup.subtree_control"), resByte, 0755); err != nil {
- return errors.Wrapf(err, "write %s", filepath.Join(current, "cgroup.subtree_control"))
- }
- }
- }
- return nil
-}
-
-// initialize initializes the specified hierarchy
-func (c *CgroupControl) initialize() (err error) {
- createdSoFar := map[string]controllerHandler{}
- defer func() {
- if err != nil {
- for name, ctr := range createdSoFar {
- if err := ctr.Destroy(c); err != nil {
- logrus.Warningf("error cleaning up controller %s for %s", name, c.path)
- }
- }
- }
- }()
- if c.cgroup2 {
- if err := createCgroupv2Path(filepath.Join(cgroupRoot, c.path)); err != nil {
- return errors.Wrapf(err, "error creating cgroup path %s", c.path)
- }
- }
- for name, handler := range handlers {
- created, err := handler.Create(c)
- if err != nil {
- return err
- }
- if created {
- createdSoFar[name] = handler
- }
- }
-
- if !c.cgroup2 {
- // We won't need to do this for cgroup v2
- for _, ctr := range c.additionalControllers {
- if ctr.symlink {
- continue
- }
- path := c.getCgroupv1Path(ctr.name)
- if err := os.MkdirAll(path, 0755); err != nil {
- return errors.Wrapf(err, "error creating cgroup path %s for %s", path, ctr.name)
- }
- }
- }
-
- return nil
-}
-
-func (c *CgroupControl) createCgroupDirectory(controller string) (bool, error) {
- cPath := c.getCgroupv1Path(controller)
- _, err := os.Stat(cPath)
- if err == nil {
- return false, nil
- }
-
- if !os.IsNotExist(err) {
- return false, err
- }
-
- if err := os.MkdirAll(cPath, 0755); err != nil {
- return false, errors.Wrapf(err, "error creating cgroup for %s", controller)
- }
- return true, nil
-}
-
-func readFileAsUint64(path string) (uint64, error) {
- data, err := ioutil.ReadFile(path)
- if err != nil {
- return 0, errors.Wrapf(err, "open %s", path)
- }
- v := cleanString(string(data))
- if v == "max" {
- return math.MaxUint64, nil
- }
- ret, err := strconv.ParseUint(v, 10, 0)
- if err != nil {
- return ret, errors.Wrapf(err, "parse %s from %s", v, path)
- }
- return ret, nil
-}
-
-// New creates a new cgroup control
-func New(path string, resources *spec.LinuxResources) (*CgroupControl, error) {
- cgroup2, err := IsCgroup2UnifiedMode()
- if err != nil {
- return nil, err
- }
- control := &CgroupControl{
- cgroup2: cgroup2,
- path: path,
- }
-
- if !cgroup2 {
- controllers, err := getAvailableControllers(handlers, false)
- if err != nil {
- return nil, err
- }
- control.additionalControllers = controllers
- }
-
- if err := control.initialize(); err != nil {
- return nil, err
- }
-
- return control, nil
-}
-
-// NewSystemd creates a new cgroup control
-func NewSystemd(path string) (*CgroupControl, error) {
- cgroup2, err := IsCgroup2UnifiedMode()
- if err != nil {
- return nil, err
- }
- control := &CgroupControl{
- cgroup2: cgroup2,
- path: path,
- systemd: true,
- }
- return control, nil
-}
-
-// Load loads an existing cgroup control
-func Load(path string) (*CgroupControl, error) {
- cgroup2, err := IsCgroup2UnifiedMode()
- if err != nil {
- return nil, err
- }
- control := &CgroupControl{
- cgroup2: cgroup2,
- path: path,
- systemd: false,
- }
- if !cgroup2 {
- controllers, err := getAvailableControllers(handlers, false)
- if err != nil {
- return nil, err
- }
- control.additionalControllers = controllers
- }
- if !cgroup2 {
- for name := range handlers {
- p := control.getCgroupv1Path(name)
- if _, err := os.Stat(p); err != nil {
- if os.IsNotExist(err) {
- if unshare.IsRootless() {
- return nil, ErrCgroupV1Rootless
- }
- // compatible with the error code
- // used by containerd/cgroups
- return nil, ErrCgroupDeleted
- }
- }
- }
- }
- return control, nil
-}
-
-// CreateSystemdUnit creates the systemd cgroup
-func (c *CgroupControl) CreateSystemdUnit(path string) error {
- if !c.systemd {
- return fmt.Errorf("the cgroup controller is not using systemd")
- }
-
- conn, err := systemdDbus.New()
- if err != nil {
- return err
- }
- defer conn.Close()
-
- return systemdCreate(path, conn)
-}
-
-// GetUserConnection returns an user connection to D-BUS
-func GetUserConnection(uid int) (*systemdDbus.Conn, error) {
- return systemdDbus.NewConnection(func() (*dbus.Conn, error) {
- return dbusAuthConnection(uid, dbus.SessionBusPrivate)
- })
-}
-
-// CreateSystemdUserUnit creates the systemd cgroup for the specified user
-func (c *CgroupControl) CreateSystemdUserUnit(path string, uid int) error {
- if !c.systemd {
- return fmt.Errorf("the cgroup controller is not using systemd")
- }
-
- conn, err := GetUserConnection(uid)
- if err != nil {
- return err
- }
- defer conn.Close()
-
- return systemdCreate(path, conn)
-}
-
-func dbusAuthConnection(uid int, createBus func(opts ...dbus.ConnOption) (*dbus.Conn, error)) (*dbus.Conn, error) {
- conn, err := createBus()
- if err != nil {
- return nil, err
- }
-
- methods := []dbus.Auth{dbus.AuthExternal(strconv.Itoa(uid))}
-
- err = conn.Auth(methods)
- if err != nil {
- conn.Close()
- return nil, err
- }
- if err := conn.Hello(); err != nil {
- return nil, err
- }
-
- return conn, nil
-}
-
-// Delete cleans a cgroup
-func (c *CgroupControl) Delete() error {
- return c.DeleteByPath(c.path)
-}
-
-// rmDirRecursively delete recursively a cgroup directory.
-// It differs from os.RemoveAll as it doesn't attempt to unlink files.
-// On cgroupfs we are allowed only to rmdir empty directories.
-func rmDirRecursively(path string) error {
- if err := os.Remove(path); err == nil || os.IsNotExist(err) {
- return nil
- }
- entries, err := ioutil.ReadDir(path)
- if err != nil {
- return errors.Wrapf(err, "read %s", path)
- }
- for _, i := range entries {
- if i.IsDir() {
- if err := rmDirRecursively(filepath.Join(path, i.Name())); err != nil {
- return err
- }
- }
- }
- if err := os.Remove(path); err != nil {
- if !os.IsNotExist(err) {
- return errors.Wrapf(err, "remove %s", path)
- }
- }
- return nil
-}
-
-// DeleteByPathConn deletes the specified cgroup path using the specified
-// dbus connection if needed.
-func (c *CgroupControl) DeleteByPathConn(path string, conn *systemdDbus.Conn) error {
- if c.systemd {
- return systemdDestroyConn(path, conn)
- }
- if c.cgroup2 {
- return rmDirRecursively(filepath.Join(cgroupRoot, c.path))
- }
- var lastError error
- for _, h := range handlers {
- if err := h.Destroy(c); err != nil {
- lastError = err
- }
- }
-
- for _, ctr := range c.additionalControllers {
- if ctr.symlink {
- continue
- }
- p := c.getCgroupv1Path(ctr.name)
- if err := rmDirRecursively(p); err != nil {
- lastError = errors.Wrapf(err, "remove %s", p)
- }
- }
- return lastError
-}
-
-// DeleteByPath deletes the specified cgroup path
-func (c *CgroupControl) DeleteByPath(path string) error {
- if c.systemd {
- conn, err := systemdDbus.New()
- if err != nil {
- return err
- }
- defer conn.Close()
- return c.DeleteByPathConn(path, conn)
- }
- return c.DeleteByPathConn(path, nil)
-}
-
-// Update updates the cgroups
-func (c *CgroupControl) Update(resources *spec.LinuxResources) error {
- for _, h := range handlers {
- if err := h.Apply(c, resources); err != nil {
- return err
- }
- }
- return nil
-}
-
-// AddPid moves the specified pid to the cgroup
-func (c *CgroupControl) AddPid(pid int) error {
- pidString := []byte(fmt.Sprintf("%d\n", pid))
-
- if c.cgroup2 {
- p := filepath.Join(cgroupRoot, c.path, "cgroup.procs")
- if err := ioutil.WriteFile(p, pidString, 0644); err != nil {
- return errors.Wrapf(err, "write %s", p)
- }
- return nil
- }
-
- var names []string
- for n := range handlers {
- names = append(names, n)
- }
-
- for _, c := range c.additionalControllers {
- if !c.symlink {
- names = append(names, c.name)
- }
- }
-
- for _, n := range names {
- p := filepath.Join(c.getCgroupv1Path(n), "tasks")
- if err := ioutil.WriteFile(p, pidString, 0644); err != nil {
- return errors.Wrapf(err, "write %s", p)
- }
- }
- return nil
-}
-
-// Stat returns usage statistics for the cgroup
-func (c *CgroupControl) Stat() (*Metrics, error) {
- m := Metrics{}
- for _, h := range handlers {
- if err := h.Stat(c, &m); err != nil {
- return nil, err
- }
- }
- return &m, nil
-}
-
-func readCgroup2MapFile(ctr *CgroupControl, name string) (map[string][]string, error) {
- ret := map[string][]string{}
- p := filepath.Join(cgroupRoot, ctr.path, name)
- f, err := os.Open(p)
- if err != nil {
- if os.IsNotExist(err) {
- return ret, nil
- }
- return nil, errors.Wrapf(err, "open file %s", p)
- }
- defer f.Close()
- scanner := bufio.NewScanner(f)
- for scanner.Scan() {
- line := scanner.Text()
- parts := strings.Fields(line)
- if len(parts) < 2 {
- continue
- }
- ret[parts[0]] = parts[1:]
- }
- if err := scanner.Err(); err != nil {
- return nil, errors.Wrapf(err, "parsing file %s", p)
- }
- return ret, nil
-}
diff --git a/vendor/github.com/containers/common/pkg/cgroups/cgroups_supported.go b/vendor/github.com/containers/common/pkg/cgroups/cgroups_supported.go
deleted file mode 100644
index 2a36777d4..000000000
--- a/vendor/github.com/containers/common/pkg/cgroups/cgroups_supported.go
+++ /dev/null
@@ -1,89 +0,0 @@
-// +build linux
-
-package cgroups
-
-import (
- "bufio"
- "fmt"
- "os"
- "path/filepath"
- "strings"
- "sync"
- "syscall"
-
- "github.com/pkg/errors"
-)
-
-var (
- isUnifiedOnce sync.Once
- isUnified bool
- isUnifiedErr error
-)
-
-// IsCgroup2UnifiedMode returns whether we are running in cgroup 2 cgroup2 mode.
-func IsCgroup2UnifiedMode() (bool, error) {
- isUnifiedOnce.Do(func() {
- var st syscall.Statfs_t
- if err := syscall.Statfs("/sys/fs/cgroup", &st); err != nil {
- isUnified, isUnifiedErr = false, err
- } else {
- isUnified, isUnifiedErr = st.Type == _cgroup2SuperMagic, nil
- }
- })
- return isUnified, isUnifiedErr
-}
-
-// UserOwnsCurrentSystemdCgroup checks whether the current EUID owns the
-// current cgroup.
-func UserOwnsCurrentSystemdCgroup() (bool, error) {
- uid := os.Geteuid()
-
- cgroup2, err := IsCgroup2UnifiedMode()
- if err != nil {
- return false, err
- }
-
- f, err := os.Open("/proc/self/cgroup")
- if err != nil {
- return false, errors.Wrapf(err, "open file /proc/self/cgroup")
- }
- defer f.Close()
-
- scanner := bufio.NewScanner(f)
- for scanner.Scan() {
- line := scanner.Text()
- parts := strings.SplitN(line, ":", 3)
-
- if len(parts) < 3 {
- continue
- }
-
- var cgroupPath string
-
- if cgroup2 {
- cgroupPath = filepath.Join(cgroupRoot, parts[2])
- } else {
- if parts[1] != "name=systemd" {
- continue
- }
- cgroupPath = filepath.Join(cgroupRoot, "systemd", parts[2])
- }
-
- st, err := os.Stat(cgroupPath)
- if err != nil {
- return false, err
- }
- s := st.Sys()
- if s == nil {
- return false, fmt.Errorf("error stat cgroup path %s", cgroupPath)
- }
-
- if int(s.(*syscall.Stat_t).Uid) != uid {
- return false, nil
- }
- }
- if err := scanner.Err(); err != nil {
- return false, errors.Wrapf(err, "parsing file /proc/self/cgroup")
- }
- return true, nil
-}
diff --git a/vendor/github.com/containers/common/pkg/cgroups/cgroups_unsupported.go b/vendor/github.com/containers/common/pkg/cgroups/cgroups_unsupported.go
deleted file mode 100644
index cd140fbf3..000000000
--- a/vendor/github.com/containers/common/pkg/cgroups/cgroups_unsupported.go
+++ /dev/null
@@ -1,14 +0,0 @@
-// +build !linux
-
-package cgroups
-
-// IsCgroup2UnifiedMode returns whether we are running in cgroup 2 cgroup2 mode.
-func IsCgroup2UnifiedMode() (bool, error) {
- return false, nil
-}
-
-// UserOwnsCurrentSystemdCgroup checks whether the current EUID owns the
-// current cgroup.
-func UserOwnsCurrentSystemdCgroup() (bool, error) {
- return false, nil
-}
diff --git a/vendor/github.com/containers/common/pkg/cgroups/cpu.go b/vendor/github.com/containers/common/pkg/cgroups/cpu.go
deleted file mode 100644
index a43a76b22..000000000
--- a/vendor/github.com/containers/common/pkg/cgroups/cpu.go
+++ /dev/null
@@ -1,123 +0,0 @@
-package cgroups
-
-import (
- "fmt"
- "io/ioutil"
- "os"
- "path/filepath"
- "strconv"
- "strings"
-
- spec "github.com/opencontainers/runtime-spec/specs-go"
- "github.com/pkg/errors"
-)
-
-type cpuHandler struct {
-}
-
-func getCPUHandler() *cpuHandler {
- return &cpuHandler{}
-}
-
-func cleanString(s string) string {
- return strings.Trim(s, "\n")
-}
-
-func readAcct(ctr *CgroupControl, name string) (uint64, error) {
- p := filepath.Join(ctr.getCgroupv1Path(CPUAcct), name)
- return readFileAsUint64(p)
-}
-
-func readAcctList(ctr *CgroupControl, name string) ([]uint64, error) {
- var r []uint64
-
- p := filepath.Join(ctr.getCgroupv1Path(CPUAcct), name)
- data, err := ioutil.ReadFile(p)
- if err != nil {
- return nil, errors.Wrapf(err, "reading %s", p)
- }
- for _, s := range strings.Split(string(data), " ") {
- s = cleanString(s)
- if s == "" {
- break
- }
- v, err := strconv.ParseUint(s, 10, 0)
- if err != nil {
- return nil, errors.Wrapf(err, "parsing %s", s)
- }
- r = append(r, v)
- }
- return r, nil
-}
-
-// Apply set the specified constraints
-func (c *cpuHandler) Apply(ctr *CgroupControl, res *spec.LinuxResources) error {
- if res.CPU == nil {
- return nil
- }
- return fmt.Errorf("cpu apply not implemented yet")
-}
-
-// Create the cgroup
-func (c *cpuHandler) Create(ctr *CgroupControl) (bool, error) {
- if ctr.cgroup2 {
- return false, nil
- }
- return ctr.createCgroupDirectory(CPU)
-}
-
-// Destroy the cgroup
-func (c *cpuHandler) Destroy(ctr *CgroupControl) error {
- return rmDirRecursively(ctr.getCgroupv1Path(CPU))
-}
-
-// Stat fills a metrics structure with usage stats for the controller
-func (c *cpuHandler) Stat(ctr *CgroupControl, m *Metrics) error {
- var err error
- usage := CPUUsage{}
- if ctr.cgroup2 {
- values, err := readCgroup2MapFile(ctr, "cpu.stat")
- if err != nil {
- return err
- }
- if val, found := values["usage_usec"]; found {
- usage.Total, err = strconv.ParseUint(cleanString(val[0]), 10, 0)
- if err != nil {
- return err
- }
- usage.Kernel *= 1000
- }
- if val, found := values["system_usec"]; found {
- usage.Kernel, err = strconv.ParseUint(cleanString(val[0]), 10, 0)
- if err != nil {
- return err
- }
- usage.Total *= 1000
- }
- // FIXME: How to read usage.PerCPU?
- } else {
- usage.Total, err = readAcct(ctr, "cpuacct.usage")
- if err != nil {
- if !os.IsNotExist(errors.Cause(err)) {
- return err
- }
- usage.Total = 0
- }
- usage.Kernel, err = readAcct(ctr, "cpuacct.usage_sys")
- if err != nil {
- if !os.IsNotExist(errors.Cause(err)) {
- return err
- }
- usage.Kernel = 0
- }
- usage.PerCPU, err = readAcctList(ctr, "cpuacct.usage_percpu")
- if err != nil {
- if !os.IsNotExist(errors.Cause(err)) {
- return err
- }
- usage.PerCPU = nil
- }
- }
- m.CPU = CPUMetrics{Usage: usage}
- return nil
-}
diff --git a/vendor/github.com/containers/common/pkg/cgroups/cpuset.go b/vendor/github.com/containers/common/pkg/cgroups/cpuset.go
deleted file mode 100644
index 46d0484f2..000000000
--- a/vendor/github.com/containers/common/pkg/cgroups/cpuset.go
+++ /dev/null
@@ -1,85 +0,0 @@
-package cgroups
-
-import (
- "fmt"
- "io/ioutil"
- "path/filepath"
- "strings"
-
- spec "github.com/opencontainers/runtime-spec/specs-go"
- "github.com/pkg/errors"
-)
-
-type cpusetHandler struct {
-}
-
-func cpusetCopyFileFromParent(dir, file string, cgroupv2 bool) ([]byte, error) {
- if dir == cgroupRoot {
- return nil, fmt.Errorf("could not find parent to initialize cpuset %s", file)
- }
- path := filepath.Join(dir, file)
- parentPath := path
- if cgroupv2 {
- parentPath = fmt.Sprintf("%s.effective", parentPath)
- }
- data, err := ioutil.ReadFile(parentPath)
- if err != nil {
- return nil, errors.Wrapf(err, "open %s", path)
- }
- if len(strings.Trim(string(data), "\n")) != 0 {
- return data, nil
- }
- data, err = cpusetCopyFileFromParent(filepath.Dir(dir), file, cgroupv2)
- if err != nil {
- return nil, err
- }
- if err := ioutil.WriteFile(path, data, 0644); err != nil {
- return nil, errors.Wrapf(err, "write %s", path)
- }
- return data, nil
-}
-
-func cpusetCopyFromParent(path string, cgroupv2 bool) error {
- for _, file := range []string{"cpuset.cpus", "cpuset.mems"} {
- if _, err := cpusetCopyFileFromParent(path, file, cgroupv2); err != nil {
- return err
- }
- }
- return nil
-}
-
-func getCpusetHandler() *cpusetHandler {
- return &cpusetHandler{}
-}
-
-// Apply set the specified constraints
-func (c *cpusetHandler) Apply(ctr *CgroupControl, res *spec.LinuxResources) error {
- if res.CPU == nil {
- return nil
- }
- return fmt.Errorf("cpuset apply not implemented yet")
-}
-
-// Create the cgroup
-func (c *cpusetHandler) Create(ctr *CgroupControl) (bool, error) {
- if ctr.cgroup2 {
- path := filepath.Join(cgroupRoot, ctr.path)
- return true, cpusetCopyFromParent(path, true)
- }
-
- created, err := ctr.createCgroupDirectory(CPUset)
- if !created || err != nil {
- return created, err
- }
- return true, cpusetCopyFromParent(ctr.getCgroupv1Path(CPUset), false)
-}
-
-// Destroy the cgroup
-func (c *cpusetHandler) Destroy(ctr *CgroupControl) error {
- return rmDirRecursively(ctr.getCgroupv1Path(CPUset))
-}
-
-// Stat fills a metrics structure with usage stats for the controller
-func (c *cpusetHandler) Stat(ctr *CgroupControl, m *Metrics) error {
- return nil
-}
diff --git a/vendor/github.com/containers/common/pkg/cgroups/memory.go b/vendor/github.com/containers/common/pkg/cgroups/memory.go
deleted file mode 100644
index b3991f7e3..000000000
--- a/vendor/github.com/containers/common/pkg/cgroups/memory.go
+++ /dev/null
@@ -1,66 +0,0 @@
-package cgroups
-
-import (
- "fmt"
- "path/filepath"
-
- spec "github.com/opencontainers/runtime-spec/specs-go"
-)
-
-type memHandler struct {
-}
-
-func getMemoryHandler() *memHandler {
- return &memHandler{}
-}
-
-// Apply set the specified constraints
-func (c *memHandler) Apply(ctr *CgroupControl, res *spec.LinuxResources) error {
- if res.Memory == nil {
- return nil
- }
- return fmt.Errorf("memory apply not implemented yet")
-}
-
-// Create the cgroup
-func (c *memHandler) Create(ctr *CgroupControl) (bool, error) {
- if ctr.cgroup2 {
- return false, nil
- }
- return ctr.createCgroupDirectory(Memory)
-}
-
-// Destroy the cgroup
-func (c *memHandler) Destroy(ctr *CgroupControl) error {
- return rmDirRecursively(ctr.getCgroupv1Path(Memory))
-}
-
-// Stat fills a metrics structure with usage stats for the controller
-func (c *memHandler) Stat(ctr *CgroupControl, m *Metrics) error {
- var err error
- usage := MemoryUsage{}
-
- var memoryRoot string
- filenames := map[string]string{}
-
- if ctr.cgroup2 {
- memoryRoot = filepath.Join(cgroupRoot, ctr.path)
- filenames["usage"] = "memory.current"
- filenames["limit"] = "memory.max"
- } else {
- memoryRoot = ctr.getCgroupv1Path(Memory)
- filenames["usage"] = "memory.usage_in_bytes"
- filenames["limit"] = "memory.limit_in_bytes"
- }
- usage.Usage, err = readFileAsUint64(filepath.Join(memoryRoot, filenames["usage"]))
- if err != nil {
- return err
- }
- usage.Limit, err = readFileAsUint64(filepath.Join(memoryRoot, filenames["limit"]))
- if err != nil {
- return err
- }
-
- m.Memory = MemoryMetrics{Usage: usage}
- return nil
-}
diff --git a/vendor/github.com/containers/common/pkg/cgroups/pids.go b/vendor/github.com/containers/common/pkg/cgroups/pids.go
deleted file mode 100644
index 65b9b5b34..000000000
--- a/vendor/github.com/containers/common/pkg/cgroups/pids.go
+++ /dev/null
@@ -1,62 +0,0 @@
-package cgroups
-
-import (
- "fmt"
- "io/ioutil"
- "path/filepath"
-
- spec "github.com/opencontainers/runtime-spec/specs-go"
-)
-
-type pidHandler struct {
-}
-
-func getPidsHandler() *pidHandler {
- return &pidHandler{}
-}
-
-// Apply set the specified constraints
-func (c *pidHandler) Apply(ctr *CgroupControl, res *spec.LinuxResources) error {
- if res.Pids == nil {
- return nil
- }
- var PIDRoot string
-
- if ctr.cgroup2 {
- PIDRoot = filepath.Join(cgroupRoot, ctr.path)
- } else {
- PIDRoot = ctr.getCgroupv1Path(Pids)
- }
-
- p := filepath.Join(PIDRoot, "pids.max")
- return ioutil.WriteFile(p, []byte(fmt.Sprintf("%d\n", res.Pids.Limit)), 0644)
-}
-
-// Create the cgroup
-func (c *pidHandler) Create(ctr *CgroupControl) (bool, error) {
- return ctr.createCgroupDirectory(Pids)
-}
-
-// Destroy the cgroup
-func (c *pidHandler) Destroy(ctr *CgroupControl) error {
- return rmDirRecursively(ctr.getCgroupv1Path(Pids))
-}
-
-// Stat fills a metrics structure with usage stats for the controller
-func (c *pidHandler) Stat(ctr *CgroupControl, m *Metrics) error {
- var PIDRoot string
-
- if ctr.cgroup2 {
- PIDRoot = filepath.Join(cgroupRoot, ctr.path)
- } else {
- PIDRoot = ctr.getCgroupv1Path(Pids)
- }
-
- current, err := readFileAsUint64(filepath.Join(PIDRoot, "pids.current"))
- if err != nil {
- return err
- }
-
- m.Pids = PidsMetrics{Current: current}
- return nil
-}
diff --git a/vendor/github.com/containers/common/pkg/cgroups/systemd.go b/vendor/github.com/containers/common/pkg/cgroups/systemd.go
deleted file mode 100644
index b8e6db156..000000000
--- a/vendor/github.com/containers/common/pkg/cgroups/systemd.go
+++ /dev/null
@@ -1,79 +0,0 @@
-package cgroups
-
-import (
- "fmt"
- "path/filepath"
- "strings"
-
- systemdDbus "github.com/coreos/go-systemd/dbus"
- "github.com/godbus/dbus"
-)
-
-func systemdCreate(path string, c *systemdDbus.Conn) error {
- slice, name := filepath.Split(path)
- slice = strings.TrimSuffix(slice, "/")
-
- var lastError error
- for i := 0; i < 2; i++ {
- properties := []systemdDbus.Property{
- systemdDbus.PropDescription(fmt.Sprintf("cgroup %s", name)),
- systemdDbus.PropWants(slice),
- }
- pMap := map[string]bool{
- "DefaultDependencies": false,
- "MemoryAccounting": true,
- "CPUAccounting": true,
- "BlockIOAccounting": true,
- }
- if i == 0 {
- pMap["Delegate"] = true
- }
- for k, v := range pMap {
- p := systemdDbus.Property{
- Name: k,
- Value: dbus.MakeVariant(v),
- }
- properties = append(properties, p)
- }
-
- ch := make(chan string)
- _, err := c.StartTransientUnit(name, "replace", properties, ch)
- if err != nil {
- lastError = err
- continue
- }
- <-ch
- return nil
- }
- return lastError
-}
-
-/*
- systemdDestroyConn is copied from containerd/cgroups/systemd.go file, that
- has the following license:
-
- 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.
-*/
-func systemdDestroyConn(path string, c *systemdDbus.Conn) error {
- name := filepath.Base(path)
-
- ch := make(chan string)
- _, err := c.StopUnit(name, "replace", ch)
- if err != nil {
- return err
- }
- <-ch
- return nil
-}
diff --git a/vendor/github.com/containers/common/pkg/config/config.go b/vendor/github.com/containers/common/pkg/config/config.go
new file mode 100644
index 000000000..db70e53a4
--- /dev/null
+++ b/vendor/github.com/containers/common/pkg/config/config.go
@@ -0,0 +1,878 @@
+package config
+
+import (
+ "fmt"
+ "os"
+ "os/exec"
+ "path/filepath"
+ "strings"
+ "sync"
+ "syscall"
+
+ "github.com/BurntSushi/toml"
+ "github.com/containers/common/pkg/capabilities"
+ "github.com/containers/common/pkg/unshare"
+ units "github.com/docker/go-units"
+ selinux "github.com/opencontainers/selinux/go-selinux"
+ "github.com/pkg/errors"
+ "github.com/sirupsen/logrus"
+)
+
+const (
+ // DefaultContainersConfig holds the default containers config path
+ DefaultContainersConfig = "/usr/share/containers/containers.conf"
+ // OverrideContainersConfig holds the default config paths overridden by the root user
+ OverrideContainersConfig = "/etc/containers/containers.conf"
+ // UserOverrideContainersConfig holds the containers config path overridden by the rootless user
+ UserOverrideContainersConfig = ".config/containers/containers.conf"
+)
+
+// RuntimeStateStore is a constant indicating which state store implementation
+// should be used by engine
+type RuntimeStateStore int
+
+const (
+ // InvalidStateStore is an invalid state store
+ InvalidStateStore RuntimeStateStore = iota
+ // InMemoryStateStore is an in-memory state that will not persist data
+ // on containers and pods between engine instances or after system
+ // reboot
+ InMemoryStateStore RuntimeStateStore = iota
+ // SQLiteStateStore is a state backed by a SQLite database
+ // It is presently disabled
+ SQLiteStateStore RuntimeStateStore = iota
+ // BoltDBStateStore is a state backed by a BoltDB database
+ BoltDBStateStore RuntimeStateStore = iota
+)
+
+// PullPolicy whether to pull new image
+type PullPolicy int
+
+const (
+ // PullImageAlways always try to pull new image when create or run
+ PullImageAlways PullPolicy = iota
+ // PullImageMissing pulls image if it is not locally
+ PullImageMissing
+ // PullImageNever will never pull new image
+ PullImageNever
+)
+
+// Config contains configuration options for container tools
+type Config struct {
+ // Containers specify settings that configure how containers will run ont the system
+ Containers ContainersConfig `toml:"containers"`
+ // Engine specifies how the container engine based on Engine will run
+ Engine EngineConfig `toml:"engine"`
+ // Network section defines the configuration of CNI Plugins
+ Network NetworkConfig `toml:"network"`
+}
+
+// ContainersConfig represents the "containers" TOML config table
+// containers global options for containers tools
+type ContainersConfig struct {
+
+ // Devices to add to all containers
+ Devices []string `toml:"devices"`
+
+ // Volumes to add to all containers
+ Volumes []string `toml:"volumes"`
+
+ // ApparmorProfile is the apparmor profile name which is used as the
+ // default for the runtime.
+ ApparmorProfile string `toml:"apparmor_profile"`
+
+ // Annotation to add to all containers
+ Annotations []string `toml:"annotations"`
+
+ // Default way to create a cgroup namespace for the container
+ CgroupNS string `toml:"cgroupns"`
+
+ // Capabilities to add to all containers.
+ DefaultCapabilities []string `toml:"default_capabilities"`
+
+ // Sysctls to add to all containers.
+ DefaultSysctls []string `toml:"default_sysctls"`
+
+ // DefaultUlimits specifies the default ulimits to apply to containers
+ DefaultUlimits []string `toml:"default_ulimits"`
+
+ // DefaultMountsFile is the path to the default mounts file for testing
+ DefaultMountsFile string `toml:"-"`
+
+ // DNSServers set default DNS servers.
+ DNSServers []string `toml:"dns_servers"`
+
+ // DNSOptions set default DNS options.
+ DNSOptions []string `toml:"dns_options"`
+
+ // DNSSearches set default DNS search domains.
+ DNSSearches []string `toml:"dns_searches"`
+
+ // EnableLabeling tells the container engines whether to use MAC
+ // Labeling to separate containers (SELinux)
+ EnableLabeling bool `toml:"label"`
+
+ // Env is the environment variable list for container process.
+ Env []string `toml:"env"`
+
+ // EnvHost Pass all host environment variables into the container.
+ EnvHost bool `toml:"env_host"`
+
+ // HTTPProxy is the proxy environment variable list to apply to container process
+ HTTPProxy bool `toml:"http_proxy"`
+
+ // Init tells container runtimes whether to run init inside the
+ // container that forwards signals and reaps processes.
+ Init bool `toml:"init"`
+
+ // InitPath is the path for init to run if the Init bool is enabled
+ InitPath string `toml:"init_path"`
+
+ // IPCNS way to to create a ipc namespace for the container
+ IPCNS string `toml:"ipcns"`
+
+ // LogDriver for the container. For example: k8s-file and journald
+ LogDriver string `toml:"log_driver"`
+
+ // LogSizeMax is the maximum number of bytes after which the log file
+ // will be truncated. It can be expressed as a human-friendly string
+ // that is parsed to bytes.
+ // Negative values indicate that the log file won't be truncated.
+ LogSizeMax int64 `toml:"log_size_max"`
+
+ // NetNS indicates how to create a network namespace for the container
+ NetNS string `toml:"netns"`
+
+ // NoHosts tells container engine whether to create its own /etc/hosts
+ NoHosts bool `toml:"no_hosts"`
+
+ // PidsLimit is the number of processes each container is restricted to
+ // by the cgroup process number controller.
+ PidsLimit int64 `toml:"pids_limit"`
+
+ // PidNS indicates how to create a pid namespace for the container
+ PidNS string `toml:"pidns"`
+
+ // SeccompProfile is the seccomp.json profile path which is used as the
+ // default for the runtime.
+ SeccompProfile string `toml:"seccomp_profile"`
+
+ // ShmSize holds the size of /dev/shm.
+ ShmSize string `toml:"shm_size"`
+
+ // UTSNS indicates how to create a UTS namespace for the container
+ UTSNS string `toml:"utsns"`
+
+ // UserNS indicates how to create a User namespace for the container
+ UserNS string `toml:"userns"`
+
+ // UserNSSize how many UIDs to allocate for automatically created UserNS
+ UserNSSize int `toml:"userns_size"`
+}
+
+// EngineConfig contains configuration options used to set up a engine runtime
+type EngineConfig struct {
+ // CgroupCheck indicates the configuration has been rewritten after an
+ // upgrade to Fedora 31 to change the default OCI runtime for cgroupsv2.
+ CgroupCheck bool `toml:"cgroup_check,omitempty"`
+
+ // CGroupManager is the CGroup Manager to use Valid values are "cgroupfs"
+ // and "systemd".
+ CgroupManager string `toml:"cgroup_manager"`
+
+ // NOTE: when changing this struct, make sure to update (*Config).Merge().
+
+ // ConmonEnvVars are environment variables to pass to the Conmon binary
+ // when it is launched.
+ ConmonEnvVars []string `toml:"conmon_env_vars"`
+
+ // ConmonPath is the path to the Conmon binary used for managing containers.
+ // The first path pointing to a valid file will be used.
+ ConmonPath []string `toml:"conmon_path"`
+
+ //DetachKeys is the sequence of keys used to detach a container.
+ DetachKeys string `toml:"detach_keys"`
+
+ // EnablePortReservation determines whether engine will reserve ports on the
+ // host when they are forwarded to containers. When enabled, when ports are
+ // forwarded to containers, they are held open by conmon as long as the
+ // container is running, ensuring that they cannot be reused by other
+ // programs on the host. However, this can cause significant memory usage if
+ // a container has many ports forwarded to it. Disabling this can save
+ // memory.
+ EnablePortReservation bool `toml:"enable_port_reservation"`
+
+ // EventsLogFilePath is where the events log is stored.
+ EventsLogFilePath string `toml:"events_logfile_path"`
+
+ // EventsLogger determines where events should be logged.
+ EventsLogger string `toml:"events_logger"`
+
+ // configuration files. When the same filename is present in in
+ // multiple directories, the file in the directory listed last in
+ // this slice takes precedence.
+ HooksDir []string `toml:"hooks_dir"`
+
+ // ImageDefaultTransport is the default transport method used to fetch
+ // images.
+ ImageDefaultTransport string `toml:"image_default_transport"`
+
+ // InfraCommand is the command run to start up a pod infra container.
+ InfraCommand string `toml:"infra_command"`
+
+ // InfraImage is the image a pod infra container will use to manage
+ // namespaces.
+ InfraImage string `toml:"infra_image"`
+
+ // InitPath is the path to the container-init binary.
+ InitPath string `toml:"init_path"`
+
+ // LockType is the type of locking to use.
+ LockType string `toml:"lock_type,omitempty"`
+
+ // Namespace is the engine namespace to use. Namespaces are used to create
+ // scopes to separate containers and pods in the state. When namespace is
+ // set, engine will only view containers and pods in the same namespace. All
+ // containers and pods created will default to the namespace set here. A
+ // namespace of "", the empty string, is equivalent to no namespace, and all
+ // containers and pods will be visible. The default namespace is "".
+ Namespace string `toml:"namespace,omitempty"`
+
+ // NetworkCmdPath is the path to the slirp4netns binary.
+ NetworkCmdPath string `toml:"network_cmd_path"`
+
+ // NoPivotRoot sets whether to set no-pivot-root in the OCI runtime.
+ NoPivotRoot bool `toml:"no_pivot_root"`
+
+ // NumLocks is the number of locks to make available for containers and
+ // pods.
+ NumLocks uint32 `toml:"num_locks,omitempty"`
+
+ // OCIRuntime is the OCI runtime to use.
+ OCIRuntime string `toml:"runtime"`
+
+ // OCIRuntimes are the set of configured OCI runtimes (default is runc).
+ OCIRuntimes map[string][]string `toml:"runtimes"`
+
+ // PullPolicy determines whether to pull image before creating or running a container
+ // default is "missing"
+ PullPolicy string `toml:"pull_policy"`
+ // RuntimePath is the path to OCI runtime binary for launching containers.
+ // The first path pointing to a valid file will be used This is used only
+ // when there are no OCIRuntime/OCIRuntimes defined. It is used only to be
+ // backward compatible with older versions of Podman.
+ RuntimePath []string `toml:"runtime_path,omitempty"`
+
+ // RuntimeSupportsJSON is the list of the OCI runtimes that support
+ // --format=json.
+ RuntimeSupportsJSON []string `toml:"runtime_supports_json"`
+
+ // RuntimeSupportsNoCgroups is a list of OCI runtimes that support
+ // running containers without CGroups.
+ RuntimeSupportsNoCgroups []string `toml:"runtime_supports_nocgroups"`
+
+ // SetOptions contains a subset of config options. It's used to indicate if
+ // a given option has either been set by the user or by the parsed
+ // configuration file. If not, the corresponding option might be
+ // overwritten by values from the database. This behavior guarantees
+ // backwards compat with older version of libpod and Podman.
+ SetOptions
+
+ // SignaturePolicyPath is the path to a signature policy to use for
+ // validating images. If left empty, the containers/image default signature
+ // policy will be used.
+ SignaturePolicyPath string `toml:"_"`
+
+ // SDNotify tells container engine to allow containers to notify the host systemd of
+ // readiness using the SD_NOTIFY mechanism.
+ SDNotify bool
+
+ // StateType is the type of the backing state store. Avoid using multiple
+ // values for this with the same containers/storage configuration on the
+ // same system. Different state types do not interact, and each will see a
+ // separate set of containers, which may cause conflicts in
+ // containers/storage. As such this is not exposed via the config file.
+ StateType RuntimeStateStore `toml:"-"`
+
+ // StaticDir is the path to a persistent directory to store container
+ // files.
+ StaticDir string `toml:"static_dir"`
+
+ // StopTimeout is the number of seconds to wait for container to exit
+ // before sending kill signal.
+ StopTimeout uint `toml:"stop_timeout"`
+
+ // TmpDir is the path to a temporary directory to store per-boot container
+ // files. Must be stored in a tmpfs.
+ TmpDir string `toml:"tmp_dir"`
+
+ // VolumePath is the default location that named volumes will be created
+ // under. This convention is followed by the default volume driver, but
+ // may not be by other drivers.
+ VolumePath string `toml:"volume_path"`
+}
+
+// SetOptions contains a subset of options in a Config. It's used to indicate if
+// a given option has either been set by the user or by a parsed engine
+// configuration file. If not, the corresponding option might be overwritten by
+// values from the database. This behavior guarantees backwards compat with
+// older version of libpod and Podman.
+type SetOptions struct {
+ // StorageConfigRunRootSet indicates if the RunRoot has been explicitly set
+ // by the config or by the user. It's required to guarantee backwards
+ // compatibility with older versions of libpod for which we must query the
+ // database configuration. Not included in the on-disk config.
+ StorageConfigRunRootSet bool `toml:"-"`
+
+ // StorageConfigGraphRootSet indicates if the RunRoot has been explicitly
+ // set by the config or by the user. It's required to guarantee backwards
+ // compatibility with older versions of libpod for which we must query the
+ // database configuration. Not included in the on-disk config.
+ StorageConfigGraphRootSet bool `toml:"-"`
+
+ // StorageConfigGraphDriverNameSet indicates if the GraphDriverName has been
+ // explicitly set by the config or by the user. It's required to guarantee
+ // backwards compatibility with older versions of libpod for which we must
+ // query the database configuration. Not included in the on-disk config.
+ StorageConfigGraphDriverNameSet bool `toml:"-"`
+
+ // StaticDirSet indicates if the StaticDir has been explicitly set by the
+ // config or by the user. It's required to guarantee backwards compatibility
+ // with older versions of libpod for which we must query the database
+ // configuration. Not included in the on-disk config.
+ StaticDirSet bool `toml:"-"`
+
+ // VolumePathSet indicates if the VolumePath has been explicitly set by the
+ // config or by the user. It's required to guarantee backwards compatibility
+ // with older versions of libpod for which we must query the database
+ // configuration. Not included in the on-disk config.
+ VolumePathSet bool `toml:"-"`
+
+ // TmpDirSet indicates if the TmpDir has been explicitly set by the config
+ // or by the user. It's required to guarantee backwards compatibility with
+ // older versions of libpod for which we must query the database
+ // configuration. Not included in the on-disk config.
+ TmpDirSet bool `toml:"-"`
+}
+
+// NetworkConfig represents the "network" TOML config table
+type NetworkConfig struct {
+ // CNIPluginDirs is where CNI plugin binaries are stored.
+ CNIPluginDirs []string `toml:"cni_plugin_dirs"`
+
+ // DefaultNetwork is the network name of the default CNI network
+ // to attach pods to.
+ DefaultNetwork string `toml:"default_network,omitempty"`
+
+ // NetworkConfigDir is where CNI network configuration files are stored.
+ NetworkConfigDir string `toml:"network_config_dir"`
+}
+
+// NewConfig creates a new Config. It starts with an empty config and, if
+// specified, merges the config at `userConfigPath` path. Depending if we're
+// running as root or rootless, we then merge the system configuration followed
+// by merging the default config (hard-coded default in memory).
+// Note that the OCI runtime is hard-set to `crun` if we're running on a system
+// with cgroupsv2. Other OCI runtimes are not yet supporting cgroupsv2. This
+// might change in the future.
+func NewConfig(userConfigPath string) (*Config, error) {
+
+ // Generate the default config for the system
+ config, err := DefaultConfig()
+ if err != nil {
+ return nil, err
+ }
+
+ // read libpod.conf and convert the config to *Config
+ if err = newLibpodConfig(config); err != nil && !os.IsNotExist(err) {
+ logrus.Errorf("error reading libpod.conf: %v", err)
+ }
+
+ // Now, gather the system configs and merge them as needed.
+ configs, err := systemConfigs()
+ if err != nil {
+ return nil, errors.Wrapf(err, "error finding config on system")
+ }
+ for _, path := range configs {
+ // Merge changes in later configs with the previous configs.
+ // Each config file that specified fields, will override the
+ // previous fields.
+ config, err := readConfigFromFile(path, config)
+ if err != nil {
+ return nil, errors.Wrapf(err, "error reading system config %q", path)
+ }
+ logrus.Debugf("Merged system config %q: %v", path, config)
+ }
+
+ // If the caller specified a config path to use, then we read it to
+ // override the system defaults.
+ if userConfigPath != "" {
+ var err error
+ // readConfigFromFile reads in container config in the specified
+ // file and then merge changes with the current default.
+ config, err = readConfigFromFile(userConfigPath, config)
+ if err != nil {
+ return nil, errors.Wrapf(err, "error reading user config %q", userConfigPath)
+ }
+ logrus.Debugf("Merged user config %q: %v", userConfigPath, config)
+ }
+ config.addCAPPrefix()
+
+ if err := config.Validate(); err != nil {
+ return nil, err
+ }
+
+ return config, nil
+}
+
+// readConfigFromFile reads the specified config file at `path` and attempts to
+// unmarshal its content into a Config. The config param specifies the previous
+// default config. If the path, only specifies a few fields in the Toml file
+// the defaults from the config parameter will be used for all other fields.
+func readConfigFromFile(path string, config *Config) (*Config, error) {
+ logrus.Debugf("Reading configuration file %q", path)
+ _, err := toml.DecodeFile(path, config)
+ if err != nil {
+ return nil, fmt.Errorf("unable to decode configuration %v: %v", path, err)
+ }
+ if config.Engine.VolumePath != "" {
+ config.Engine.VolumePathSet = true
+ }
+ if config.Engine.StaticDir != "" {
+ config.Engine.StaticDirSet = true
+ }
+ if config.Engine.TmpDir != "" {
+ config.Engine.TmpDirSet = true
+ }
+
+ return config, err
+}
+
+// Returns the list of configuration files, if they exist in order of hierarchy.
+// The files are read in order and each new file can/will override previous
+// file settings.
+func systemConfigs() ([]string, error) {
+ configs := []string{}
+ path := os.Getenv("CONTAINERS_CONF")
+ if path != "" {
+ if _, err := os.Stat(path); err != nil {
+ return nil, errors.Wrap(err, "failed to stat of %s from CONTAINERS_CONF environment variable")
+ }
+ return append(configs, path), nil
+ }
+ if _, err := os.Stat(DefaultContainersConfig); err == nil {
+ configs = append(configs, DefaultContainersConfig)
+ }
+ if _, err := os.Stat(OverrideContainersConfig); err == nil {
+ configs = append(configs, OverrideContainersConfig)
+ }
+ if unshare.IsRootless() {
+ path, err := rootlessConfigPath()
+ if err != nil {
+ return nil, err
+ }
+ if _, err := os.Stat(path); err == nil {
+ configs = append(configs, path)
+ }
+ }
+ return configs, nil
+}
+
+// CheckCgroupsAndAdjustConfig checks if we're running rootless with the systemd
+// cgroup manager. In case the user session isn't available, we're switching the
+// cgroup manager to cgroupfs. Note, this only applies to rootless.
+func (c *Config) CheckCgroupsAndAdjustConfig() {
+ if !unshare.IsRootless() || c.Engine.CgroupManager != SystemdCgroupsManager {
+ return
+ }
+
+ session := os.Getenv("DBUS_SESSION_BUS_ADDRESS")
+ hasSession := session != ""
+ if hasSession && strings.HasPrefix(session, "unix:path=") {
+ _, err := os.Stat(strings.TrimPrefix(session, "unix:path="))
+ hasSession = err == nil
+ }
+
+ if !hasSession {
+ logrus.Warningf("The cgroups manager is set to systemd but there is no systemd user session available")
+ logrus.Warningf("For using systemd, you may need to login using an user session")
+ logrus.Warningf("Alternatively, you can enable lingering with: `loginctl enable-linger %d` (possibly as root)", unshare.GetRootlessUID())
+ logrus.Warningf("Falling back to --cgroup-manager=cgroupfs")
+ c.Engine.CgroupManager = CgroupfsCgroupsManager
+ }
+}
+
+func (c *Config) addCAPPrefix() {
+ toCAPPrefixed := func(cap string) string {
+ if !strings.HasPrefix(strings.ToLower(cap), "cap_") {
+ return "CAP_" + strings.ToUpper(cap)
+ }
+ return cap
+ }
+ for i, cap := range c.Containers.DefaultCapabilities {
+ c.Containers.DefaultCapabilities[i] = toCAPPrefixed(cap)
+ }
+}
+
+// Validate is the main entry point for library configuration validation.
+func (c *Config) Validate() error {
+
+ if err := c.Containers.Validate(); err != nil {
+ return errors.Wrapf(err, " error validating containers config")
+ }
+
+ if !c.Containers.EnableLabeling {
+ selinux.SetDisabled()
+ }
+
+ if err := c.Engine.Validate(); err != nil {
+ return errors.Wrapf(err, "error validating engine configs")
+ }
+
+ if err := c.Network.Validate(); err != nil {
+ return errors.Wrapf(err, "error validating network configs")
+ }
+
+ return nil
+}
+
+// Validate is the main entry point for Engine configuration validation
+// It returns an `error` on validation failure, otherwise
+// `nil`.
+func (c *EngineConfig) Validate() error {
+ // Relative paths can cause nasty bugs, because core paths we use could
+ // shift between runs (or even parts of the program - the OCI runtime
+ // uses a different working directory than we do, for example.
+ if c.StaticDir != "" && !filepath.IsAbs(c.StaticDir) {
+ return fmt.Errorf("static directory must be an absolute path - instead got %q", c.StaticDir)
+ }
+ if c.TmpDir != "" && !filepath.IsAbs(c.TmpDir) {
+ return fmt.Errorf("temporary directory must be an absolute path - instead got %q", c.TmpDir)
+ }
+ if c.VolumePath != "" && !filepath.IsAbs(c.VolumePath) {
+ return fmt.Errorf("volume path must be an absolute path - instead got %q", c.VolumePath)
+ }
+
+ // Check if the pullPolicy from containers.conf is valid
+ // if it is invalid returns the error
+ pullPolicy := strings.ToLower(c.PullPolicy)
+ if _, err := ValidatePullPolicy(pullPolicy); err != nil {
+ return errors.Wrapf(err, "invalid pull type from containers.conf %q", c.PullPolicy)
+ }
+ return nil
+}
+
+// Validate is the main entry point for containers configuration validation
+// It returns an `error` on validation failure, otherwise
+// `nil`.
+func (c *ContainersConfig) Validate() error {
+ for _, u := range c.DefaultUlimits {
+ ul, err := units.ParseUlimit(u)
+ if err != nil {
+ return fmt.Errorf("unrecognized ulimit %s: %v", u, err)
+ }
+ _, err = ul.GetRlimit()
+ if err != nil {
+ return err
+ }
+ }
+
+ for _, d := range c.Devices {
+ _, _, _, err := Device(d)
+ if err != nil {
+ return err
+ }
+ }
+
+ if c.LogSizeMax >= 0 && c.LogSizeMax < OCIBufSize {
+ return fmt.Errorf("log size max should be negative or >= %d", OCIBufSize)
+ }
+
+ if _, err := units.FromHumanSize(c.ShmSize); err != nil {
+ return fmt.Errorf("invalid --shm-size %s, %q", c.ShmSize, err)
+ }
+
+ return nil
+}
+
+// Validate is the main entry point for network configuration validation.
+// The parameter `onExecution` specifies if the validation should include
+// execution checks. It returns an `error` on validation failure, otherwise
+// `nil`.
+func (c *NetworkConfig) Validate() error {
+
+ if c.NetworkConfigDir != cniConfigDir {
+ err := isDirectory(c.NetworkConfigDir)
+ if err != nil {
+ return errors.Wrapf(err, "invalid network_config_dir: %s", c.NetworkConfigDir)
+ }
+ }
+
+ if stringsEq(c.CNIPluginDirs, cniBinDir) {
+ return nil
+ }
+
+ for _, pluginDir := range c.CNIPluginDirs {
+ if err := isDirectory(pluginDir); err == nil {
+ return nil
+ }
+ }
+
+ return errors.Errorf("invalid cni_plugin_dirs: %s", strings.Join(c.CNIPluginDirs, ","))
+}
+
+// ValidatePullPolicy check if the pullPolicy from CLI is valid and returns the valid enum type
+// if the value from CLI or containers.conf is invalid returns the error
+func ValidatePullPolicy(pullPolicy string) (PullPolicy, error) {
+ switch pullPolicy {
+ case "always":
+ return PullImageAlways, nil
+ case "missing":
+ return PullImageMissing, nil
+ case "never":
+ return PullImageNever, nil
+ case "":
+ return PullImageMissing, nil
+ default:
+ return PullImageMissing, errors.Errorf("invalid pull policy %q", pullPolicy)
+ }
+}
+
+// FindConmon iterates over (*Config).ConmonPath and returns the path
+// to first (version) matching conmon binary. If non is found, we try
+// to do a path lookup of "conmon".
+func (c *Config) FindConmon() (string, error) {
+ foundOutdatedConmon := false
+ for _, path := range c.Engine.ConmonPath {
+ stat, err := os.Stat(path)
+ if err != nil {
+ continue
+ }
+ if stat.IsDir() {
+ continue
+ }
+ if err := probeConmon(path); err != nil {
+ logrus.Warnf("Conmon at %s invalid: %v", path, err)
+ foundOutdatedConmon = true
+ continue
+ }
+ logrus.Debugf("Using conmon: %q", path)
+ return path, nil
+ }
+
+ // Search the $PATH as last fallback
+ if path, err := exec.LookPath("conmon"); err == nil {
+ if err := probeConmon(path); err != nil {
+ logrus.Warnf("Conmon at %s is invalid: %v", path, err)
+ foundOutdatedConmon = true
+ } else {
+ logrus.Debugf("Using conmon from $PATH: %q", path)
+ return path, nil
+ }
+ }
+
+ if foundOutdatedConmon {
+ return "", errors.Wrapf(ErrConmonOutdated,
+ "please update to v%d.%d.%d or later",
+ _conmonMinMajorVersion, _conmonMinMinorVersion, _conmonMinPatchVersion)
+ }
+
+ return "", errors.Wrapf(ErrInvalidArg,
+ "could not find a working conmon binary (configured options: %v)",
+ c.Engine.ConmonPath)
+}
+
+// GetDefaultEnv returns the environment variables for the container.
+// It will checn the HTTPProxy and HostEnv booleans and add the appropriate
+// environment variables to the container.
+func (c *Config) GetDefaultEnv() []string {
+ var env []string
+ if c.Containers.EnvHost {
+ env = append(env, os.Environ()...)
+ } else if c.Containers.HTTPProxy {
+ proxy := []string{"http_proxy", "https_proxy", "ftp_proxy", "no_proxy", "HTTP_PROXY", "HTTPS_PROXY", "FTP_PROXY", "NO_PROXY"}
+ for _, p := range proxy {
+ if val, ok := os.LookupEnv(p); ok {
+ env = append(env, fmt.Sprintf("%s=%s", p, val))
+ }
+ }
+ }
+ return append(env, c.Containers.Env...)
+}
+
+// Capabilities returns the capabilities parses the Add and Drop capability
+// list from the default capabiltiies for the container
+func (c *Config) Capabilities(user string, addCapabilities, dropCapabilities []string) []string {
+
+ userNotRoot := func(user string) bool {
+ if user == "" || user == "root" || user == "0" {
+ return false
+ }
+ return true
+ }
+
+ var caps []string
+ defaultCapabilities := c.Containers.DefaultCapabilities
+ if userNotRoot(user) {
+ defaultCapabilities = []string{}
+ }
+
+ mapCap := make(map[string]bool, len(defaultCapabilities))
+ for _, c := range addCapabilities {
+ if strings.ToLower(c) == "all" {
+ defaultCapabilities = capabilities.AllCapabilities()
+ addCapabilities = nil
+ break
+ }
+ }
+
+ for _, c := range append(defaultCapabilities, addCapabilities...) {
+ mapCap[c] = true
+ }
+ for _, c := range dropCapabilities {
+ if "all" == strings.ToLower(c) {
+ return caps
+ }
+ mapCap[c] = false
+ }
+ for cap, add := range mapCap {
+ if add {
+ caps = append(caps, cap)
+ }
+ }
+ return caps
+}
+
+// Device parses device mapping string to a src, dest & permissions string
+// Valid values for device looklike:
+// '/dev/sdc"
+// '/dev/sdc:/dev/xvdc"
+// '/dev/sdc:/dev/xvdc:rwm"
+// '/dev/sdc:rm"
+func Device(device string) (string, string, string, error) {
+ src := ""
+ dst := ""
+ permissions := "rwm"
+ split := strings.Split(device, ":")
+ switch len(split) {
+ case 3:
+ if !IsValidDeviceMode(split[2]) {
+ return "", "", "", fmt.Errorf("invalid device mode: %s", split[2])
+ }
+ permissions = split[2]
+ fallthrough
+ case 2:
+ if IsValidDeviceMode(split[1]) {
+ permissions = split[1]
+ } else {
+ if len(split[1]) == 0 || split[1][0] != '/' {
+ return "", "", "", fmt.Errorf("invalid device mode: %s", split[1])
+ }
+ dst = split[1]
+ }
+ fallthrough
+ case 1:
+ if !strings.HasPrefix(split[0], "/dev/") {
+ return "", "", "", fmt.Errorf("invalid device mode: %s", split[0])
+ }
+ src = split[0]
+ default:
+ return "", "", "", fmt.Errorf("invalid device specification: %s", device)
+ }
+
+ if dst == "" {
+ dst = src
+ }
+ return src, dst, permissions, nil
+}
+
+// IsValidDeviceMode checks if the mode for device is valid or not.
+// IsValid mode is a composition of r (read), w (write), and m (mknod).
+func IsValidDeviceMode(mode string) bool {
+ var legalDeviceMode = map[rune]bool{
+ 'r': true,
+ 'w': true,
+ 'm': true,
+ }
+ if mode == "" {
+ return false
+ }
+ for _, c := range mode {
+ if !legalDeviceMode[c] {
+ return false
+ }
+ legalDeviceMode[c] = false
+ }
+ return true
+}
+
+// isDirectory tests whether the given path exists and is a directory. It
+// follows symlinks.
+func isDirectory(path string) error {
+ info, err := os.Stat(path)
+ if err != nil {
+ return err
+ }
+
+ if !info.Mode().IsDir() {
+ // Return a PathError to be consistent with os.Stat().
+ return &os.PathError{
+ Op: "stat",
+ Path: path,
+ Err: syscall.ENOTDIR,
+ }
+ }
+
+ return nil
+}
+
+func rootlessConfigPath() (string, error) {
+ if configHome := os.Getenv("XDG_CONFIG_HOME"); configHome != "" {
+ return filepath.Join(configHome, UserOverrideContainersConfig), nil
+ }
+ home, err := unshare.HomeDir()
+ if err != nil {
+ return "", err
+ }
+
+ return filepath.Join(home, UserOverrideContainersConfig), nil
+}
+
+func stringsEq(a, b []string) bool {
+
+ if len(a) != len(b) {
+ return false
+ }
+
+ for i := range a {
+ if a[i] != b[i] {
+ return false
+ }
+ }
+
+ return true
+}
+
+var (
+ configOnce sync.Once
+ config *Config
+)
+
+// Default returns the default container config.
+// Configuration files will be read in the following files:
+// * /usr/share/containers/containers.conf
+// * /etc/containers/containers.conf
+// * $HOME/.config/containers/containers.conf # When run in rootless mode
+// Fields in latter files override defaults set in previous files and the
+// default config.
+// None of these files are required, and not all fields need to be specified
+// in each file, only the fields you want to override.
+// The system defaults container config files can be overwritten using the
+// CONTAINERS_CONF environment variable. This is usually done for testing.
+func Default() (*Config, error) {
+ var err error
+ configOnce.Do(func() {
+ config, err = NewConfig("")
+ })
+ return config, err
+}
diff --git a/vendor/github.com/containers/common/pkg/config/config_linux.go b/vendor/github.com/containers/common/pkg/config/config_linux.go
new file mode 100644
index 000000000..17b862967
--- /dev/null
+++ b/vendor/github.com/containers/common/pkg/config/config_linux.go
@@ -0,0 +1,7 @@
+package config
+
+import selinux "github.com/opencontainers/selinux/go-selinux"
+
+func selinuxEnabled() bool {
+ return selinux.GetEnabled()
+}
diff --git a/vendor/github.com/containers/common/pkg/config/config_unix.go b/vendor/github.com/containers/common/pkg/config/config_unix.go
new file mode 100644
index 000000000..f270f2e95
--- /dev/null
+++ b/vendor/github.com/containers/common/pkg/config/config_unix.go
@@ -0,0 +1,15 @@
+// +build !windows
+
+package config
+
+// Defaults for linux/unix if none are specified
+const (
+ cniConfigDir = "/etc/cni/net.d/"
+)
+
+var cniBinDir = []string{
+ "/usr/libexec/cni",
+ "/usr/lib/cni",
+ "/usr/local/lib/cni",
+ "/opt/cni/bin",
+}
diff --git a/vendor/github.com/containers/common/pkg/config/config_unsupported.go b/vendor/github.com/containers/common/pkg/config/config_unsupported.go
new file mode 100644
index 000000000..6563fd317
--- /dev/null
+++ b/vendor/github.com/containers/common/pkg/config/config_unsupported.go
@@ -0,0 +1,7 @@
+// +build !linux
+
+package config
+
+func selinuxEnabled() bool {
+ return false
+}
diff --git a/vendor/github.com/containers/common/pkg/config/config_windows.go b/vendor/github.com/containers/common/pkg/config/config_windows.go
new file mode 100644
index 000000000..f6a6512a1
--- /dev/null
+++ b/vendor/github.com/containers/common/pkg/config/config_windows.go
@@ -0,0 +1,10 @@
+// +build windows
+
+package config
+
+// Defaults for linux/unix if none are specified
+const (
+ cniConfigDir = "C:\\cni\\etc\\net.d\\"
+)
+
+var cniBinDir = []string{"C:\\cni\\bin\\"}
diff --git a/vendor/github.com/containers/common/pkg/config/containers.conf b/vendor/github.com/containers/common/pkg/config/containers.conf
new file mode 100644
index 000000000..b01db5f88
--- /dev/null
+++ b/vendor/github.com/containers/common/pkg/config/containers.conf
@@ -0,0 +1,379 @@
+# The containers configuration file specifies all of the available configuration
+# command-line options/flags for container engine tools like Podman & Buildah,
+# but in a TOML format that can be easily modified and versioned.
+
+# Please refer to containers.conf(5) for details of all configuration options.
+# Not all container engines implement all of the options.
+# All of the options have hard coded defaults and these options will override
+# the built in defaults. Users can then override these options via the command
+# line. Container engines will read containers.conf files in up to three
+# locations in the following order:
+# 1. /usr/share/containers/containers.conf
+# 2. /etc/containers/containers.conf
+# 3. $HOME/.config/containers/containers.conf (Rootless containers ONLY)
+# Items specified in the latter containers.conf, if they exist, override the
+# previous containers.conf settings, or the default settings.
+
+[containers]
+
+# List of devices. Specified as
+# "<device-on-host>:<device-on-container>:<permissions>", for example:
+# "/dev/sdc:/dev/xvdc:rwm".
+# If it is empty or commented out, only the default devices will be used
+#
+# devices = []
+
+# List of volumes. Specified as
+# "<directory-on-host>:<directory-in-container>:<options>", for example:
+# "/db:/var/lib/db:ro".
+# If it is empty or commented out, no volumes will be added
+#
+# volumes = []
+
+# Used to change the name of the default AppArmor profile of container engine.
+#
+# apparmor_profile = "container-default"
+
+# List of annotation. Specified as
+# "key=value"
+# If it is empty or commented out, no annotations will be added
+#
+# annotations = []
+
+# Default way to to create a cgroup namespace for the container
+# Options are:
+# `private` Create private Cgroup Namespace for the container.
+# `host` Share host Cgroup Namespace with the container.
+#
+# cgroupns = "private"
+
+# List of default capabilities for containers. If it is empty or commented out,
+# the default capabilities defined in the container engine will be added.
+#
+# default_capabilities = [
+# "AUDIT_WRITE",
+# "CHOWN",
+# "DAC_OVERRIDE",
+# "FOWNER",
+# "FSETID",
+# "KILL",
+# "MKNOD",
+# "NET_BIND_SERVICE",
+# "NET_RAW",
+# "SETGID",
+# "SETPCAP",
+# "SETUID",
+# "SYS_CHROOT",
+# ]
+
+# A list of sysctls to be set in containers by default,
+# specified as "name=value",
+# for example:"net.ipv4.ping_group_range = 0 1000".
+#
+# default_sysctls = [
+# "net.ipv4.ping_group_range=0 1000",
+# ]
+
+# A list of ulimits to be set in containers by default, specified as
+# "<ulimit name>=<soft limit>:<hard limit>", for example:
+# "nofile=1024:2048"
+# See setrlimit(2) for a list of resource names.
+# Any limit not specified here will be inherited from the process launching the
+# container engine.
+# Ulimits has limits for non privileged container engines.
+#
+# default_ulimits = [
+# “nofile”=”1280:2560”,
+# ]
+
+# List of default DNS options to be added to /etc/resolv.conf inside of the container.
+#
+# dns_options = []
+
+# List of default DNS search domains to be added to /etc/resolv.conf inside of the container.
+#
+# dns_searches = []
+
+# Set default DNS servers.
+# This option can be used to override the DNS configuration passed to the
+# container. The special value “none” can be specified to disable creation of
+# /etc/resolv.conf in the container.
+# The /etc/resolv.conf file in the image will be used without changes.
+#
+# dns_servers = []
+
+# Environment variable list for the conmon process; used for passing necessary
+# environment variables to conmon or the runtime.
+#
+# env = [
+# "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
+# ]
+
+# Pass all host environment variables into the container.
+#
+# env_host = false
+
+# Path to OCI hooks directories for automatically executed hooks.
+#
+# hooks_dir = [
+# “/usr/share/containers/oci/hooks.d”,
+# ]
+
+# Default proxy environment variables passed into the container.
+# The environment variables passed in include:
+# http_proxy, https_proxy, ftp_proxy, no_proxy, and the upper case versions of
+# these. This option is needed when host system uses a proxy but container
+# should not use proxy. Proxy environment variables specified for the container
+# in any other way will override the values passed from the host.
+#
+# http_proxy = true
+
+# Run an init inside the container that forwards signals and reaps processes.
+#
+# init = false
+
+# Container init binary, if init=true, this is the init binary to be used for containers.
+#
+# init_path = "/usr/libexec/podman/catatonit"
+
+# Default way to to create an IPC namespace (POSIX SysV IPC) for the container
+# Options are:
+# `private` Create private IPC Namespace for the container.
+# `host` Share host IPC Namespace with the container.
+#
+# ipcns = "private"
+
+# Flag tells container engine to whether to use container separation using
+# MAC(SELinux)labeling or not.
+# Flag is ignored on label disabled systems.
+#
+# label = true
+
+# Logging driver for the container. Available options: k8s-file and journald.
+#
+# log_driver = "k8s-file"
+
+# Maximum size allowed for the container log file. Negative numbers indicate
+# that no size limit is imposed. If positive, it must be >= 8192 to match or
+# exceed conmon's read buffer. The file is truncated and re-opened so the
+# limit is never exceeded.
+#
+# log_size_max = -1
+
+# Default way to to create a Network namespace for the container
+# Options are:
+# `private` Create private Network Namespace for the container.
+# `host` Share host Network Namespace with the container.
+# `none` Containers do not use the network
+#
+# netns = "private"
+
+# Create /etc/hosts for the container. By default, container engine manage
+# /etc/hosts, automatically adding the container's own IP address.
+#
+# no_hosts = false
+
+# Maximum number of processes allowed in a container.
+#
+# pids_limit = 2048
+
+# Default way to to create a PID namespace for the container
+# Options are:
+# `private` Create private PID Namespace for the container.
+# `host` Share host PID Namespace with the container.
+#
+# pidns = "private"
+
+# Path to the seccomp.json profile which is used as the default seccomp profile
+# for the runtime.
+#
+# seccomp_profile = "/usr/share/containers/seccomp.json"
+
+# Size of /dev/shm. Specified as <number><unit>.
+# Unit is optional, values:
+# b (bytes), k (kilobytes), m (megabytes), or g (gigabytes).
+# If the unit is omitted, the system uses bytes.
+#
+# shm_size = "65536k"
+
+# Default way to to create a UTS namespace for the container
+# Options are:
+# `private` Create private UTS Namespace for the container.
+# `host` Share host UTS Namespace with the container.
+#
+# utsns = "private"
+
+# Default way to to create a User namespace for the container
+# Options are:
+# `auto` Create unique User Namespace for the container.
+# `host` Share host User Namespace with the container.
+#
+# userns = "host"
+
+# Number of UIDs to allocate for the automatic container creation.
+# UIDs are allocated from the “container” UIDs listed in
+# /etc/subuid & /etc/subgid
+#
+# userns_size=65536
+
+# The network table contains settings pertaining to the management of
+# CNI plugins.
+
+[network]
+
+# Path to directory where CNI plugin binaries are located.
+#
+# cni_plugin_dirs = ["/usr/libexec/cni"]
+
+# Path to the directory where CNI configuration files are located.
+#
+# network_config_dir = "/etc/cni/net.d/"
+
+[engine]
+
+# Cgroup management implementation used for the runtime.
+# Valid options “systemd” or “cgroupfs”
+#
+# cgroup_manager = "systemd"
+
+# Environment variables to pass into conmon
+#
+# conmon_env_vars = [
+# "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
+# ]
+
+# Paths to look for the conmon container manager binary
+#
+# conmon_path = [
+# "/usr/libexec/podman/conmon",
+# "/usr/local/libexec/podman/conmon",
+# "/usr/local/lib/podman/conmon",
+# "/usr/bin/conmon",
+# "/usr/sbin/conmon",
+# "/usr/local/bin/conmon",
+# "/usr/local/sbin/conmon"
+# ]
+
+# Specify the keys sequence used to detach a container.
+# Format is a single character [a-Z] or a comma separated sequence of
+# `ctrl-<value>`, where `<value>` is one of:
+# `a-z`, `@`, `^`, `[`, `\`, `]`, `^` or `_`
+#
+# detach_keys = "ctrl-p,ctrl-q"
+
+# Determines whether engine will reserve ports on the host when they are
+# forwarded to containers. When enabled, when ports are forwarded to containers,
+# ports are held open by as long as the container is running, ensuring that
+# they cannot be reused by other programs on the host. However, this can cause
+# significant memory usage if a container has many ports forwarded to it.
+# Disabling this can save memory.
+#
+# enable_port_reservation = true
+
+# Selects which logging mechanism to use for container engine events.
+# Valid values are `journald`, `file` and `none`.
+#
+# events_logger = "journald"
+
+# Default transport method for pulling and pushing for images
+#
+# image_default_transport = "docker://"
+
+# Default command to run the infra container
+#
+# infra_command = "/pause"
+
+# Infra (pause) container image name for pod infra containers. When running a
+# pod, we start a `pause` process in a container to hold open the namespaces
+# associated with the pod. This container does nothing other then sleep,
+# reserving the pods resources for the lifetime of the pod.
+#
+# infra_image = "k8s.gcr.io/pause:3.1"
+
+# Specify the locking mechanism to use; valid values are "shm" and "file".
+# Change the default only if you are sure of what you are doing, in general
+# "file" is useful only on platforms where cgo is not available for using the
+# faster "shm" lock type. You may need to run "podman system renumber" after
+# you change the lock type.
+#
+# lock_type** = "shm"
+
+# Default engine namespace
+# If engine is joined to a namespace, it will see only containers and pods
+# that were created in the same namespace, and will create new containers and
+# pods in that namespace.
+# The default namespace is "", which corresponds to no namespace. When no
+# namespace is set, all containers and pods are visible.
+#
+# namespace = ""
+
+# Whether to use chroot instead of pivot_root in the runtime
+#
+# no_pivot_root = false
+
+# Number of locks available for containers and pods.
+# If this is changed, a lock renumber must be performed (e.g. with the
+# 'podman system renumber' command).
+#
+# num_locks = 2048
+
+# Whether to pull new image before running a container
+# pull_policy = "missing"
+
+# Directory for persistent engine files (database, etc)
+# By default, this will be configured relative to where the containers/storage
+# stores containers
+# Uncomment to change location from this default
+#
+# static_dir = "/var/lib/containers/storage/libpod"
+
+# Directory for temporary files. Must be tmpfs (wiped after reboot)
+#
+# tmp_dir = "/var/run/libpod"
+
+# Directory for libpod named volumes.
+# By default, this will be configured relative to where containers/storage
+# stores containers.
+# Uncomment to change location from this default.
+#
+# volume_path = "/var/lib/containers/storage/volumes"
+
+# Default OCI runtime
+#
+# runtime = "runc"
+
+# List of the OCI runtimes that support --format=json. When json is supported
+# engine will use it for reporting nicer errors.
+#
+# runtime_supports_json = ["crun", "runc"]
+
+# Paths to look for a valid OCI runtime (runc, runv, etc)
+[engine.runtimes]
+# runc = [
+# "/usr/bin/runc",
+# "/usr/sbin/runc",
+# "/usr/local/bin/runc",
+# "/usr/local/sbin/runc",
+# "/sbin/runc",
+# "/bin/runc",
+# "/usr/lib/cri-o-runc/sbin/runc",
+# ]
+
+# crun = [
+# "/usr/bin/crun",
+# "/usr/sbin/crun",
+# "/usr/local/bin/crun",
+# "/usr/local/sbin/crun",
+# "/sbin/crun",
+# "/bin/crun",
+# "/run/current-system/sw/bin/crun",
+# ]
+
+# Number of seconds to wait for container to exit before sending kill signal.
+#stop_timeout = 10
+
+# The [engine.runtimes] table MUST be the last entry in this file.
+# (Unless another table is added)
+# TOML does not provide a way to end a table other than a further table being
+# defined, so every key hereafter will be part of [runtimes] and not the main
+# config.
diff --git a/vendor/github.com/containers/common/pkg/config/default.go b/vendor/github.com/containers/common/pkg/config/default.go
new file mode 100644
index 000000000..04c3f9773
--- /dev/null
+++ b/vendor/github.com/containers/common/pkg/config/default.go
@@ -0,0 +1,346 @@
+package config
+
+import (
+ "bytes"
+ "os"
+ "os/exec"
+ "path/filepath"
+ "regexp"
+ "strconv"
+
+ "github.com/containers/common/pkg/unshare"
+ "github.com/containers/storage"
+ "github.com/pkg/errors"
+ "github.com/sirupsen/logrus"
+)
+
+const (
+ // _conmonMinMajorVersion is the major version required for conmon.
+ _conmonMinMajorVersion = 2
+
+ // _conmonMinMinorVersion is the minor version required for conmon.
+ _conmonMinMinorVersion = 0
+
+ // _conmonMinPatchVersion is the sub-minor version required for conmon.
+ _conmonMinPatchVersion = 1
+
+ // _conmonVersionFormatErr is used when the expected versio-format of conmon
+ // has changed.
+ _conmonVersionFormatErr = "conmon version changed format"
+
+ // _defaultGraphRoot points to the default path of the graph root.
+ _defaultGraphRoot = "/var/lib/containers/storage"
+
+ // _defaultTransport is a prefix that we apply to an image name to check
+ // docker hub first for the image.
+ _defaultTransport = "docker://"
+)
+
+var (
+ // DefaultInitPath is the default path to the container-init binary
+ DefaultInitPath = "/usr/libexec/podman/catatonit"
+ // DefaultInfraImage to use for infra container
+ DefaultInfraImage = "k8s.gcr.io/pause:3.1"
+ // DefaultInfraCommand to be run in an infra container
+ DefaultInfraCommand = "/pause"
+ // DefaultRootlessSHMLockPath is the default path for rootless SHM locks
+ DefaultRootlessSHMLockPath = "/libpod_rootless_lock"
+ // DefaultDetachKeys is the default keys sequence for detaching a
+ // container
+ DefaultDetachKeys = "ctrl-p,ctrl-q"
+)
+
+var (
+ // ErrConmonOutdated indicates the version of conmon found (whether via the configuration or $PATH)
+ // is out of date for the current podman version
+ ErrConmonOutdated = errors.New("outdated conmon version")
+ // ErrInvalidArg indicates that an invalid argument was passed
+ ErrInvalidArg = errors.New("invalid argument")
+ // DefaultHooksDirs defines the default hooks directory
+ DefaultHooksDirs = []string{"/usr/share/containers/oci/hooks.d"}
+ // DefaultCapabilities for the default_capabilities option in the containers.conf file
+ DefaultCapabilities = []string{
+ "CAP_AUDIT_WRITE",
+ "CAP_CHOWN",
+ "CAP_DAC_OVERRIDE",
+ "CAP_FOWNER",
+ "CAP_FSETID",
+ "CAP_KILL",
+ "CAP_MKNOD",
+ "CAP_NET_BIND_SERVICE",
+ "CAP_NET_RAW",
+ "CAP_SETFCAP",
+ "CAP_SETGID",
+ "CAP_SETPCAP",
+ "CAP_SETUID",
+ "CAP_SYS_CHROOT",
+ }
+)
+
+const (
+ // EtcDir is the sysconfdir where podman should look for system config files.
+ // It can be overridden at build time.
+ _etcDir = "/etc"
+ // InstallPrefix is the prefix where podman will be installed.
+ // It can be overridden at build time.
+ _installPrefix = "/usr"
+ // CgroupfsCgroupsManager represents cgroupfs native cgroup manager
+ CgroupfsCgroupsManager = "cgroupfs"
+ // DefaultApparmorProfile specifies the default apparmor profile for the container.
+ DefaultApparmorProfile = "container-default"
+ // SystemdCgroupsManager represents systemd native cgroup manager
+ SystemdCgroupsManager = "systemd"
+ // DefaultLogDriver is the default type of log files
+ DefaultLogDriver = "k8s-file"
+ // DefaultLogSizeMax is the default value for the maximum log size
+ // allowed for a container. Negative values mean that no limit is imposed.
+ DefaultLogSizeMax = -1
+ // DefaultPidsLimit is the default value for maximum number of processes
+ // allowed inside a container
+ DefaultPidsLimit = 2048
+ // DefaultPullPolicy pulls the image if it does not exist locally
+ DefaultPullPolicy = "missing"
+ // DefaultRootlessSignaturePolicyPath is the default value for the
+ // rootless policy.json file.
+ DefaultRootlessSignaturePolicyPath = ".config/containers/policy.json"
+ // DefaultShmSize default value
+ DefaultShmSize = "65536k"
+ // DefaultUserNSSize default value
+ DefaultUserNSSize = 65536
+ // OCIBufSize limits maximum LogSizeMax
+ OCIBufSize = 8192
+ // SeccompOverridePath if this exists it overrides the default seccomp path.
+ SeccompOverridePath = _etcDir + "/containers/seccomp.json"
+ // SeccompDefaultPath defines the default seccomp path.
+ SeccompDefaultPath = _installPrefix + "/share/containers/seccomp.json"
+)
+
+// DefaultConfig defines the default values from containers.conf
+func DefaultConfig() (*Config, error) {
+
+ defaultEngineConfig, err := defaultConfigFromMemory()
+ if err != nil {
+ return nil, err
+ }
+
+ netns := "bridge"
+ if unshare.IsRootless() {
+ home, err := unshare.HomeDir()
+ if err != nil {
+ return nil, err
+ }
+ sigPath := filepath.Join(home, DefaultRootlessSignaturePolicyPath)
+ if _, err := os.Stat(sigPath); err == nil {
+ defaultEngineConfig.SignaturePolicyPath = sigPath
+ }
+ netns = "slirp4netns"
+ }
+
+ return &Config{
+ Containers: ContainersConfig{
+ Devices: []string{},
+ Volumes: []string{},
+ Annotations: []string{},
+ ApparmorProfile: DefaultApparmorProfile,
+ CgroupNS: "private",
+ DefaultCapabilities: DefaultCapabilities,
+ DefaultSysctls: []string{},
+ DefaultUlimits: getDefaultProcessLimits(),
+ DNSServers: []string{},
+ DNSOptions: []string{},
+ DNSSearches: []string{},
+ EnableLabeling: selinuxEnabled(),
+ Env: []string{
+ "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
+ },
+ EnvHost: false,
+ HTTPProxy: false,
+ Init: false,
+ InitPath: "",
+ IPCNS: "private",
+ LogDriver: DefaultLogDriver,
+ LogSizeMax: DefaultLogSizeMax,
+ NetNS: netns,
+ NoHosts: false,
+ PidsLimit: DefaultPidsLimit,
+ PidNS: "private",
+ SeccompProfile: SeccompDefaultPath,
+ ShmSize: DefaultShmSize,
+ UTSNS: "private",
+ UserNS: "private",
+ UserNSSize: DefaultUserNSSize,
+ },
+ Network: NetworkConfig{
+ DefaultNetwork: "podman",
+ NetworkConfigDir: cniConfigDir,
+ CNIPluginDirs: cniBinDir,
+ },
+ Engine: *defaultEngineConfig,
+ }, nil
+}
+
+// defaultConfigFromMemory returns a default engine configuration. Note that the
+// config is different for root and rootless. It also parses the storage.conf.
+func defaultConfigFromMemory() (*EngineConfig, error) {
+ c := new(EngineConfig)
+ tmp, err := defaultTmpDir()
+ if err != nil {
+ return nil, err
+ }
+ c.TmpDir = tmp
+
+ c.EventsLogFilePath = filepath.Join(c.TmpDir, "events", "events.log")
+
+ storeOpts, err := storage.DefaultStoreOptions(unshare.IsRootless(), unshare.GetRootlessUID())
+ if err != nil {
+ return nil, err
+ }
+ if storeOpts.GraphRoot == "" {
+ logrus.Warnf("Storage configuration is unset - using hardcoded default graph root %q", _defaultGraphRoot)
+ storeOpts.GraphRoot = _defaultGraphRoot
+ }
+ c.StaticDir = filepath.Join(storeOpts.GraphRoot, "libpod")
+ c.VolumePath = filepath.Join(storeOpts.GraphRoot, "volumes")
+
+ c.HooksDir = DefaultHooksDirs
+ c.ImageDefaultTransport = _defaultTransport
+ c.StateType = BoltDBStateStore
+
+ c.OCIRuntime = "runc"
+ // If we're running on cgroups v2, default to using crun.
+ if onCgroupsv2, _ := isCgroup2UnifiedMode(); onCgroupsv2 {
+ c.OCIRuntime = "crun"
+ }
+ c.CgroupManager = SystemdCgroupsManager
+ c.StopTimeout = uint(10)
+
+ c.OCIRuntimes = map[string][]string{
+ "runc": {
+ "/usr/bin/runc",
+ "/usr/sbin/runc",
+ "/usr/local/bin/runc",
+ "/usr/local/sbin/runc",
+ "/sbin/runc",
+ "/bin/runc",
+ "/usr/lib/cri-o-runc/sbin/runc",
+ "/run/current-system/sw/bin/runc",
+ },
+ "crun": {
+ "/usr/bin/crun",
+ "/usr/sbin/crun",
+ "/usr/local/bin/crun",
+ "/usr/local/sbin/crun",
+ "/sbin/crun",
+ "/bin/crun",
+ "/run/current-system/sw/bin/crun",
+ },
+ }
+ c.ConmonEnvVars = []string{
+ "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
+ }
+ c.ConmonPath = []string{
+ "/usr/libexec/podman/conmon",
+ "/usr/local/libexec/podman/conmon",
+ "/usr/local/lib/podman/conmon",
+ "/usr/bin/conmon",
+ "/usr/sbin/conmon",
+ "/usr/local/bin/conmon",
+ "/usr/local/sbin/conmon",
+ "/run/current-system/sw/bin/conmon",
+ }
+ c.PullPolicy = DefaultPullPolicy
+ c.RuntimeSupportsJSON = []string{
+ "crun",
+ "runc",
+ }
+ c.RuntimeSupportsNoCgroups = []string{"crun"}
+ c.InitPath = DefaultInitPath
+ c.NoPivotRoot = false
+
+ c.InfraCommand = DefaultInfraCommand
+ c.InfraImage = DefaultInfraImage
+ c.EnablePortReservation = true
+ c.NumLocks = 2048
+ c.EventsLogger = "journald"
+ c.DetachKeys = DefaultDetachKeys
+ c.SDNotify = false
+ // TODO - ideally we should expose a `type LockType string` along with
+ // constants.
+ c.LockType = "shm"
+
+ return c, nil
+}
+
+func defaultTmpDir() (string, error) {
+ if !unshare.IsRootless() {
+ return "/var/run/libpod", nil
+ }
+
+ runtimeDir, err := getRuntimeDir()
+ if err != nil {
+ return "", err
+ }
+ libpodRuntimeDir := filepath.Join(runtimeDir, "libpod")
+
+ if err := os.Mkdir(libpodRuntimeDir, 0700|os.ModeSticky); err != nil {
+ if !os.IsExist(err) {
+ return "", errors.Wrapf(err, "cannot mkdir %s", libpodRuntimeDir)
+ } else if err := os.Chmod(libpodRuntimeDir, 0700|os.ModeSticky); err != nil {
+ // The directory already exist, just set the sticky bit
+ return "", errors.Wrapf(err, "could not set sticky bit on %s", libpodRuntimeDir)
+ }
+ }
+ return filepath.Join(libpodRuntimeDir, "tmp"), nil
+}
+
+// probeConmon calls conmon --version and verifies it is a new enough version for
+// the runtime expectations the container engine currently has.
+func probeConmon(conmonBinary string) error {
+ cmd := exec.Command(conmonBinary, "--version")
+ var out bytes.Buffer
+ cmd.Stdout = &out
+ err := cmd.Run()
+ if err != nil {
+ return err
+ }
+ r := regexp.MustCompile(`^conmon version (?P<Major>\d+).(?P<Minor>\d+).(?P<Patch>\d+)`)
+
+ matches := r.FindStringSubmatch(out.String())
+ if len(matches) != 4 {
+ return errors.Wrap(err, _conmonVersionFormatErr)
+ }
+ major, err := strconv.Atoi(matches[1])
+ if err != nil {
+ return errors.Wrap(err, _conmonVersionFormatErr)
+ }
+ if major < _conmonMinMajorVersion {
+ return ErrConmonOutdated
+ }
+ if major > _conmonMinMajorVersion {
+ return nil
+ }
+
+ minor, err := strconv.Atoi(matches[2])
+ if err != nil {
+ return errors.Wrap(err, _conmonVersionFormatErr)
+ }
+ if minor < _conmonMinMinorVersion {
+ return ErrConmonOutdated
+ }
+ if minor > _conmonMinMinorVersion {
+ return nil
+ }
+
+ patch, err := strconv.Atoi(matches[3])
+ if err != nil {
+ return errors.Wrap(err, _conmonVersionFormatErr)
+ }
+ if patch < _conmonMinPatchVersion {
+ return ErrConmonOutdated
+ }
+ if patch > _conmonMinPatchVersion {
+ return nil
+ }
+
+ return nil
+}
diff --git a/vendor/github.com/containers/common/pkg/config/default_linux.go b/vendor/github.com/containers/common/pkg/config/default_linux.go
new file mode 100644
index 000000000..91b73d344
--- /dev/null
+++ b/vendor/github.com/containers/common/pkg/config/default_linux.go
@@ -0,0 +1,55 @@
+package config
+
+import (
+ "fmt"
+ "io/ioutil"
+ "strconv"
+ "strings"
+ "syscall"
+
+ "golang.org/x/sys/unix"
+)
+
+// isCgroup2UnifiedMode returns whether we are running in cgroup2 mode.
+func isCgroup2UnifiedMode() (isUnified bool, isUnifiedErr error) {
+ cgroupRoot := "/sys/fs/cgroup"
+
+ var st syscall.Statfs_t
+ if err := syscall.Statfs(cgroupRoot, &st); err != nil {
+ isUnified, isUnifiedErr = false, err
+ } else {
+ isUnified, isUnifiedErr = int64(st.Type) == int64(unix.CGROUP2_SUPER_MAGIC), nil
+ }
+ return
+}
+
+const (
+ oldMaxSize = uint64(1048576)
+)
+
+// getDefaultProcessLimits returns the nproc for the current process in ulimits format
+// Note that nfile sometimes cannot be set to unlimited, and the limit is hardcoded
+// to (oldMaxSize) 1048576 (2^20), see: http://stackoverflow.com/a/1213069/1811501
+// In rootless containers this will fail, and the process will just use its current limits
+func getDefaultProcessLimits() []string {
+ rlim := unix.Rlimit{Cur: oldMaxSize, Max: oldMaxSize}
+ oldrlim := rlim
+ // Attempt to set file limit and process limit to pid_max in OS
+ dat, err := ioutil.ReadFile("/proc/sys/kernel/pid_max")
+ if err == nil {
+ val := strings.TrimSuffix(string(dat), "\n")
+ max, err := strconv.ParseUint(val, 10, 64)
+ if err == nil {
+ rlim = unix.Rlimit{Cur: uint64(max), Max: uint64(max)}
+ }
+ }
+ defaultLimits := []string{}
+ if err := unix.Setrlimit(unix.RLIMIT_NPROC, &rlim); err == nil {
+ defaultLimits = append(defaultLimits, fmt.Sprintf("nproc=%d:%d", rlim.Cur, rlim.Max))
+ } else {
+ if err := unix.Setrlimit(unix.RLIMIT_NPROC, &oldrlim); err == nil {
+ defaultLimits = append(defaultLimits, fmt.Sprintf("nproc=%d:%d", oldrlim.Cur, oldrlim.Max))
+ }
+ }
+ return defaultLimits
+}
diff --git a/vendor/github.com/containers/common/pkg/config/default_unsupported.go b/vendor/github.com/containers/common/pkg/config/default_unsupported.go
new file mode 100644
index 000000000..1ae1dd12c
--- /dev/null
+++ b/vendor/github.com/containers/common/pkg/config/default_unsupported.go
@@ -0,0 +1,13 @@
+// +build !linux
+
+package config
+
+// isCgroup2UnifiedMode returns whether we are running in cgroup2 mode.
+func isCgroup2UnifiedMode() (isUnified bool, isUnifiedErr error) {
+ return false, nil
+}
+
+// getDefaultProcessLimits returns the nofile and nproc for the current process in ulimits format
+func getDefaultProcessLimits() []string {
+ return []string{}
+}
diff --git a/vendor/github.com/containers/common/pkg/config/libpodConfig.go b/vendor/github.com/containers/common/pkg/config/libpodConfig.go
new file mode 100644
index 000000000..333f43815
--- /dev/null
+++ b/vendor/github.com/containers/common/pkg/config/libpodConfig.go
@@ -0,0 +1,382 @@
+package config
+
+/* libpodConfig.go contains deprecated functionality and should not be used any longer */
+
+import (
+ "fmt"
+ "os"
+ "os/exec"
+ "path/filepath"
+
+ "github.com/BurntSushi/toml"
+ "github.com/containers/common/pkg/unshare"
+ "github.com/pkg/errors"
+ "github.com/sirupsen/logrus"
+)
+
+const (
+ // _rootlessConfigPath is the path to the rootless libpod.conf in $HOME.
+ _rootlessConfigPath = ".config/containers/libpod.conf"
+
+ // _rootConfigPath is the path to the libpod configuration file
+ // This file is loaded to replace the builtin default config before
+ // runtime options (e.g. WithStorageConfig) are applied.
+ // If it is not present, the builtin default config is used instead
+ // This path can be overridden when the runtime is created by using
+ // NewRuntimeFromConfig() instead of NewRuntime().
+ _rootConfigPath = _installPrefix + "/share/containers/libpod.conf"
+
+ // _rootOverrideConfigPath is the path to an override for the default libpod
+ // configuration file. If OverrideConfigPath exists, it will be used in
+ // place of the configuration file pointed to by ConfigPath.
+ _rootOverrideConfigPath = _etcDir + "/containers/libpod.conf"
+)
+
+// ConfigFromLibpod contains configuration options used to set up a libpod runtime
+type ConfigFromLibpod struct {
+ // NOTE: when changing this struct, make sure to update (*Config).Merge().
+
+ // SetOptions contains a subset of config options. It's used to indicate if
+ // a given option has either been set by the user or by a parsed libpod
+ // configuration file. If not, the corresponding option might be
+ // overwritten by values from the database. This behavior guarantees
+ // backwards compat with older version of libpod and Podman.
+ SetOptions
+
+ // VolumePath is the default location that named volumes will be created
+ // under. This convention is followed by the default volume driver, but
+ // may not be by other drivers.
+ VolumePath string `toml:"volume_path,omitempty"`
+
+ // ImageDefaultTransport is the default transport method used to fetch
+ // images.
+ ImageDefaultTransport string `toml:"image_default_transport,omitempty"`
+
+ // SignaturePolicyPath is the path to a signature policy to use for
+ // validating images. If left empty, the containers/image default signature
+ // policy will be used.
+ SignaturePolicyPath string `toml:"signature_policy_path,omitempty"`
+
+ // OCIRuntime is the OCI runtime to use.
+ OCIRuntime string `toml:"runtime,omitempty"`
+
+ // OCIRuntimes are the set of configured OCI runtimes (default is runc).
+ OCIRuntimes map[string][]string `toml:"runtimes,omitempty"`
+
+ // RuntimeSupportsJSON is the list of the OCI runtimes that support
+ // --format=json.
+ RuntimeSupportsJSON []string `toml:"runtime_supports_json,omitempty"`
+
+ // RuntimeSupportsNoCgroups is a list of OCI runtimes that support
+ // running containers without CGroups.
+ RuntimeSupportsNoCgroups []string `toml:"runtime_supports_nocgroups,omitempty"`
+
+ // RuntimePath is the path to OCI runtime binary for launching containers.
+ // The first path pointing to a valid file will be used This is used only
+ // when there are no OCIRuntime/OCIRuntimes defined. It is used only to be
+ // backward compatible with older versions of Podman.
+ RuntimePath []string `toml:"runtime_path,omitempty"`
+
+ // ConmonPath is the path to the Conmon binary used for managing containers.
+ // The first path pointing to a valid file will be used.
+ ConmonPath []string `toml:"conmon_path,omitempty"`
+
+ // ConmonEnvVars are environment variables to pass to the Conmon binary
+ // when it is launched.
+ ConmonEnvVars []string `toml:"conmon_env_vars,omitempty"`
+
+ // CGroupManager is the CGroup Manager to use Valid values are "cgroupfs"
+ // and "systemd".
+ CgroupManager string `toml:"cgroup_manager,omitempty"`
+
+ // InitPath is the path to the container-init binary.
+ InitPath string `toml:"init_path,omitempty"`
+
+ // StaticDir is the path to a persistent directory to store container
+ // files.
+ StaticDir string `toml:"static_dir,omitempty"`
+
+ // TmpDir is the path to a temporary directory to store per-boot container
+ // files. Must be stored in a tmpfs.
+ TmpDir string `toml:"tmp_dir,omitempty"`
+
+ // MaxLogSize is the maximum size of container logfiles.
+ MaxLogSize int64 `toml:"max_log_size,omitempty"`
+
+ // NoPivotRoot sets whether to set no-pivot-root in the OCI runtime.
+ NoPivotRoot bool `toml:"no_pivot_root,omitempty"`
+
+ // CNIConfigDir sets the directory where CNI configuration files are
+ // stored.
+ CNIConfigDir string `toml:"cni_config_dir,omitempty"`
+
+ // CNIPluginDir sets a number of directories where the CNI network
+ // plugins can be located.
+ CNIPluginDir []string `toml:"cni_plugin_dir,omitempty"`
+
+ // CNIDefaultNetwork is the network name of the default CNI network
+ // to attach pods to.
+ CNIDefaultNetwork string `toml:"cni_default_network,omitempty"`
+
+ // HooksDir holds paths to the directories containing hooks
+ // configuration files. When the same filename is present in in
+ // multiple directories, the file in the directory listed last in
+ // this slice takes precedence.
+ HooksDir []string `toml:"hooks_dir,omitempty"`
+
+ // Namespace is the libpod namespace to use. Namespaces are used to create
+ // scopes to separate containers and pods in the state. When namespace is
+ // set, libpod will only view containers and pods in the same namespace. All
+ // containers and pods created will default to the namespace set here. A
+ // namespace of "", the empty string, is equivalent to no namespace, and all
+ // containers and pods will be visible. The default namespace is "".
+ Namespace string `toml:"namespace,omitempty"`
+
+ // InfraImage is the image a pod infra container will use to manage
+ // namespaces.
+ InfraImage string `toml:"infra_image,omitempty"`
+
+ // InfraCommand is the command run to start up a pod infra container.
+ InfraCommand string `toml:"infra_command,omitempty"`
+
+ // EnablePortReservation determines whether libpod will reserve ports on the
+ // host when they are forwarded to containers. When enabled, when ports are
+ // forwarded to containers, they are held open by conmon as long as the
+ // container is running, ensuring that they cannot be reused by other
+ // programs on the host. However, this can cause significant memory usage if
+ // a container has many ports forwarded to it. Disabling this can save
+ // memory.
+ EnablePortReservation bool `toml:"enable_port_reservation,omitempty"`
+
+ // EnableLabeling indicates whether libpod will support container labeling.
+ EnableLabeling bool `toml:"label,omitempty"`
+
+ // NetworkCmdPath is the path to the slirp4netns binary.
+ NetworkCmdPath string `toml:"network_cmd_path,omitempty"`
+
+ // NumLocks is the number of locks to make available for containers and
+ // pods.
+ NumLocks uint32 `toml:"num_locks,omitempty"`
+
+ // LockType is the type of locking to use.
+ LockType string `toml:"lock_type,omitempty"`
+
+ // EventsLogger determines where events should be logged.
+ EventsLogger string `toml:"events_logger,omitempty"`
+
+ // EventsLogFilePath is where the events log is stored.
+ EventsLogFilePath string `toml:"events_logfile_path,omitempty"`
+
+ //DetachKeys is the sequence of keys used to detach a container.
+ DetachKeys string `toml:"detach_keys,omitempty"`
+
+ // SDNotify tells Libpod to allow containers to notify the host systemd of
+ // readiness using the SD_NOTIFY mechanism.
+ SDNotify bool `toml:",omitempty"`
+
+ // CgroupCheck indicates the configuration has been rewritten after an
+ // upgrade to Fedora 31 to change the default OCI runtime for cgroupsv2.
+ CgroupCheck bool `toml:"cgroup_check,omitempty"`
+}
+
+// newLibpodConfig creates a new ConfigFromLibpod and converts it to Config.
+// Depending if we're running as root or rootless, we then merge the system configuration followed
+// by merging the default config (hard-coded default in memory).
+// Note that the OCI runtime is hard-set to `crun` if we're running on a system
+// with cgroupsv2. Other OCI runtimes are not yet supporting cgroupsv2. This
+// might change in the future.
+func newLibpodConfig(c *Config) error {
+ // Start with the default config and interatively merge
+ // fields in the system configs.
+ config := c.libpodConfig()
+
+ // Now, check if the user can access system configs and merge them if needed.
+ configs, err := systemLibpodConfigs()
+ if err != nil {
+ return errors.Wrapf(err, "error finding config on system")
+ }
+
+ for _, path := range configs {
+ config, err = readLibpodConfigFromFile(path, config)
+ if err != nil {
+ return errors.Wrapf(err, "error reading system config %q", path)
+ }
+ }
+
+ // Since runc does not currently support cgroupV2
+ // Change to default crun on first running of libpod.conf
+ // TODO Once runc has support for cgroups, this function should be removed.
+ if !config.CgroupCheck && unshare.IsRootless() {
+ cgroupsV2, err := isCgroup2UnifiedMode()
+ if err != nil {
+ return err
+ }
+ if cgroupsV2 {
+ path, err := exec.LookPath("crun")
+ if err != nil {
+ // Can't find crun path so do nothing
+ logrus.Warnf("Can not find crun package on the host, containers might fail to run on cgroup V2 systems without crun: %q", err)
+ } else {
+ config.CgroupCheck = true
+ config.OCIRuntime = path
+ }
+ }
+ }
+
+ c.libpodToContainersConfig(config)
+
+ return nil
+}
+
+// readConfigFromFile reads the specified config file at `path` and attempts to
+// unmarshal its content into a Config. The config param specifies the previous
+// default config. If the path, only specifies a few fields in the Toml file
+// the defaults from the config parameter will be used for all other fields.
+func readLibpodConfigFromFile(path string, config *ConfigFromLibpod) (*ConfigFromLibpod, error) {
+ logrus.Debugf("Reading configuration file %q", path)
+ _, err := toml.DecodeFile(path, config)
+ if err != nil {
+ return nil, fmt.Errorf("unable to decode configuration %v: %v", path, err)
+ }
+
+ // For the sake of backwards compat we need to check if the config fields
+ // with *Set suffix are set in the config. Note that the storage-related
+ // fields are NOT set in the config here but in the storage.conf OR directly
+ // by the user.
+ if config.VolumePath != "" {
+ config.VolumePathSet = true
+ }
+ if config.StaticDir != "" {
+ config.StaticDirSet = true
+ }
+ if config.TmpDir != "" {
+ config.TmpDirSet = true
+ }
+
+ return config, err
+}
+
+func systemLibpodConfigs() ([]string, error) {
+ if unshare.IsRootless() {
+ path, err := rootlessLibpodConfigPath()
+ if err != nil {
+ return nil, err
+ }
+ if _, err := os.Stat(path); err == nil {
+ containersConfPath, err := rootlessConfigPath()
+ if err != nil {
+ containersConfPath = filepath.Join("$HOME", UserOverrideContainersConfig)
+ }
+ // TODO: Raise to Warnf, when Podman is updated to
+ // remove libpod.conf by default
+ logrus.Debugf("Found deprecated file %s, please remove. Use %s to override defaults.\n", path, containersConfPath)
+ return []string{path}, nil
+ }
+ return nil, err
+ }
+
+ configs := []string{}
+ if _, err := os.Stat(_rootConfigPath); err == nil {
+ // TODO: Raise to Warnf, when Podman is updated to
+ // remove libpod.conf by default
+ logrus.Debugf("Found deprecated file %s, please remove. Use %s to override defaults.\n", _rootConfigPath, OverrideContainersConfig)
+ configs = append(configs, _rootConfigPath)
+ }
+ if _, err := os.Stat(_rootOverrideConfigPath); err == nil {
+ // TODO: Raise to Warnf, when Podman is updated to
+ // remove libpod.conf by default
+ logrus.Debugf("Found deprecated file %s, please remove. Use %s to override defaults.\n", _rootOverrideConfigPath, OverrideContainersConfig)
+ configs = append(configs, _rootOverrideConfigPath)
+ }
+ return configs, nil
+}
+
+func rootlessLibpodConfigPath() (string, error) {
+ home, err := unshare.HomeDir()
+ if err != nil {
+ return "", err
+ }
+
+ return filepath.Join(home, _rootlessConfigPath), nil
+}
+
+func (c *Config) libpodConfig() *ConfigFromLibpod {
+ return &ConfigFromLibpod{
+ InitPath: c.Containers.InitPath,
+ MaxLogSize: c.Containers.LogSizeMax,
+ EnableLabeling: c.Containers.EnableLabeling,
+
+ SetOptions: c.Engine.SetOptions,
+ VolumePath: c.Engine.VolumePath,
+ ImageDefaultTransport: c.Engine.ImageDefaultTransport,
+ OCIRuntime: c.Engine.OCIRuntime,
+ OCIRuntimes: c.Engine.OCIRuntimes,
+ RuntimeSupportsJSON: c.Engine.RuntimeSupportsJSON,
+ RuntimeSupportsNoCgroups: c.Engine.RuntimeSupportsNoCgroups,
+ RuntimePath: c.Engine.RuntimePath,
+ ConmonPath: c.Engine.ConmonPath,
+ ConmonEnvVars: c.Engine.ConmonEnvVars,
+ CgroupManager: c.Engine.CgroupManager,
+ StaticDir: c.Engine.StaticDir,
+ TmpDir: c.Engine.TmpDir,
+ NoPivotRoot: c.Engine.NoPivotRoot,
+ HooksDir: c.Engine.HooksDir,
+ Namespace: c.Engine.Namespace,
+ InfraImage: c.Engine.InfraImage,
+ InfraCommand: c.Engine.InfraCommand,
+ EnablePortReservation: c.Engine.EnablePortReservation,
+ NetworkCmdPath: c.Engine.NetworkCmdPath,
+ NumLocks: c.Engine.NumLocks,
+ LockType: c.Engine.LockType,
+ EventsLogger: c.Engine.EventsLogger,
+ EventsLogFilePath: c.Engine.EventsLogFilePath,
+ DetachKeys: c.Engine.DetachKeys,
+ SDNotify: c.Engine.SDNotify,
+ CgroupCheck: c.Engine.CgroupCheck,
+ SignaturePolicyPath: c.Engine.SignaturePolicyPath,
+
+ CNIConfigDir: c.Network.NetworkConfigDir,
+ CNIPluginDir: c.Network.CNIPluginDirs,
+ CNIDefaultNetwork: c.Network.DefaultNetwork,
+ }
+}
+
+func (c *Config) libpodToContainersConfig(libpodConf *ConfigFromLibpod) {
+
+ c.Containers.InitPath = libpodConf.InitPath
+ c.Containers.LogSizeMax = libpodConf.MaxLogSize
+ c.Containers.EnableLabeling = libpodConf.EnableLabeling
+
+ c.Engine.SignaturePolicyPath = libpodConf.SignaturePolicyPath
+ c.Engine.SetOptions = libpodConf.SetOptions
+ c.Engine.VolumePath = libpodConf.VolumePath
+ c.Engine.ImageDefaultTransport = libpodConf.ImageDefaultTransport
+ c.Engine.OCIRuntime = libpodConf.OCIRuntime
+ c.Engine.OCIRuntimes = libpodConf.OCIRuntimes
+ c.Engine.RuntimeSupportsJSON = libpodConf.RuntimeSupportsJSON
+ c.Engine.RuntimeSupportsNoCgroups = libpodConf.RuntimeSupportsNoCgroups
+ c.Engine.RuntimePath = libpodConf.RuntimePath
+ c.Engine.ConmonPath = libpodConf.ConmonPath
+ c.Engine.ConmonEnvVars = libpodConf.ConmonEnvVars
+ c.Engine.CgroupManager = libpodConf.CgroupManager
+ c.Engine.StaticDir = libpodConf.StaticDir
+ c.Engine.TmpDir = libpodConf.TmpDir
+ c.Engine.NoPivotRoot = libpodConf.NoPivotRoot
+ c.Engine.HooksDir = libpodConf.HooksDir
+ c.Engine.Namespace = libpodConf.Namespace
+ c.Engine.InfraImage = libpodConf.InfraImage
+ c.Engine.InfraCommand = libpodConf.InfraCommand
+ c.Engine.EnablePortReservation = libpodConf.EnablePortReservation
+ c.Engine.NetworkCmdPath = libpodConf.NetworkCmdPath
+ c.Engine.NumLocks = libpodConf.NumLocks
+ c.Engine.LockType = libpodConf.LockType
+ c.Engine.EventsLogger = libpodConf.EventsLogger
+ c.Engine.EventsLogFilePath = libpodConf.EventsLogFilePath
+ c.Engine.DetachKeys = libpodConf.DetachKeys
+ c.Engine.SDNotify = libpodConf.SDNotify
+ c.Engine.CgroupCheck = libpodConf.CgroupCheck
+
+ c.Network.NetworkConfigDir = libpodConf.CNIConfigDir
+ c.Network.CNIPluginDirs = libpodConf.CNIPluginDir
+ c.Network.DefaultNetwork = libpodConf.CNIDefaultNetwork
+}
diff --git a/vendor/github.com/containers/common/pkg/config/util_supported.go b/vendor/github.com/containers/common/pkg/config/util_supported.go
new file mode 100644
index 000000000..101952f1d
--- /dev/null
+++ b/vendor/github.com/containers/common/pkg/config/util_supported.go
@@ -0,0 +1,69 @@
+// +build linux darwin
+
+package config
+
+import (
+ "fmt"
+ "os"
+ "path/filepath"
+ "sync"
+ "syscall"
+
+ "github.com/containers/common/pkg/unshare"
+ "github.com/pkg/errors"
+ "github.com/sirupsen/logrus"
+)
+
+var (
+ rootlessRuntimeDirOnce sync.Once
+ rootlessRuntimeDir string
+)
+
+// getRuntimeDir returns the runtime directory
+func getRuntimeDir() (string, error) {
+ var rootlessRuntimeDirError error
+
+ rootlessRuntimeDirOnce.Do(func() {
+ runtimeDir := os.Getenv("XDG_RUNTIME_DIR")
+ uid := fmt.Sprintf("%d", unshare.GetRootlessUID())
+ if runtimeDir == "" {
+ tmpDir := filepath.Join("/run", "user", uid)
+ if err := os.MkdirAll(tmpDir, 0700); err != nil {
+ logrus.Debugf("unable to make temp dir %s", tmpDir)
+ }
+ st, err := os.Stat(tmpDir)
+ if err == nil && int(st.Sys().(*syscall.Stat_t).Uid) == os.Geteuid() && st.Mode().Perm() == 0700 {
+ runtimeDir = tmpDir
+ }
+ }
+ if runtimeDir == "" {
+ tmpDir := filepath.Join(os.TempDir(), fmt.Sprintf("run-%s", uid))
+ if err := os.MkdirAll(tmpDir, 0700); err != nil {
+ logrus.Debugf("unable to make temp dir %s", tmpDir)
+ }
+ st, err := os.Stat(tmpDir)
+ if err == nil && int(st.Sys().(*syscall.Stat_t).Uid) == os.Geteuid() && st.Mode().Perm() == 0700 {
+ runtimeDir = tmpDir
+ }
+ }
+ if runtimeDir == "" {
+ home := os.Getenv("HOME")
+ if home == "" {
+ rootlessRuntimeDirError = fmt.Errorf("neither XDG_RUNTIME_DIR nor HOME was set non-empty")
+ return
+ }
+ resolvedHome, err := filepath.EvalSymlinks(home)
+ if err != nil {
+ rootlessRuntimeDirError = errors.Wrapf(err, "cannot resolve %s", home)
+ return
+ }
+ runtimeDir = filepath.Join(resolvedHome, "rundir")
+ }
+ rootlessRuntimeDir = runtimeDir
+ })
+
+ if rootlessRuntimeDirError != nil {
+ return "", rootlessRuntimeDirError
+ }
+ return rootlessRuntimeDir, nil
+}
diff --git a/vendor/github.com/containers/common/pkg/config/util_windows.go b/vendor/github.com/containers/common/pkg/config/util_windows.go
new file mode 100644
index 000000000..995301f5d
--- /dev/null
+++ b/vendor/github.com/containers/common/pkg/config/util_windows.go
@@ -0,0 +1,12 @@
+// +build windows
+
+package config
+
+import (
+ "github.com/pkg/errors"
+)
+
+// getRuntimeDir returns the runtime directory
+func getRuntimeDir() (string, error) {
+ return "", errors.New("this function is not implemented for windows")
+}
diff --git a/vendor/github.com/containers/common/pkg/unshare/getenv_linux_cgo.go b/vendor/github.com/containers/common/pkg/unshare/getenv_linux_cgo.go
new file mode 100644
index 000000000..4f441c32c
--- /dev/null
+++ b/vendor/github.com/containers/common/pkg/unshare/getenv_linux_cgo.go
@@ -0,0 +1,22 @@
+// +build linux,cgo
+
+package unshare
+
+import (
+ "unsafe"
+)
+
+/*
+#cgo remoteclient CFLAGS: -Wall -Werror
+#include <stdlib.h>
+*/
+import "C"
+
+func getenv(name string) string {
+ cName := C.CString(name)
+ defer C.free(unsafe.Pointer(cName))
+
+ value := C.GoString(C.getenv(cName))
+
+ return value
+}
diff --git a/vendor/github.com/containers/common/pkg/unshare/getenv_linux_nocgo.go b/vendor/github.com/containers/common/pkg/unshare/getenv_linux_nocgo.go
new file mode 100644
index 000000000..a5005403a
--- /dev/null
+++ b/vendor/github.com/containers/common/pkg/unshare/getenv_linux_nocgo.go
@@ -0,0 +1,11 @@
+// +build linux,!cgo
+
+package unshare
+
+import (
+ "os"
+)
+
+func getenv(name string) string {
+ return os.Getenv(name)
+}
diff --git a/vendor/github.com/containers/common/pkg/unshare/unshare_linux.go b/vendor/github.com/containers/common/pkg/unshare/unshare_linux.go
index ed83908c2..ef33ab8eb 100644
--- a/vendor/github.com/containers/common/pkg/unshare/unshare_linux.go
+++ b/vendor/github.com/containers/common/pkg/unshare/unshare_linux.go
@@ -50,6 +50,31 @@ func Command(args ...string) *Cmd {
}
}
+func getRootlessUID() int {
+ uidEnv := getenv("_CONTAINERS_ROOTLESS_UID")
+ if uidEnv != "" {
+ u, _ := strconv.Atoi(uidEnv)
+ return u
+ }
+ return os.Geteuid()
+}
+
+func getRootlessGID() int {
+ gidEnv := getenv("_CONTAINERS_ROOTLESS_GID")
+ if gidEnv != "" {
+ u, _ := strconv.Atoi(gidEnv)
+ return u
+ }
+
+ /* If the _CONTAINERS_ROOTLESS_UID is set, assume the gid==uid. */
+ uidEnv := os.Getenv("_CONTAINERS_ROOTLESS_UID")
+ if uidEnv != "" {
+ u, _ := strconv.Atoi(uidEnv)
+ return u
+ }
+ return os.Getegid()
+}
+
func (c *Cmd) Start() error {
runtime.LockOSThread()
defer runtime.UnlockOSThread()
@@ -61,10 +86,10 @@ func (c *Cmd) Start() error {
c.Env = append(c.Env, fmt.Sprintf("_Containers-unshare=%d", c.UnshareFlags))
// Please the libpod "rootless" package to find the expected env variables.
- if os.Geteuid() != 0 {
+ if IsRootless() {
c.Env = append(c.Env, "_CONTAINERS_USERNS_CONFIGURED=done")
- c.Env = append(c.Env, fmt.Sprintf("_CONTAINERS_ROOTLESS_UID=%d", os.Geteuid()))
- c.Env = append(c.Env, fmt.Sprintf("_CONTAINERS_ROOTLESS_GID=%d", os.Getegid()))
+ c.Env = append(c.Env, fmt.Sprintf("_CONTAINERS_ROOTLESS_UID=%d", getRootlessUID()))
+ c.Env = append(c.Env, fmt.Sprintf("_CONTAINERS_ROOTLESS_GID=%d", getRootlessGID()))
}
// Create the pipe for reading the child's PID.
@@ -318,14 +343,14 @@ const (
// IsRootless tells us if we are running in rootless mode
func IsRootless() bool {
isRootlessOnce.Do(func() {
- isRootless = os.Geteuid() != 0 || os.Getenv(UsernsEnvName) != ""
+ isRootless = getRootlessUID() != 0 || getenv(UsernsEnvName) != ""
})
return isRootless
}
// GetRootlessUID returns the UID of the user in the parent userNS
func GetRootlessUID() int {
- uidEnv := os.Getenv("_CONTAINERS_ROOTLESS_UID")
+ uidEnv := getenv("_CONTAINERS_ROOTLESS_UID")
if uidEnv != "" {
u, _ := strconv.Atoi(uidEnv)
return u
diff --git a/vendor/github.com/containers/image/v5/copy/copy.go b/vendor/github.com/containers/image/v5/copy/copy.go
index 29660b6b2..8432dbe32 100644
--- a/vendor/github.com/containers/image/v5/copy/copy.go
+++ b/vendor/github.com/containers/image/v5/copy/copy.go
@@ -380,6 +380,7 @@ func (c *copier) copyMultipleImages(ctx context.Context, policyContext *signatur
return nil, "", errors.Wrap(err, "Can not copy signatures")
}
}
+ canModifyManifestList := (len(sigs) == 0)
// Determine if we'll need to convert the manifest list to a different format.
forceListMIMEType := options.ForceManifestMIMEType
@@ -394,7 +395,6 @@ func (c *copier) copyMultipleImages(ctx context.Context, policyContext *signatur
return nil, "", errors.Wrapf(err, "Error determining manifest list type to write to destination")
}
if selectedListType != list.MIMEType() {
- canModifyManifestList := (len(sigs) == 0)
if !canModifyManifestList {
return nil, "", errors.Errorf("Error: manifest list must be converted to type %q to be written to destination, but that would invalidate signatures", selectedListType)
}
@@ -451,12 +451,6 @@ func (c *copier) copyMultipleImages(ctx context.Context, policyContext *signatur
return nil, "", errors.Wrapf(err, "Error updating manifest list")
}
- // Check if the updates meaningfully changed the list of images.
- listIsModified := false
- if !reflect.DeepEqual(list.Instances(), originalList.Instances()) {
- listIsModified = true
- }
-
// Perform the list conversion.
if selectedListType != list.MIMEType() {
list, err = list.ConvertToMIMEType(selectedListType)
@@ -465,12 +459,23 @@ func (c *copier) copyMultipleImages(ctx context.Context, policyContext *signatur
}
}
- // If we can't use the original value, but we have to change it, flag an error.
- if listIsModified {
- manifestList, err = list.Serialize()
- if err != nil {
- return nil, "", errors.Wrapf(err, "Error encoding updated manifest list (%q: %#v)", list.MIMEType(), list.Instances())
+ // Check if the updates or a type conversion meaningfully changed the list of images
+ // by serializing them both so that we can compare them.
+ updatedManifestList, err := list.Serialize()
+ if err != nil {
+ return nil, "", errors.Wrapf(err, "Error encoding updated manifest list (%q: %#v)", list.MIMEType(), list.Instances())
+ }
+ originalManifestList, err := originalList.Serialize()
+ if err != nil {
+ return nil, "", errors.Wrapf(err, "Error encoding original manifest list for comparison (%q: %#v)", originalList.MIMEType(), originalList.Instances())
+ }
+
+ // If we can't just use the original value, but we have to change it, flag an error.
+ if !bytes.Equal(updatedManifestList, originalManifestList) {
+ if !canModifyManifestList {
+ return nil, "", errors.Errorf("Error: manifest list must be converted to type %q to be written to destination, but that would invalidate signatures", selectedListType)
}
+ manifestList = updatedManifestList
logrus.Debugf("Manifest list has been updated")
}
@@ -709,7 +714,7 @@ func checkImageDestinationForCurrentRuntime(ctx context.Context, sys *types.Syst
wantedOS = sys.OSChoice
}
if wantedOS != c.OS {
- return fmt.Errorf("Image operating system mismatch: image uses %q, expecting %q", c.OS, wantedOS)
+ logrus.Infof("Image operating system mismatch: image uses %q, expecting %q", c.OS, wantedOS)
}
wantedArch := runtime.GOARCH
@@ -717,7 +722,7 @@ func checkImageDestinationForCurrentRuntime(ctx context.Context, sys *types.Syst
wantedArch = sys.ArchitectureChoice
}
if wantedArch != c.Architecture {
- return fmt.Errorf("Image architecture mismatch: image uses %q, expecting %q", c.Architecture, wantedArch)
+ logrus.Infof("Image architecture mismatch: image uses %q, expecting %q", c.Architecture, wantedArch)
}
}
return nil
diff --git a/vendor/github.com/containers/image/v5/copy/manifest.go b/vendor/github.com/containers/image/v5/copy/manifest.go
index bcf082df3..5a3cf06a4 100644
--- a/vendor/github.com/containers/image/v5/copy/manifest.go
+++ b/vendor/github.com/containers/image/v5/copy/manifest.go
@@ -127,14 +127,14 @@ func isMultiImage(ctx context.Context, img types.UnparsedImage) (bool, error) {
// forced value, and returns the MIME type to which we should convert the list
// of manifests, whether we are converting to it or using it unmodified.
func (c *copier) determineListConversion(currentListMIMEType string, destSupportedMIMETypes []string, forcedListMIMEType string) (string, error) {
- // If we're forcing it, we prefer the forced value over everything else.
- if forcedListMIMEType != "" {
- return forcedListMIMEType, nil
- }
// If there's no list of supported types, then anything we support is expected to be supported.
if len(destSupportedMIMETypes) == 0 {
destSupportedMIMETypes = manifest.SupportedListMIMETypes
}
+ // If we're forcing it, replace the list of supported types with the forced value.
+ if forcedListMIMEType != "" {
+ destSupportedMIMETypes = []string{forcedListMIMEType}
+ }
var selectedType string
for i := range destSupportedMIMETypes {
// The second priority is the first member of the list of acceptable types that is a list,
@@ -148,9 +148,15 @@ func (c *copier) determineListConversion(currentListMIMEType string, destSupport
selectedType = destSupportedMIMETypes[i]
}
}
+ logrus.Debugf("Manifest list has MIME type %s, ordered candidate list [%s]", currentListMIMEType, strings.Join(destSupportedMIMETypes, ", "))
if selectedType == "" {
return "", errors.Errorf("destination does not support any supported manifest list types (%v)", manifest.SupportedListMIMETypes)
}
+ if selectedType != currentListMIMEType {
+ logrus.Debugf("... will convert to %s", selectedType)
+ } else {
+ logrus.Debugf("... will use the original manifest list type")
+ }
// Done.
return selectedType, nil
}
diff --git a/vendor/github.com/containers/image/v5/directory/directory_dest.go b/vendor/github.com/containers/image/v5/directory/directory_dest.go
index caa7a207f..d70b6c07f 100644
--- a/vendor/github.com/containers/image/v5/directory/directory_dest.go
+++ b/vendor/github.com/containers/image/v5/directory/directory_dest.go
@@ -6,6 +6,7 @@ import (
"io/ioutil"
"os"
"path/filepath"
+ "runtime"
"github.com/containers/image/v5/types"
"github.com/opencontainers/go-digest"
@@ -142,8 +143,11 @@ func (d *dirImageDestination) PutBlob(ctx context.Context, stream io.Reader, inp
return types.BlobInfo{}, err
}
succeeded := false
+ explicitClosed := false
defer func() {
- blobFile.Close()
+ if !explicitClosed {
+ blobFile.Close()
+ }
if !succeeded {
os.Remove(blobFile.Name())
}
@@ -164,10 +168,21 @@ func (d *dirImageDestination) PutBlob(ctx context.Context, stream io.Reader, inp
if err := blobFile.Sync(); err != nil {
return types.BlobInfo{}, err
}
- if err := blobFile.Chmod(0644); err != nil {
- return types.BlobInfo{}, err
+
+ // On POSIX systems, blobFile was created with mode 0600, so we need to make it readable.
+ // On Windows, the “permissions of newly created files” argument to syscall.Open is
+ // ignored and the file is already readable; besides, blobFile.Chmod, i.e. syscall.Fchmod,
+ // always fails on Windows.
+ if runtime.GOOS != "windows" {
+ if err := blobFile.Chmod(0644); err != nil {
+ return types.BlobInfo{}, err
+ }
}
+
blobPath := d.ref.layerPath(computedDigest)
+ // need to explicitly close the file, since a rename won't otherwise not work on Windows
+ blobFile.Close()
+ explicitClosed = true
if err := os.Rename(blobFile.Name(), blobPath); err != nil {
return types.BlobInfo{}, err
}
diff --git a/vendor/github.com/containers/image/v5/docker/docker_client.go b/vendor/github.com/containers/image/v5/docker/docker_client.go
index 986bcb986..aa8463d18 100644
--- a/vendor/github.com/containers/image/v5/docker/docker_client.go
+++ b/vendor/github.com/containers/image/v5/docker/docker_client.go
@@ -6,7 +6,6 @@ import (
"encoding/json"
"fmt"
"io"
- "io/ioutil"
"net/http"
"net/url"
"os"
@@ -17,6 +16,7 @@ import (
"time"
"github.com/containers/image/v5/docker/reference"
+ "github.com/containers/image/v5/internal/iolimits"
"github.com/containers/image/v5/pkg/docker/config"
"github.com/containers/image/v5/pkg/sysregistriesv2"
"github.com/containers/image/v5/pkg/tlsclientconfig"
@@ -45,6 +45,10 @@ const (
extensionSignatureSchemaVersion = 2 // extensionSignature.Version
extensionSignatureTypeAtomic = "atomic" // extensionSignature.Type
+
+ backoffNumIterations = 5
+ backoffInitialDelay = 2 * time.Second
+ backoffMaxDelay = 60 * time.Second
)
var systemPerHostCertDirPaths = [2]string{"/etc/containers/certs.d", "/etc/docker/certs.d"}
@@ -277,7 +281,7 @@ func CheckAuth(ctx context.Context, sys *types.SystemContext, username, password
}
defer resp.Body.Close()
- return httpResponseToError(resp)
+ return httpResponseToError(resp, "")
}
// SearchResult holds the information of each matching image
@@ -351,7 +355,7 @@ func SearchRegistry(ctx context.Context, sys *types.SystemContext, registry, ima
} else {
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
- logrus.Debugf("error getting search results from v1 endpoint %q: %v", registry, httpResponseToError(resp))
+ logrus.Debugf("error getting search results from v1 endpoint %q: %v", registry, httpResponseToError(resp, ""))
} else {
if err := json.NewDecoder(resp.Body).Decode(v1Res); err != nil {
return nil, err
@@ -368,7 +372,7 @@ func SearchRegistry(ctx context.Context, sys *types.SystemContext, registry, ima
} else {
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
- logrus.Errorf("error getting search results from v2 endpoint %q: %v", registry, httpResponseToError(resp))
+ logrus.Errorf("error getting search results from v2 endpoint %q: %v", registry, httpResponseToError(resp, ""))
} else {
if err := json.NewDecoder(resp.Body).Decode(v2Res); err != nil {
return nil, err
@@ -400,74 +404,64 @@ func (c *dockerClient) makeRequest(ctx context.Context, method, path string, hea
return c.makeRequestToResolvedURL(ctx, method, url, headers, stream, -1, auth, extraScope)
}
+// parseRetryAfter determines the delay required by the "Retry-After" header in res and returns it,
+// silently falling back to fallbackDelay if the header is missing or invalid.
+func parseRetryAfter(res *http.Response, fallbackDelay time.Duration) time.Duration {
+ after := res.Header.Get("Retry-After")
+ if after == "" {
+ return fallbackDelay
+ }
+ logrus.Debugf("Detected 'Retry-After' header %q", after)
+ // First, check if we have a numerical value.
+ if num, err := strconv.ParseInt(after, 10, 64); err == nil {
+ return time.Duration(num) * time.Second
+ }
+ // Second, check if we have an HTTP date.
+ // If the delta between the date and now is positive, use it.
+ // Otherwise, fall back to using the default exponential back off.
+ if t, err := http.ParseTime(after); err == nil {
+ delta := time.Until(t)
+ if delta > 0 {
+ return delta
+ }
+ logrus.Debugf("Retry-After date in the past, ignoring it")
+ return fallbackDelay
+ }
+ // If the header contents are bogus, fall back to using the default exponential back off.
+ logrus.Debugf("Invalid Retry-After format, ignoring it")
+ return fallbackDelay
+}
+
// makeRequestToResolvedURL creates and executes a http.Request with the specified parameters, adding authentication and TLS options for the Docker client.
// streamLen, if not -1, specifies the length of the data expected on stream.
// makeRequest should generally be preferred.
-// In case of an http 429 status code in the response, it performs an exponential back off starting at 2 seconds for at most 5 iterations.
-// If the `Retry-After` header is set in the response, the specified value or date is
-// If the stream is non-nil, no back off will be performed.
+// In case of an HTTP 429 status code in the response, it may automatically retry a few times.
// TODO(runcom): too many arguments here, use a struct
func (c *dockerClient) makeRequestToResolvedURL(ctx context.Context, method, url string, headers map[string][]string, stream io.Reader, streamLen int64, auth sendAuth, extraScope *authScope) (*http.Response, error) {
- var (
- res *http.Response
- err error
- delay int64
- )
- delay = 2
- const numIterations = 5
- const maxDelay = 60
-
- // math.Min() only supports float64, so have an anonymous func to avoid
- // casting.
- min := func(a int64, b int64) int64 {
- if a < b {
- return a
+ delay := backoffInitialDelay
+ attempts := 0
+ for {
+ res, err := c.makeRequestToResolvedURLOnce(ctx, method, url, headers, stream, streamLen, auth, extraScope)
+ attempts++
+ if res == nil || res.StatusCode != http.StatusTooManyRequests || // Only retry on StatusTooManyRequests, success or other failure is returned to caller immediately
+ stream != nil || // We can't retry with a body (which is not restartable in the general case)
+ attempts == backoffNumIterations {
+ return res, err
}
- return b
- }
- nextDelay := func(r *http.Response, delay int64) int64 {
- after := res.Header.Get("Retry-After")
- if after == "" {
- return min(delay, maxDelay)
- }
- logrus.Debugf("detected 'Retry-After' header %q", after)
- // First check if we have a numerical value.
- if num, err := strconv.ParseInt(after, 10, 64); err == nil {
- return min(num, maxDelay)
+ delay = parseRetryAfter(res, delay)
+ if delay > backoffMaxDelay {
+ delay = backoffMaxDelay
}
- // Secondly check if we have an http date.
- // If the delta between the date and now is positive, use it.
- // Otherwise, fall back to using the default exponential back off.
- if t, err := http.ParseTime(after); err == nil {
- delta := int64(time.Until(t).Seconds())
- if delta > 0 {
- return min(delta, maxDelay)
- }
- logrus.Debugf("negative date: falling back to using %d seconds", delay)
- return min(delay, maxDelay)
+ logrus.Debugf("Too many requests to %s: sleeping for %f seconds before next attempt", url, delay.Seconds())
+ select {
+ case <-ctx.Done():
+ return nil, ctx.Err()
+ case <-time.After(delay):
+ // Nothing
}
- // If the header contains bogus, fall back to using the default
- // exponential back off.
- logrus.Debugf("invalid format: falling back to using %d seconds", delay)
- return min(delay, maxDelay)
- }
-
- for i := 0; i < numIterations; i++ {
- res, err = c.makeRequestToResolvedURLOnce(ctx, method, url, headers, stream, streamLen, auth, extraScope)
- if stream == nil && res != nil && res.StatusCode == http.StatusTooManyRequests {
- if i < numIterations-1 {
- logrus.Errorf("HEADER %v", res.Header)
- delay = nextDelay(res, delay) // compute next delay - does NOT exceed maxDelay
- logrus.Debugf("too many request to %s: sleeping for %d seconds before next attempt", url, delay)
- time.Sleep(time.Duration(delay) * time.Second)
- delay = delay * 2 // exponential back off
- }
- continue
- }
- break
+ delay = delay * 2 // exponential back off
}
- return res, err
}
// makeRequestToResolvedURLOnce creates and executes a http.Request with the specified parameters, adding authentication and TLS options for the Docker client.
@@ -597,7 +591,7 @@ func (c *dockerClient) getBearerToken(ctx context.Context, challenge challenge,
default:
return nil, errors.Errorf("unexpected http code: %d (%s), URL: %s", res.StatusCode, http.StatusText(res.StatusCode), authReq.URL)
}
- tokenBlob, err := ioutil.ReadAll(res.Body)
+ tokenBlob, err := iolimits.ReadAtMost(res.Body, iolimits.MaxAuthTokenBodySize)
if err != nil {
return nil, err
}
@@ -627,7 +621,7 @@ func (c *dockerClient) detectPropertiesHelper(ctx context.Context) error {
defer resp.Body.Close()
logrus.Debugf("Ping %s status %d", url, resp.StatusCode)
if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusUnauthorized {
- return httpResponseToError(resp)
+ return httpResponseToError(resp, "")
}
c.challenges = parseAuthHeader(resp.Header)
c.scheme = scheme
@@ -690,7 +684,7 @@ func (c *dockerClient) getExtensionsSignatures(ctx context.Context, ref dockerRe
return nil, errors.Wrapf(clientLib.HandleErrorResponse(res), "Error downloading signatures for %s in %s", manifestDigest, ref.ref.Name())
}
- body, err := ioutil.ReadAll(res.Body)
+ body, err := iolimits.ReadAtMost(res.Body, iolimits.MaxSignatureListBodySize)
if err != nil {
return nil, err
}
diff --git a/vendor/github.com/containers/image/v5/docker/docker_image.go b/vendor/github.com/containers/image/v5/docker/docker_image.go
index dad382cd0..483581dbc 100644
--- a/vendor/github.com/containers/image/v5/docker/docker_image.go
+++ b/vendor/github.com/containers/image/v5/docker/docker_image.go
@@ -70,7 +70,7 @@ func GetRepositoryTags(ctx context.Context, sys *types.SystemContext, ref types.
return nil, err
}
defer res.Body.Close()
- if err := httpResponseToError(res); err != nil {
+ if err := httpResponseToError(res, "Error fetching tags list"); err != nil {
return nil, err
}
diff --git a/vendor/github.com/containers/image/v5/docker/docker_image_dest.go b/vendor/github.com/containers/image/v5/docker/docker_image_dest.go
index 47a73d868..ab74e1607 100644
--- a/vendor/github.com/containers/image/v5/docker/docker_image_dest.go
+++ b/vendor/github.com/containers/image/v5/docker/docker_image_dest.go
@@ -15,6 +15,7 @@ import (
"strings"
"github.com/containers/image/v5/docker/reference"
+ "github.com/containers/image/v5/internal/iolimits"
"github.com/containers/image/v5/manifest"
"github.com/containers/image/v5/pkg/blobinfocache/none"
"github.com/containers/image/v5/types"
@@ -58,14 +59,16 @@ func (d *dockerImageDestination) Close() error {
}
func (d *dockerImageDestination) SupportedManifestMIMETypes() []string {
- return []string{
+ mimeTypes := []string{
imgspecv1.MediaTypeImageManifest,
manifest.DockerV2Schema2MediaType,
imgspecv1.MediaTypeImageIndex,
manifest.DockerV2ListMediaType,
- manifest.DockerV2Schema1SignedMediaType,
- manifest.DockerV2Schema1MediaType,
}
+ if d.c.sys == nil || !d.c.sys.DockerDisableDestSchema1MIMETypes {
+ mimeTypes = append(mimeTypes, manifest.DockerV2Schema1SignedMediaType, manifest.DockerV2Schema1MediaType)
+ }
+ return mimeTypes
}
// SupportsSignatures returns an error (to be displayed to the user) if the destination certainly can't store signatures.
@@ -620,7 +623,7 @@ sigExists:
}
defer res.Body.Close()
if res.StatusCode != http.StatusCreated {
- body, err := ioutil.ReadAll(res.Body)
+ body, err := iolimits.ReadAtMost(res.Body, iolimits.MaxErrorBodySize)
if err == nil {
logrus.Debugf("Error body %s", string(body))
}
diff --git a/vendor/github.com/containers/image/v5/docker/docker_image_src.go b/vendor/github.com/containers/image/v5/docker/docker_image_src.go
index 35beb30e5..967845e72 100644
--- a/vendor/github.com/containers/image/v5/docker/docker_image_src.go
+++ b/vendor/github.com/containers/image/v5/docker/docker_image_src.go
@@ -10,8 +10,10 @@ import (
"net/url"
"os"
"strconv"
+ "strings"
"github.com/containers/image/v5/docker/reference"
+ "github.com/containers/image/v5/internal/iolimits"
"github.com/containers/image/v5/manifest"
"github.com/containers/image/v5/pkg/sysregistriesv2"
"github.com/containers/image/v5/types"
@@ -53,43 +55,77 @@ func newImageSource(ctx context.Context, sys *types.SystemContext, ref dockerRef
// non-mirror original location last; this both transparently handles the case
// of no mirrors configured, and ensures we return the error encountered when
// acessing the upstream location if all endpoints fail.
- manifestLoadErr := errors.New("Internal error: newImageSource returned without trying any endpoint")
pullSources, err := registry.PullSourcesFromReference(ref.ref)
if err != nil {
return nil, err
}
+ type attempt struct {
+ ref reference.Named
+ err error
+ }
+ attempts := []attempt{}
for _, pullSource := range pullSources {
- logrus.Debugf("Trying to pull %q", pullSource.Reference)
- dockerRef, err := newReference(pullSource.Reference)
- if err != nil {
- return nil, err
+ logrus.Debugf("Trying to access %q", pullSource.Reference)
+ s, err := newImageSourceAttempt(ctx, sys, pullSource, primaryDomain)
+ if err == nil {
+ return s, nil
}
-
- endpointSys := sys
- // sys.DockerAuthConfig does not explicitly specify a registry; we must not blindly send the credentials intended for the primary endpoint to mirrors.
- if endpointSys != nil && endpointSys.DockerAuthConfig != nil && reference.Domain(dockerRef.ref) != primaryDomain {
- copy := *endpointSys
- copy.DockerAuthConfig = nil
- endpointSys = &copy
+ logrus.Debugf("Accessing %q failed: %v", pullSource.Reference, err)
+ attempts = append(attempts, attempt{
+ ref: pullSource.Reference,
+ err: err,
+ })
+ }
+ switch len(attempts) {
+ case 0:
+ return nil, errors.New("Internal error: newImageSource returned without trying any endpoint")
+ case 1:
+ return nil, attempts[0].err // If no mirrors are used, perfectly preserve the error type and add no noise.
+ default:
+ // Don’t just build a string, try to preserve the typed error.
+ primary := &attempts[len(attempts)-1]
+ extras := []string{}
+ for i := 0; i < len(attempts)-1; i++ {
+ // This is difficult to fit into a single-line string, when the error can contain arbitrary strings including any metacharacters we decide to use.
+ // The paired [] at least have some chance of being unambiguous.
+ extras = append(extras, fmt.Sprintf("[%s: %v]", attempts[i].ref.String(), attempts[i].err))
}
+ return nil, errors.Wrapf(primary.err, "(Mirrors also failed: %s): %s", strings.Join(extras, "\n"), primary.ref.String())
+ }
+}
- client, err := newDockerClientFromRef(endpointSys, dockerRef, false, "pull")
- if err != nil {
- return nil, err
- }
- client.tlsClientConfig.InsecureSkipVerify = pullSource.Endpoint.Insecure
+// newImageSourceAttempt is an internal helper for newImageSource. Everyone else must call newImageSource.
+// Given a pullSource and primaryDomain, return a dockerImageSource if it is reachable.
+// The caller must call .Close() on the returned ImageSource.
+func newImageSourceAttempt(ctx context.Context, sys *types.SystemContext, pullSource sysregistriesv2.PullSource, primaryDomain string) (*dockerImageSource, error) {
+ ref, err := newReference(pullSource.Reference)
+ if err != nil {
+ return nil, err
+ }
- testImageSource := &dockerImageSource{
- ref: dockerRef,
- c: client,
- }
+ endpointSys := sys
+ // sys.DockerAuthConfig does not explicitly specify a registry; we must not blindly send the credentials intended for the primary endpoint to mirrors.
+ if endpointSys != nil && endpointSys.DockerAuthConfig != nil && reference.Domain(ref.ref) != primaryDomain {
+ copy := *endpointSys
+ copy.DockerAuthConfig = nil
+ endpointSys = &copy
+ }
- manifestLoadErr = testImageSource.ensureManifestIsLoaded(ctx)
- if manifestLoadErr == nil {
- return testImageSource, nil
- }
+ client, err := newDockerClientFromRef(endpointSys, ref, false, "pull")
+ if err != nil {
+ return nil, err
}
- return nil, manifestLoadErr
+ client.tlsClientConfig.InsecureSkipVerify = pullSource.Endpoint.Insecure
+
+ s := &dockerImageSource{
+ ref: ref,
+ c: client,
+ }
+
+ if err := s.ensureManifestIsLoaded(ctx); err != nil {
+ return nil, err
+ }
+ return s, nil
}
// Reference returns the reference used to set up this source, _as specified by the user_
@@ -156,7 +192,8 @@ func (s *dockerImageSource) fetchManifest(ctx context.Context, tagOrDigest strin
if res.StatusCode != http.StatusOK {
return nil, "", errors.Wrapf(client.HandleErrorResponse(res), "Error reading manifest %s in %s", tagOrDigest, s.ref.ref.Name())
}
- manblob, err := ioutil.ReadAll(res.Body)
+
+ manblob, err := iolimits.ReadAtMost(res.Body, iolimits.MaxManifestBodySize)
if err != nil {
return nil, "", err
}
@@ -239,7 +276,7 @@ func (s *dockerImageSource) GetBlob(ctx context.Context, info types.BlobInfo, ca
if err != nil {
return nil, 0, err
}
- if err := httpResponseToError(res); err != nil {
+ if err := httpResponseToError(res, "Error fetching blob"); err != nil {
return nil, 0, err
}
cache.RecordKnownLocation(s.ref.Transport(), bicTransportScope(s.ref), info.Digest, newBICLocationReference(s.ref))
@@ -342,7 +379,7 @@ func (s *dockerImageSource) getOneSignature(ctx context.Context, url *url.URL) (
} else if res.StatusCode != http.StatusOK {
return nil, false, errors.Errorf("Error reading signature from %s: status %d (%s)", url.String(), res.StatusCode, http.StatusText(res.StatusCode))
}
- sig, err := ioutil.ReadAll(res.Body)
+ sig, err := iolimits.ReadAtMost(res.Body, iolimits.MaxSignatureBodySize)
if err != nil {
return nil, false, err
}
@@ -401,7 +438,7 @@ func deleteImage(ctx context.Context, sys *types.SystemContext, ref dockerRefere
return err
}
defer get.Body.Close()
- manifestBody, err := ioutil.ReadAll(get.Body)
+ manifestBody, err := iolimits.ReadAtMost(get.Body, iolimits.MaxManifestBodySize)
if err != nil {
return err
}
@@ -424,7 +461,7 @@ func deleteImage(ctx context.Context, sys *types.SystemContext, ref dockerRefere
}
defer delete.Body.Close()
- body, err := ioutil.ReadAll(delete.Body)
+ body, err := iolimits.ReadAtMost(delete.Body, iolimits.MaxErrorBodySize)
if err != nil {
return err
}
diff --git a/vendor/github.com/containers/image/v5/docker/errors.go b/vendor/github.com/containers/image/v5/docker/errors.go
index 860868f41..f626cc7da 100644
--- a/vendor/github.com/containers/image/v5/docker/errors.go
+++ b/vendor/github.com/containers/image/v5/docker/errors.go
@@ -14,7 +14,7 @@ var (
// docker V1 registry.
ErrV1NotSupported = errors.New("can't talk to a V1 docker registry")
// ErrTooManyRequests is returned when the status code returned is 429
- ErrTooManyRequests = errors.New("too many request to registry")
+ ErrTooManyRequests = errors.New("too many requests to registry")
)
// ErrUnauthorizedForCredentials is returned when the status code returned is 401
@@ -26,9 +26,9 @@ func (e ErrUnauthorizedForCredentials) Error() string {
return fmt.Sprintf("unable to retrieve auth token: invalid username/password: %s", e.Err.Error())
}
-// httpResponseToError translates the https.Response into an error. It returns
+// httpResponseToError translates the https.Response into an error, possibly prefixing it with the supplied context. It returns
// nil if the response is not considered an error.
-func httpResponseToError(res *http.Response) error {
+func httpResponseToError(res *http.Response, context string) error {
switch res.StatusCode {
case http.StatusOK:
return nil
@@ -38,6 +38,9 @@ func httpResponseToError(res *http.Response) error {
err := client.HandleErrorResponse(res)
return ErrUnauthorizedForCredentials{Err: err}
default:
- return perrors.Errorf("invalid status code from registry %d (%s)", res.StatusCode, http.StatusText(res.StatusCode))
+ if context != "" {
+ context = context + ": "
+ }
+ return perrors.Errorf("%sinvalid status code from registry %d (%s)", context, res.StatusCode, http.StatusText(res.StatusCode))
}
}
diff --git a/vendor/github.com/containers/image/v5/docker/tarfile/dest.go b/vendor/github.com/containers/image/v5/docker/tarfile/dest.go
index c322156b5..c171da505 100644
--- a/vendor/github.com/containers/image/v5/docker/tarfile/dest.go
+++ b/vendor/github.com/containers/image/v5/docker/tarfile/dest.go
@@ -13,6 +13,7 @@ import (
"time"
"github.com/containers/image/v5/docker/reference"
+ "github.com/containers/image/v5/internal/iolimits"
"github.com/containers/image/v5/internal/tmpdir"
"github.com/containers/image/v5/manifest"
"github.com/containers/image/v5/types"
@@ -143,7 +144,7 @@ func (d *Destination) PutBlob(ctx context.Context, stream io.Reader, inputInfo t
}
if isConfig {
- buf, err := ioutil.ReadAll(stream)
+ buf, err := iolimits.ReadAtMost(stream, iolimits.MaxConfigBodySize)
if err != nil {
return types.BlobInfo{}, errors.Wrap(err, "Error reading Config file stream")
}
diff --git a/vendor/github.com/containers/image/v5/docker/tarfile/src.go b/vendor/github.com/containers/image/v5/docker/tarfile/src.go
index 80dd753e4..c1f1a0f27 100644
--- a/vendor/github.com/containers/image/v5/docker/tarfile/src.go
+++ b/vendor/github.com/containers/image/v5/docker/tarfile/src.go
@@ -11,6 +11,7 @@ import (
"path"
"sync"
+ "github.com/containers/image/v5/internal/iolimits"
"github.com/containers/image/v5/internal/tmpdir"
"github.com/containers/image/v5/manifest"
"github.com/containers/image/v5/pkg/compression"
@@ -203,13 +204,13 @@ func findTarComponent(inputFile io.Reader, path string) (*tar.Reader, *tar.Heade
}
// readTarComponent returns full contents of componentPath.
-func (s *Source) readTarComponent(path string) ([]byte, error) {
+func (s *Source) readTarComponent(path string, limit int) ([]byte, error) {
file, err := s.openTarComponent(path)
if err != nil {
return nil, errors.Wrapf(err, "Error loading tar component %s", path)
}
defer file.Close()
- bytes, err := ioutil.ReadAll(file)
+ bytes, err := iolimits.ReadAtMost(file, limit)
if err != nil {
return nil, err
}
@@ -240,7 +241,7 @@ func (s *Source) ensureCachedDataIsPresentPrivate() error {
}
// Read and parse config.
- configBytes, err := s.readTarComponent(tarManifest[0].Config)
+ configBytes, err := s.readTarComponent(tarManifest[0].Config, iolimits.MaxConfigBodySize)
if err != nil {
return err
}
@@ -266,7 +267,7 @@ func (s *Source) ensureCachedDataIsPresentPrivate() error {
// loadTarManifest loads and decodes the manifest.json.
func (s *Source) loadTarManifest() ([]ManifestItem, error) {
// FIXME? Do we need to deal with the legacy format?
- bytes, err := s.readTarComponent(manifestFileName)
+ bytes, err := s.readTarComponent(manifestFileName, iolimits.MaxTarFileManifestSize)
if err != nil {
return nil, err
}
diff --git a/vendor/github.com/containers/image/v5/image/docker_schema2.go b/vendor/github.com/containers/image/v5/image/docker_schema2.go
index 7891562b7..1e2114d7e 100644
--- a/vendor/github.com/containers/image/v5/image/docker_schema2.go
+++ b/vendor/github.com/containers/image/v5/image/docker_schema2.go
@@ -7,10 +7,10 @@ import (
"encoding/hex"
"encoding/json"
"fmt"
- "io/ioutil"
"strings"
"github.com/containers/image/v5/docker/reference"
+ "github.com/containers/image/v5/internal/iolimits"
"github.com/containers/image/v5/manifest"
"github.com/containers/image/v5/pkg/blobinfocache/none"
"github.com/containers/image/v5/types"
@@ -102,7 +102,7 @@ func (m *manifestSchema2) ConfigBlob(ctx context.Context) ([]byte, error) {
return nil, err
}
defer stream.Close()
- blob, err := ioutil.ReadAll(stream)
+ blob, err := iolimits.ReadAtMost(stream, iolimits.MaxConfigBodySize)
if err != nil {
return nil, err
}
diff --git a/vendor/github.com/containers/image/v5/image/oci.go b/vendor/github.com/containers/image/v5/image/oci.go
index 059d84977..b5ddb9aaa 100644
--- a/vendor/github.com/containers/image/v5/image/oci.go
+++ b/vendor/github.com/containers/image/v5/image/oci.go
@@ -4,9 +4,9 @@ import (
"context"
"encoding/json"
"fmt"
- "io/ioutil"
"github.com/containers/image/v5/docker/reference"
+ "github.com/containers/image/v5/internal/iolimits"
"github.com/containers/image/v5/manifest"
"github.com/containers/image/v5/pkg/blobinfocache/none"
"github.com/containers/image/v5/types"
@@ -67,7 +67,7 @@ func (m *manifestOCI1) ConfigBlob(ctx context.Context) ([]byte, error) {
return nil, err
}
defer stream.Close()
- blob, err := ioutil.ReadAll(stream)
+ blob, err := iolimits.ReadAtMost(stream, iolimits.MaxConfigBodySize)
if err != nil {
return nil, err
}
diff --git a/vendor/github.com/containers/image/v5/internal/iolimits/iolimits.go b/vendor/github.com/containers/image/v5/internal/iolimits/iolimits.go
new file mode 100644
index 000000000..3fed1995c
--- /dev/null
+++ b/vendor/github.com/containers/image/v5/internal/iolimits/iolimits.go
@@ -0,0 +1,60 @@
+package iolimits
+
+import (
+ "io"
+ "io/ioutil"
+
+ "github.com/pkg/errors"
+)
+
+// All constants below are intended to be used as limits for `ReadAtMost`. The
+// immediate use-case for limiting the size of in-memory copied data is to
+// protect against OOM DOS attacks as described inCVE-2020-1702. Instead of
+// copying data until running out of memory, we error out after hitting the
+// specified limit.
+const (
+ // megaByte denotes one megabyte and is intended to be used as a limit in
+ // `ReadAtMost`.
+ megaByte = 1 << 20
+ // MaxManifestBodySize is the maximum allowed size of a manifest. The limit
+ // of 4 MB aligns with the one of a Docker registry:
+ // https://github.com/docker/distribution/blob/a8371794149d1d95f1e846744b05c87f2f825e5a/registry/handlers/manifests.go#L30
+ MaxManifestBodySize = 4 * megaByte
+ // MaxAuthTokenBodySize is the maximum allowed size of an auth token.
+ // The limit of 1 MB is considered to be greatly sufficient.
+ MaxAuthTokenBodySize = megaByte
+ // MaxSignatureListBodySize is the maximum allowed size of a signature list.
+ // The limit of 4 MB is considered to be greatly sufficient.
+ MaxSignatureListBodySize = 4 * megaByte
+ // MaxSignatureBodySize is the maximum allowed size of a signature.
+ // The limit of 4 MB is considered to be greatly sufficient.
+ MaxSignatureBodySize = 4 * megaByte
+ // MaxErrorBodySize is the maximum allowed size of an error-response body.
+ // The limit of 1 MB is considered to be greatly sufficient.
+ MaxErrorBodySize = megaByte
+ // MaxConfigBodySize is the maximum allowed size of a config blob.
+ // The limit of 4 MB is considered to be greatly sufficient.
+ MaxConfigBodySize = 4 * megaByte
+ // MaxOpenShiftStatusBody is the maximum allowed size of an OpenShift status body.
+ // The limit of 4 MB is considered to be greatly sufficient.
+ MaxOpenShiftStatusBody = 4 * megaByte
+ // MaxTarFileManifestSize is the maximum allowed size of a (docker save)-like manifest (which may contain multiple images)
+ // The limit of 1 MB is considered to be greatly sufficient.
+ MaxTarFileManifestSize = megaByte
+)
+
+// ReadAtMost reads from reader and errors out if the specified limit (in bytes) is exceeded.
+func ReadAtMost(reader io.Reader, limit int) ([]byte, error) {
+ limitedReader := io.LimitReader(reader, int64(limit+1))
+
+ res, err := ioutil.ReadAll(limitedReader)
+ if err != nil {
+ return nil, err
+ }
+
+ if len(res) > limit {
+ return nil, errors.Errorf("exceeded maximum allowed size of %d bytes", limit)
+ }
+
+ return res, nil
+}
diff --git a/vendor/github.com/containers/image/v5/openshift/openshift.go b/vendor/github.com/containers/image/v5/openshift/openshift.go
index b9242da6e..28bfc456d 100644
--- a/vendor/github.com/containers/image/v5/openshift/openshift.go
+++ b/vendor/github.com/containers/image/v5/openshift/openshift.go
@@ -7,13 +7,13 @@ import (
"encoding/json"
"fmt"
"io"
- "io/ioutil"
"net/http"
"net/url"
"strings"
"github.com/containers/image/v5/docker"
"github.com/containers/image/v5/docker/reference"
+ "github.com/containers/image/v5/internal/iolimits"
"github.com/containers/image/v5/manifest"
"github.com/containers/image/v5/types"
"github.com/containers/image/v5/version"
@@ -102,7 +102,7 @@ func (c *openshiftClient) doRequest(ctx context.Context, method, path string, re
return nil, err
}
defer res.Body.Close()
- body, err := ioutil.ReadAll(res.Body)
+ body, err := iolimits.ReadAtMost(res.Body, iolimits.MaxOpenShiftStatusBody)
if err != nil {
return nil, err
}
diff --git a/vendor/github.com/containers/image/v5/signature/mechanism_gpgme.go b/vendor/github.com/containers/image/v5/signature/mechanism_gpgme.go
index 4825ab27c..277fba16b 100644
--- a/vendor/github.com/containers/image/v5/signature/mechanism_gpgme.go
+++ b/vendor/github.com/containers/image/v5/signature/mechanism_gpgme.go
@@ -139,7 +139,7 @@ func (m *gpgmeSigningMechanism) Sign(input []byte, keyIdentity string) ([]byte,
}
// Verify parses unverifiedSignature and returns the content and the signer's identity
-func (m gpgmeSigningMechanism) Verify(unverifiedSignature []byte) (contents []byte, keyIdentity string, err error) {
+func (m *gpgmeSigningMechanism) Verify(unverifiedSignature []byte) (contents []byte, keyIdentity string, err error) {
signedBuffer := bytes.Buffer{}
signedData, err := gpgme.NewDataWriter(&signedBuffer)
if err != nil {
@@ -170,6 +170,6 @@ func (m gpgmeSigningMechanism) Verify(unverifiedSignature []byte) (contents []by
// WARNING: The short key identifier (which correponds to "Key ID" for OpenPGP keys)
// is NOT the same as a "key identity" used in other calls ot this interface, and
// the values may have no recognizable relationship if the public key is not available.
-func (m gpgmeSigningMechanism) UntrustedSignatureContents(untrustedSignature []byte) (untrustedContents []byte, shortKeyIdentifier string, err error) {
+func (m *gpgmeSigningMechanism) UntrustedSignatureContents(untrustedSignature []byte) (untrustedContents []byte, shortKeyIdentifier string, err error) {
return gpgUntrustedSignatureContents(untrustedSignature)
}
diff --git a/vendor/github.com/containers/image/v5/signature/mechanism_openpgp.go b/vendor/github.com/containers/image/v5/signature/mechanism_openpgp.go
index eccd610c9..51f20f310 100644
--- a/vendor/github.com/containers/image/v5/signature/mechanism_openpgp.go
+++ b/vendor/github.com/containers/image/v5/signature/mechanism_openpgp.go
@@ -154,6 +154,6 @@ func (m *openpgpSigningMechanism) Verify(unverifiedSignature []byte) (contents [
// WARNING: The short key identifier (which correponds to "Key ID" for OpenPGP keys)
// is NOT the same as a "key identity" used in other calls ot this interface, and
// the values may have no recognizable relationship if the public key is not available.
-func (m openpgpSigningMechanism) UntrustedSignatureContents(untrustedSignature []byte) (untrustedContents []byte, shortKeyIdentifier string, err error) {
+func (m *openpgpSigningMechanism) UntrustedSignatureContents(untrustedSignature []byte) (untrustedContents []byte, shortKeyIdentifier string, err error) {
return gpgUntrustedSignatureContents(untrustedSignature)
}
diff --git a/vendor/github.com/containers/image/v5/types/types.go b/vendor/github.com/containers/image/v5/types/types.go
index d38a17fab..ba249ca25 100644
--- a/vendor/github.com/containers/image/v5/types/types.go
+++ b/vendor/github.com/containers/image/v5/types/types.go
@@ -547,6 +547,8 @@ type SystemContext struct {
// Note that this field is used mainly to integrate containers/image into projectatomic/docker
// in order to not break any existing docker's integration tests.
DockerDisableV1Ping bool
+ // If true, dockerImageDestination.SupportedManifestMIMETypes will omit the Schema1 media types from the supported list
+ DockerDisableDestSchema1MIMETypes bool
// Directory to use for OSTree temporary files
OSTreeTmpDirPath string
diff --git a/vendor/github.com/containers/image/v5/version/version.go b/vendor/github.com/containers/image/v5/version/version.go
index a92774466..0fd7a4a37 100644
--- a/vendor/github.com/containers/image/v5/version/version.go
+++ b/vendor/github.com/containers/image/v5/version/version.go
@@ -6,9 +6,9 @@ const (
// VersionMajor is for an API incompatible changes
VersionMajor = 5
// VersionMinor is for functionality in a backwards-compatible manner
- VersionMinor = 1
+ VersionMinor = 2
// VersionPatch is for backwards-compatible bug fixes
- VersionPatch = 0
+ VersionPatch = 1
// VersionDev indicates development branch. Releases will be empty string.
VersionDev = ""
diff --git a/vendor/github.com/containers/storage/.cirrus.yml b/vendor/github.com/containers/storage/.cirrus.yml
index e4b38947d..3463adf90 100644
--- a/vendor/github.com/containers/storage/.cirrus.yml
+++ b/vendor/github.com/containers/storage/.cirrus.yml
@@ -19,7 +19,7 @@ env:
####
# GCE project where images live
IMAGE_PROJECT: "libpod-218412"
- _BUILT_IMAGE_SUFFIX: "libpod-6228273469587456"
+ _BUILT_IMAGE_SUFFIX: "libpod-5874660151656448"
FEDORA_CACHE_IMAGE_NAME: "fedora-31-${_BUILT_IMAGE_SUFFIX}"
PRIOR_FEDORA_CACHE_IMAGE_NAME: "fedora-30-${_BUILT_IMAGE_SUFFIX}"
UBUNTU_CACHE_IMAGE_NAME: "ubuntu-19-${_BUILT_IMAGE_SUFFIX}"
@@ -50,31 +50,50 @@ gce_instance:
disk: 200
image_name: "${FEDORA_CACHE_IMAGE_NAME}"
+
testing_task:
+
depends_on:
- lint
+
+ # Not all $TEST_DRIVER combinations are valid for all OS types.
+ # Note: Nested-variable resolution happens at runtime, not eval. time.
+ # Use verbose logic for ease of reading/maintaining.
+ only_if: >-
+ ( $VM_IMAGE =~ '.*UBUNTU.*' && $TEST_DRIVER == "vfs" ) ||
+ ( $VM_IMAGE =~ '.*UBUNTU.*' && $TEST_DRIVER == "aufs" ) ||
+ ( $VM_IMAGE =~ '.*UBUNTU.*' && $TEST_DRIVER == "overlay" ) ||
+ ( $VM_IMAGE =~ '.*UBUNTU.*' && $TEST_DRIVER == "fuse-overlay" ) ||
+ ( $VM_IMAGE =~ '.*FEDORA.*' && $TEST_DRIVER != "aufs" )
+
+ allow_failures: $TEST_DRIVER == "devicemapper"
+
+ env:
+ matrix:
+ VM_IMAGE: "${FEDORA_CACHE_IMAGE_NAME}"
+ VM_IMAGE: "${PRIOR_FEDORA_CACHE_IMAGE_NAME}"
+ VM_IMAGE: "${UBUNTU_CACHE_IMAGE_NAME}"
+ # VM_IMAGE: "${PRIOR_UBUNTU_CACHE_IMAGE_NAME}" # No fuse3 support
+ matrix: # See ./contrib/cirrus/build_and_test.sh
+ TEST_DRIVER: "vfs"
+ TEST_DRIVER: "aufs"
+ TEST_DRIVER: "overlay"
+ TEST_DRIVER: "fuse-overlay"
+ TEST_DRIVER: "devicemapper"
+ TEST_DRIVER: "fuse-overlay-whiteout"
+
gce_instance: # Only need to specify differences from defaults (above)
- matrix: # Duplicate this task for each matrix product.
- image_name: "${FEDORA_CACHE_IMAGE_NAME}"
- image_name: "${PRIOR_FEDORA_CACHE_IMAGE_NAME}"
- image_name: "${UBUNTU_CACHE_IMAGE_NAME}"
- # image_name: "${PRIOR_UBUNTU_CACHE_IMAGE_NAME}" # No fuse3 support
+ image_name: "${VM_IMAGE}"
# Separate scripts for separate outputs, makes debugging easier.
setup_script: '${CIRRUS_WORKING_DIR}/${SCRIPT_BASE}/setup.sh |& ${_TIMESTAMP}'
build_and_test_script: '${CIRRUS_WORKING_DIR}/${SCRIPT_BASE}/build_and_test.sh |& ${_TIMESTAMP}'
- # Log collection when job was successful
- df_script: '${_DFCMD} || true'
- rh_audit_log_script: '${_RAUDITCMD} || true'
- ubuntu_audit_log_script: '${_UAUDITCMD} || true'
- journal_log_script: '${_JOURNALCMD} || true'
-
- on_failure: # Script names must be different from above
- failure_df_script: '${_DFCMD} || true'
- failure_rh_audit_log_script: '${_RAUDITCMD} || true'
- failure_ubuntu_audit_log_script: '${_UAUDITCMD} || true'
- failure_journal_log_script: '${_JOURNALCMD} || true'
+ always:
+ df_script: '${_DFCMD} || true'
+ rh_audit_log_script: '${_RAUDITCMD} || true'
+ ubuntu_audit_log_script: '${_UAUDITCMD} || true'
+ journal_log_script: '${_JOURNALCMD} || true'
lint_task:
env:
@@ -94,7 +113,7 @@ lint_task:
meta_task:
container:
- image: "quay.io/libpod/imgts:latest" # see contrib/imgts
+ image: "quay.io/libpod/imgts:master"
cpu: 1
memory: 1
diff --git a/vendor/github.com/containers/storage/.golangci.yml b/vendor/github.com/containers/storage/.golangci.yml
index ec4ebb187..cd4638a39 100644
--- a/vendor/github.com/containers/storage/.golangci.yml
+++ b/vendor/github.com/containers/storage/.golangci.yml
@@ -3,37 +3,35 @@ run:
concurrency: 6
deadline: 5m
linters:
- disable-all: true
- enable:
- - bodyclose
- - depguard
- - gofmt
- - interfacer
- - typecheck
- # - deadcode
- # - dupl
- # - errcheck
- # - gochecknoglobals
- # - gochecknoinits
- # - goconst
- # - gocritic
- # - gocyclo
- # - goimports
- # - golint
- # - gosec
- # - gosimple
- # - govet
- # - ineffassign
- # - lll
- # - maligned
- # - misspell
- # - nakedret
- # - prealloc
- # - scopelint
- # - staticcheck
- # - structcheck
- # - stylecheck
- # - unconvert
- # - unparam
- # - unused
- # - varcheck
+ enable-all: true
+ disable:
+ - dogsled
+ - dupl
+ - errcheck
+ - funlen
+ - gochecknoglobals
+ - gochecknoinits
+ - gocognit
+ - gocritic
+ - gocyclo
+ - godox
+ - gomnd
+ - gosec
+ - gosimple
+ - govet
+ - ineffassign
+ - lll
+ - maligned
+ - misspell
+ - nakedret
+ - prealloc
+ - scopelint
+ - staticcheck
+ - structcheck
+ - stylecheck
+ - unconvert
+ - unparam
+ - unused
+ - varcheck
+ - whitespace
+ - wsl
diff --git a/vendor/github.com/containers/storage/.travis.yml b/vendor/github.com/containers/storage/.travis.yml
deleted file mode 100644
index a7865729d..000000000
--- a/vendor/github.com/containers/storage/.travis.yml
+++ /dev/null
@@ -1,62 +0,0 @@
----
-
-sudo: required
-
-# N/B: host go env. not actually used, see .run_ci_tests.sh
-language: go
-go:
- - master
-
-services:
- - docker
-
-env:
- # Ubuntu
- - GO_VERSION="stable"
- DISTRO="ubuntu"
-
- - GO_VERSION="1.12.12"
- DISTRO="ubuntu"
-
- # Fedora
- - GO_VERSION="stable"
- DISTRO="fedora"
-
- - GO_VERSION="1.12.12"
- DISTRO="fedora"
-
- # CentOS
- - GO_VERSION="stable"
- DISTRO="centos"
-
- - GO_VERSION="1.12.12"
- DISTRO="centos"
-
-# GO_VERSION="stable" builds successfully, but tests fail on all platforms.
-# Run the tests, but ignore the result (for now)
-matrix:
- allow_failures:
- - env: GO_VERSION="stable" DISTRO="ubuntu"
- - env: GO_VERSION="stable" DISTRO="fedora"
- - env: GO_VERSION="stable" DISTRO="centos"
-
-before_install:
- - sudo apt-get -qq update
- - sudo apt-get -qq install realpath
-
-script:
- - echo "Travis/host environment:"
- - export TRAVIS_ENV="-e TRAVIS=$TRAVIS
- -e CI=$CI
- -e TRAVIS_COMMIT=$TRAVIS_COMMIT
- -e TRAVIS_COMMIT_RANGE=$TRAVIS_COMMIT_RANGE
- -e TRAVIS_REPO_SLUG=$TRAVIS_REPO_SLUG
- -e TRAVIS_PULL_REQUEST=$TRAVIS_PULL_REQUEST
- -e TRAVIS_PULL_REQUEST_SHA=$TRAVIS_PULL_REQUEST_SHA
- -e TRAVIS_PULL_REQUEST_SLUG=$TRAVIS_PULL_REQUEST_SLUG
- -e TRAVIS_BRANCH=$TRAVIS_BRANCH
- -e TRAVIS_JOB_ID=$TRAVIS_JOB_ID
- -e TRAVIS_BUILD_DIR=$TRAVIS_BUILD_DIR"
- - env
- - echo "Running tests in SPC using ./hack/run_ci_tests.sh"
- - ./hack/run_ci_tests.sh
diff --git a/vendor/github.com/containers/storage/CODE-OF-CONDUCT.md b/vendor/github.com/containers/storage/CODE-OF-CONDUCT.md
new file mode 100644
index 000000000..be0791620
--- /dev/null
+++ b/vendor/github.com/containers/storage/CODE-OF-CONDUCT.md
@@ -0,0 +1,3 @@
+## The Containers Storage Project Community Code of Conduct
+
+The Containers Storage project follows the [Containers Community Code of Conduct](https://github.com/containers/common/blob/master/CODE-OF-CONDUCT.md).
diff --git a/vendor/github.com/containers/storage/Makefile b/vendor/github.com/containers/storage/Makefile
index 1b69d6060..09937303b 100644
--- a/vendor/github.com/containers/storage/Makefile
+++ b/vendor/github.com/containers/storage/Makefile
@@ -54,19 +54,19 @@ sources := $(wildcard *.go cmd/containers-storage/*.go drivers/*.go drivers/*/*.
containers-storage: $(sources) ## build using gc on the host
$(GO_BUILD) -compiler gc $(BUILDFLAGS) ./cmd/containers-storage
-layers_ffjson.go: layers.go
+layers_ffjson.go: $(FFJSON) layers.go
$(RM) $@
$(FFJSON) layers.go
-images_ffjson.go: images.go
+images_ffjson.go: $(FFJSON) images.go
$(RM) $@
$(FFJSON) images.go
-containers_ffjson.go: containers.go
+containers_ffjson.go: $(FFJSON) containers.go
$(RM) $@
$(FFJSON) containers.go
-pkg/archive/archive_ffjson.go: pkg/archive/archive.go
+pkg/archive/archive_ffjson.go: $(FFJSON) pkg/archive/archive.go
$(RM) $@
$(FFJSON) pkg/archive/archive.go
@@ -118,6 +118,9 @@ validate: ## validate DCO, gofmt, ./pkg/ isolation, golint,\ngo vet and vendor u
install.tools:
make -C tests/tools
+$(FFJSON):
+ make -C tests/tools build/ffjson
+
install.docs: docs
make -C docs install
diff --git a/vendor/github.com/containers/storage/VERSION b/vendor/github.com/containers/storage/VERSION
index 928b5d437..de646d2fc 100644
--- a/vendor/github.com/containers/storage/VERSION
+++ b/vendor/github.com/containers/storage/VERSION
@@ -1 +1 @@
-1.15.8-dev
+1.16.6
diff --git a/vendor/github.com/containers/storage/drivers/aufs/aufs.go b/vendor/github.com/containers/storage/drivers/aufs/aufs.go
index 4430670a2..c4ced0488 100644
--- a/vendor/github.com/containers/storage/drivers/aufs/aufs.go
+++ b/vendor/github.com/containers/storage/drivers/aufs/aufs.go
@@ -35,7 +35,7 @@ import (
"sync"
"time"
- "github.com/containers/storage/drivers"
+ graphdriver "github.com/containers/storage/drivers"
"github.com/containers/storage/pkg/archive"
"github.com/containers/storage/pkg/chrootarchive"
"github.com/containers/storage/pkg/directory"
diff --git a/vendor/github.com/containers/storage/drivers/btrfs/btrfs.go b/vendor/github.com/containers/storage/drivers/btrfs/btrfs.go
index 5be1639d0..be4362dc0 100644
--- a/vendor/github.com/containers/storage/drivers/btrfs/btrfs.go
+++ b/vendor/github.com/containers/storage/drivers/btrfs/btrfs.go
@@ -26,7 +26,7 @@ import (
"sync"
"unsafe"
- "github.com/containers/storage/drivers"
+ graphdriver "github.com/containers/storage/drivers"
"github.com/containers/storage/pkg/idtools"
"github.com/containers/storage/pkg/mount"
"github.com/containers/storage/pkg/parsers"
diff --git a/vendor/github.com/containers/storage/drivers/chown.go b/vendor/github.com/containers/storage/drivers/chown.go
index f2f1ec386..7604a86db 100644
--- a/vendor/github.com/containers/storage/drivers/chown.go
+++ b/vendor/github.com/containers/storage/drivers/chown.go
@@ -5,10 +5,10 @@ import (
"encoding/json"
"fmt"
"os"
- "path/filepath"
"github.com/containers/storage/pkg/idtools"
"github.com/containers/storage/pkg/reexec"
+ "github.com/opencontainers/selinux/pkg/pwalk"
)
const (
@@ -51,16 +51,13 @@ func chownByMapsMain() {
if len(toHost.UIDs()) == 0 && len(toHost.GIDs()) == 0 {
toHost = nil
}
- chown := func(path string, info os.FileInfo, err error) error {
- if err != nil {
- return fmt.Errorf("error walking to %q: %v", path, err)
- }
+ chown := func(path string, info os.FileInfo, _ error) error {
if path == "." {
return nil
}
return platformLChown(path, info, toHost, toContainer)
}
- if err := filepath.Walk(".", chown); err != nil {
+ if err := pwalk.Walk(".", chown); err != nil {
fmt.Fprintf(os.Stderr, "error during chown: %v", err)
os.Exit(1)
}
diff --git a/vendor/github.com/containers/storage/drivers/chown_unix.go b/vendor/github.com/containers/storage/drivers/chown_unix.go
index 51d6d754b..3a3978b71 100644
--- a/vendor/github.com/containers/storage/drivers/chown_unix.go
+++ b/vendor/github.com/containers/storage/drivers/chown_unix.go
@@ -12,66 +12,63 @@ import (
)
func platformLChown(path string, info os.FileInfo, toHost, toContainer *idtools.IDMappings) error {
- sysinfo := info.Sys()
- if st, ok := sysinfo.(*syscall.Stat_t); ok {
- // Map an on-disk UID/GID pair from host to container
- // using the first map, then back to the host using the
- // second map. Skip that first step if they're 0, to
- // compensate for cases where a parent layer should
- // have had a mapped value, but didn't.
- uid, gid := int(st.Uid), int(st.Gid)
- if toContainer != nil {
- pair := idtools.IDPair{
- UID: uid,
- GID: gid,
- }
- mappedUid, mappedGid, err := toContainer.ToContainer(pair)
- if err != nil {
- if (uid != 0) || (gid != 0) {
- return fmt.Errorf("error mapping host ID pair %#v for %q to container: %v", pair, path, err)
- }
- mappedUid, mappedGid = uid, gid
- }
- uid, gid = mappedUid, mappedGid
+ st, ok := info.Sys().(*syscall.Stat_t)
+ if !ok {
+ return nil
+ }
+ // Map an on-disk UID/GID pair from host to container
+ // using the first map, then back to the host using the
+ // second map. Skip that first step if they're 0, to
+ // compensate for cases where a parent layer should
+ // have had a mapped value, but didn't.
+ uid, gid := int(st.Uid), int(st.Gid)
+ if toContainer != nil {
+ pair := idtools.IDPair{
+ UID: uid,
+ GID: gid,
}
- if toHost != nil {
- pair := idtools.IDPair{
- UID: uid,
- GID: gid,
- }
- mappedPair, err := toHost.ToHost(pair)
- if err != nil {
- return fmt.Errorf("error mapping container ID pair %#v for %q to host: %v", pair, path, err)
+ mappedUID, mappedGID, err := toContainer.ToContainer(pair)
+ if err != nil {
+ if (uid != 0) || (gid != 0) {
+ return fmt.Errorf("error mapping host ID pair %#v for %q to container: %v", pair, path, err)
}
- uid, gid = mappedPair.UID, mappedPair.GID
+ mappedUID, mappedGID = uid, gid
+ }
+ uid, gid = mappedUID, mappedGID
+ }
+ if toHost != nil {
+ pair := idtools.IDPair{
+ UID: uid,
+ GID: gid,
+ }
+ mappedPair, err := toHost.ToHost(pair)
+ if err != nil {
+ return fmt.Errorf("error mapping container ID pair %#v for %q to host: %v", pair, path, err)
+ }
+ uid, gid = mappedPair.UID, mappedPair.GID
+ }
+ if uid != int(st.Uid) || gid != int(st.Gid) {
+ cap, err := system.Lgetxattr(path, "security.capability")
+ if err != nil && err != system.ErrNotSupportedPlatform {
+ return fmt.Errorf("%s: Lgetxattr(%q): %v", os.Args[0], path, err)
}
- if uid != int(st.Uid) || gid != int(st.Gid) {
- stat, err := os.Lstat(path)
- if err != nil {
- return fmt.Errorf("%s: lstat(%q): %v", os.Args[0], path, err)
- }
- cap, err := system.Lgetxattr(path, "security.capability")
- if err != nil && err != system.ErrNotSupportedPlatform {
- return fmt.Errorf("%s: Lgetxattr(%q): %v", os.Args[0], path, err)
- }
- // Make the change.
- if err := syscall.Lchown(path, uid, gid); err != nil {
- return fmt.Errorf("%s: chown(%q): %v", os.Args[0], path, err)
- }
- // Restore the SUID and SGID bits if they were originally set.
- if (stat.Mode()&os.ModeSymlink == 0) && stat.Mode()&(os.ModeSetuid|os.ModeSetgid) != 0 {
- if err := os.Chmod(path, stat.Mode()); err != nil {
- return fmt.Errorf("%s: chmod(%q): %v", os.Args[0], path, err)
- }
+ // Make the change.
+ if err := syscall.Lchown(path, uid, gid); err != nil {
+ return fmt.Errorf("%s: chown(%q): %v", os.Args[0], path, err)
+ }
+ // Restore the SUID and SGID bits if they were originally set.
+ if (info.Mode()&os.ModeSymlink == 0) && info.Mode()&(os.ModeSetuid|os.ModeSetgid) != 0 {
+ if err := os.Chmod(path, info.Mode()); err != nil {
+ return fmt.Errorf("%s: chmod(%q): %v", os.Args[0], path, err)
}
- if cap != nil {
- if err := system.Lsetxattr(path, "security.capability", cap, 0); err != nil {
- return fmt.Errorf("%s: Lsetxattr(%q): %v", os.Args[0], path, err)
- }
+ }
+ if cap != nil {
+ if err := system.Lsetxattr(path, "security.capability", cap, 0); err != nil {
+ return fmt.Errorf("%s: Lsetxattr(%q): %v", os.Args[0], path, err)
}
-
}
+
}
return nil
}
diff --git a/vendor/github.com/containers/storage/drivers/devmapper/deviceset.go b/vendor/github.com/containers/storage/drivers/devmapper/deviceset.go
index 1ea6cfc36..d0c7fab0a 100644
--- a/vendor/github.com/containers/storage/drivers/devmapper/deviceset.go
+++ b/vendor/github.com/containers/storage/drivers/devmapper/deviceset.go
@@ -18,7 +18,7 @@ import (
"sync"
"time"
- "github.com/containers/storage/drivers"
+ graphdriver "github.com/containers/storage/drivers"
"github.com/containers/storage/pkg/devicemapper"
"github.com/containers/storage/pkg/dmesg"
"github.com/containers/storage/pkg/idtools"
@@ -49,8 +49,13 @@ var (
lvmSetupConfigForce bool
)
-const deviceSetMetaFile string = "deviceset-metadata"
-const transactionMetaFile string = "transaction-metadata"
+const (
+ deviceSetMetaFile = "deviceset-metadata"
+ transactionMetaFile = "transaction-metadata"
+ xfs = "xfs"
+ ext4 = "ext4"
+ base = "base"
+)
type transaction struct {
OpenTransactionID uint64 `json:"open_transaction_id"`
@@ -199,7 +204,7 @@ func getDevName(name string) string {
func (info *devInfo) Name() string {
hash := info.Hash
if hash == "" {
- hash = "base"
+ hash = base
}
return fmt.Sprintf("%s-%s", info.devices.devicePrefix, hash)
}
@@ -219,7 +224,7 @@ func (devices *DeviceSet) metadataDir() string {
func (devices *DeviceSet) metadataFile(info *devInfo) string {
file := info.Hash
if file == "" {
- file = "base"
+ file = base
}
return path.Join(devices.metadataDir(), file)
}
@@ -440,7 +445,7 @@ func (devices *DeviceSet) deviceFileWalkFunction(path string, finfo os.FileInfo)
logrus.Debugf("devmapper: Loading data for file %s", path)
hash := finfo.Name()
- if hash == "base" {
+ if hash == base {
hash = ""
}
@@ -542,7 +547,7 @@ func xfsSupported() error {
}
// Check if kernel supports xfs filesystem or not.
- exec.Command("modprobe", "xfs").Run()
+ exec.Command("modprobe", xfs).Run()
f, err := os.Open("/proc/filesystems")
if err != nil {
@@ -567,16 +572,16 @@ func xfsSupported() error {
func determineDefaultFS() string {
err := xfsSupported()
if err == nil {
- return "xfs"
+ return xfs
}
- logrus.Warnf("devmapper: XFS is not supported in your system (%v). Defaulting to ext4 filesystem", err)
- return "ext4"
+ logrus.Warnf("devmapper: XFS is not supported in your system (%v). Defaulting to %s filesystem", ext4, err)
+ return ext4
}
// mkfsOptions tries to figure out whether some additional mkfs options are required
func mkfsOptions(fs string) []string {
- if fs == "xfs" && !kernel.CheckKernelVersion(3, 16, 0) {
+ if fs == xfs && !kernel.CheckKernelVersion(3, 16, 0) {
// For kernels earlier than 3.16 (and newer xfsutils),
// some xfs features need to be explicitly disabled.
return []string{"-m", "crc=0,finobt=0"}
@@ -609,9 +614,9 @@ func (devices *DeviceSet) createFilesystem(info *devInfo) (err error) {
}()
switch devices.filesystem {
- case "xfs":
+ case xfs:
err = exec.Command("mkfs.xfs", args...).Run()
- case "ext4":
+ case ext4:
err = exec.Command("mkfs.ext4", append([]string{"-E", "nodiscard,lazy_itable_init=0,lazy_journal_init=0"}, args...)...).Run()
if err != nil {
err = exec.Command("mkfs.ext4", append([]string{"-E", "nodiscard,lazy_itable_init=0"}, args...)...).Run()
@@ -1197,24 +1202,24 @@ func (devices *DeviceSet) growFS(info *devInfo) error {
}
options := ""
- if devices.BaseDeviceFilesystem == "xfs" {
+ if devices.BaseDeviceFilesystem == xfs {
// XFS needs nouuid or it can't mount filesystems with the same fs
options = joinMountOptions(options, "nouuid")
}
options = joinMountOptions(options, devices.mountOptions)
if err := mount.Mount(info.DevName(), fsMountPoint, devices.BaseDeviceFilesystem, options); err != nil {
- return fmt.Errorf("Error mounting '%s' on '%s': %s\n%v", info.DevName(), fsMountPoint, err, string(dmesg.Dmesg(256)))
+ return errors.Wrapf(err, "Failed to mount; dmesg: %s", string(dmesg.Dmesg(256)))
}
defer unix.Unmount(fsMountPoint, unix.MNT_DETACH)
switch devices.BaseDeviceFilesystem {
- case "ext4":
+ case ext4:
if out, err := exec.Command("resize2fs", info.DevName()).CombinedOutput(); err != nil {
return fmt.Errorf("Failed to grow rootfs:%v:%s", err, string(out))
}
- case "xfs":
+ case xfs:
if out, err := exec.Command("xfs_growfs", info.DevName()).CombinedOutput(); err != nil {
return fmt.Errorf("Failed to grow rootfs:%v:%s", err, string(out))
}
@@ -2391,7 +2396,7 @@ func (devices *DeviceSet) MountDevice(hash, path string, moptions graphdriver.Mo
options := ""
- if fstype == "xfs" {
+ if fstype == xfs {
// XFS needs nouuid or it can't mount filesystems with the same fs
options = joinMountOptions(options, "nouuid")
}
@@ -2409,10 +2414,10 @@ func (devices *DeviceSet) MountDevice(hash, path string, moptions graphdriver.Mo
options = joinMountOptions(options, label.FormatMountLabel("", moptions.MountLabel))
if err := mount.Mount(info.DevName(), path, fstype, options); err != nil {
- return fmt.Errorf("devmapper: Error mounting '%s' on '%s': %s\n%v", info.DevName(), path, err, string(dmesg.Dmesg(256)))
+ return errors.Wrapf(err, "Failed to mount; dmesg: %s", string(dmesg.Dmesg(256)))
}
- if fstype == "xfs" && devices.xfsNospaceRetries != "" {
+ if fstype == xfs && devices.xfsNospaceRetries != "" {
if err := devices.xfsSetNospaceRetries(info); err != nil {
unix.Unmount(path, unix.MNT_DETACH)
devices.deactivateDevice(info)
@@ -2693,7 +2698,7 @@ func NewDeviceSet(root string, doInit bool, options []string, uidMaps, gidMaps [
}
devices.metaDataLoopbackSize = size
case "dm.fs":
- if val != "ext4" && val != "xfs" {
+ if val != ext4 && val != xfs {
return nil, fmt.Errorf("devmapper: Unsupported filesystem %s", val)
}
devices.filesystem = val
diff --git a/vendor/github.com/containers/storage/drivers/devmapper/driver.go b/vendor/github.com/containers/storage/drivers/devmapper/driver.go
index 3c044c12e..ca50e7f06 100644
--- a/vendor/github.com/containers/storage/drivers/devmapper/driver.go
+++ b/vendor/github.com/containers/storage/drivers/devmapper/driver.go
@@ -9,7 +9,7 @@ import (
"path"
"strconv"
- "github.com/containers/storage/drivers"
+ graphdriver "github.com/containers/storage/drivers"
"github.com/containers/storage/pkg/devicemapper"
"github.com/containers/storage/pkg/idtools"
"github.com/containers/storage/pkg/locker"
diff --git a/vendor/github.com/containers/storage/drivers/driver.go b/vendor/github.com/containers/storage/drivers/driver.go
index 8d6b2a5dc..a5393c10f 100644
--- a/vendor/github.com/containers/storage/drivers/driver.go
+++ b/vendor/github.com/containers/storage/drivers/driver.go
@@ -49,8 +49,8 @@ type MountOpts struct {
// Mount label is the MAC Labels to assign to mount point (SELINUX)
MountLabel string
// UidMaps & GidMaps are the User Namespace mappings to be assigned to content in the mount point
- UidMaps []idtools.IDMap
- GidMaps []idtools.IDMap
+ UidMaps []idtools.IDMap // nolint: golint
+ GidMaps []idtools.IDMap // nolint: golint
Options []string
}
diff --git a/vendor/github.com/containers/storage/drivers/overlay/overlay.go b/vendor/github.com/containers/storage/drivers/overlay/overlay.go
index 25d885be9..232cac71a 100644
--- a/vendor/github.com/containers/storage/drivers/overlay/overlay.go
+++ b/vendor/github.com/containers/storage/drivers/overlay/overlay.go
@@ -401,9 +401,8 @@ func supportsOverlay(home string, homeMagic graphdriver.FsMagic, rootUID, rootGI
if err == nil {
logrus.Debugf("overlay test mount with multiple lowers succeeded")
return supportsDType, nil
- } else {
- logrus.Debugf("overlay test mount with multiple lowers failed %v", err)
}
+ logrus.Debugf("overlay test mount with multiple lowers failed %v", err)
}
flags = fmt.Sprintf("lowerdir=%s,upperdir=%s,workdir=%s", lower1Dir, upperDir, workDir)
if len(flags) < unix.Getpagesize() {
@@ -411,9 +410,8 @@ func supportsOverlay(home string, homeMagic graphdriver.FsMagic, rootUID, rootGI
if err == nil {
logrus.Errorf("overlay test mount with multiple lowers failed, but succeeded with a single lower")
return supportsDType, errors.Wrap(graphdriver.ErrNotSupported, "kernel too old to provide multiple lowers feature for overlay")
- } else {
- logrus.Debugf("overlay test mount with a single lower failed %v", err)
}
+ logrus.Debugf("overlay test mount with a single lower failed %v", err)
}
logrus.Errorf("'overlay' is not supported over %s at %q", backingFs, home)
return supportsDType, errors.Wrapf(graphdriver.ErrIncompatibleFS, "'overlay' is not supported over %s at %q", backingFs, home)
@@ -810,15 +808,6 @@ func (d *Driver) get(id string, disableShifting bool, options graphdriver.MountO
return "", err
}
readWrite := true
- // fuse-overlayfs doesn't support working without an upperdir.
- if d.options.mountProgram == "" {
- for _, o := range options.Options {
- if o == "ro" {
- readWrite = false
- break
- }
- }
- }
lowers, err := ioutil.ReadFile(path.Join(dir, lowerFile))
if err != nil && !os.IsNotExist(err) {
diff --git a/vendor/github.com/containers/storage/drivers/overlayutils/overlayutils.go b/vendor/github.com/containers/storage/drivers/overlayutils/overlayutils.go
index 49aaad07d..9fc57b36b 100644
--- a/vendor/github.com/containers/storage/drivers/overlayutils/overlayutils.go
+++ b/vendor/github.com/containers/storage/drivers/overlayutils/overlayutils.go
@@ -5,7 +5,7 @@ package overlayutils
import (
"fmt"
- "github.com/containers/storage/drivers"
+ graphdriver "github.com/containers/storage/drivers"
"github.com/pkg/errors"
)
diff --git a/vendor/github.com/containers/storage/drivers/vfs/driver.go b/vendor/github.com/containers/storage/drivers/vfs/driver.go
index 58a1635ae..f2859b427 100644
--- a/vendor/github.com/containers/storage/drivers/vfs/driver.go
+++ b/vendor/github.com/containers/storage/drivers/vfs/driver.go
@@ -8,7 +8,7 @@ import (
"strconv"
"strings"
- "github.com/containers/storage/drivers"
+ graphdriver "github.com/containers/storage/drivers"
"github.com/containers/storage/pkg/archive"
"github.com/containers/storage/pkg/idtools"
"github.com/containers/storage/pkg/parsers"
diff --git a/vendor/github.com/containers/storage/drivers/zfs/zfs.go b/vendor/github.com/containers/storage/drivers/zfs/zfs.go
index a2bf5565b..c9c8c5c3c 100644
--- a/vendor/github.com/containers/storage/drivers/zfs/zfs.go
+++ b/vendor/github.com/containers/storage/drivers/zfs/zfs.go
@@ -12,7 +12,7 @@ import (
"sync"
"time"
- "github.com/containers/storage/drivers"
+ graphdriver "github.com/containers/storage/drivers"
"github.com/containers/storage/pkg/idtools"
"github.com/containers/storage/pkg/mount"
"github.com/containers/storage/pkg/parsers"
diff --git a/vendor/github.com/containers/storage/drivers/zfs/zfs_linux.go b/vendor/github.com/containers/storage/drivers/zfs/zfs_linux.go
index fb1ef3a3d..edcb1da36 100644
--- a/vendor/github.com/containers/storage/drivers/zfs/zfs_linux.go
+++ b/vendor/github.com/containers/storage/drivers/zfs/zfs_linux.go
@@ -1,7 +1,7 @@
package zfs
import (
- "github.com/containers/storage/drivers"
+ graphdriver "github.com/containers/storage/drivers"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
)
diff --git a/vendor/github.com/containers/storage/go.mod b/vendor/github.com/containers/storage/go.mod
index b7a05a65b..40cd856a9 100644
--- a/vendor/github.com/containers/storage/go.mod
+++ b/vendor/github.com/containers/storage/go.mod
@@ -2,29 +2,25 @@ module github.com/containers/storage
require (
github.com/BurntSushi/toml v0.3.1
- github.com/DataDog/zstd v1.4.0 // indirect
github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5
github.com/Microsoft/hcsshim v0.8.7
- github.com/docker/docker v0.0.0-20171019062838-86f080cff091 // indirect
github.com/docker/go-units v0.4.0
- github.com/klauspost/compress v1.9.7
- github.com/klauspost/cpuid v1.2.1 // indirect
- github.com/klauspost/pgzip v1.2.1
- github.com/mattn/go-shellwords v1.0.7
+ github.com/klauspost/compress v1.10.3
+ github.com/klauspost/pgzip v1.2.3
+ github.com/mattn/go-shellwords v1.0.10
github.com/mistifyio/go-zfs v2.1.1+incompatible
github.com/opencontainers/go-digest v1.0.0-rc1
github.com/opencontainers/runc v1.0.0-rc9
- github.com/opencontainers/selinux v1.3.0
+ github.com/opencontainers/selinux v1.4.0
github.com/pkg/errors v0.9.1
github.com/pquerna/ffjson v0.0.0-20181028064349-e517b90714f7
- github.com/sirupsen/logrus v1.4.2
- github.com/spf13/pflag v1.0.3 // indirect
- github.com/stretchr/testify v1.4.0
+ github.com/sirupsen/logrus v1.5.0
+ github.com/stretchr/testify v1.5.1
github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2
github.com/tchap/go-patricia v2.3.0+incompatible
github.com/vbatts/tar-split v0.11.1
golang.org/x/net v0.0.0-20190628185345-da137c7871d7
- golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3
+ golang.org/x/sys v0.0.0-20191115151921-52ab43148777
gotest.tools v2.2.0+incompatible
)
diff --git a/vendor/github.com/containers/storage/go.sum b/vendor/github.com/containers/storage/go.sum
index ffda0c42f..2c53f6ba6 100644
--- a/vendor/github.com/containers/storage/go.sum
+++ b/vendor/github.com/containers/storage/go.sum
@@ -1,27 +1,15 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
-github.com/DataDog/zstd v1.4.0 h1:vhoV+DUHnRZdKW1i5UMjAk2G4JY8wN4ayRfYDNdEhwo=
-github.com/DataDog/zstd v1.4.0/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo=
-github.com/Microsoft/go-winio v0.4.12 h1:xAfWHN1IrQ0NJ9TBC0KBZoqLjzDTr1ML+4MywiUOryc=
-github.com/Microsoft/go-winio v0.4.12/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA=
-github.com/Microsoft/go-winio v0.4.14 h1:+hMXMk01us9KgxGb7ftKQt2Xpf5hH/yky+TDA+qxleU=
-github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA=
github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5 h1:ygIc8M6trr62pF5DucadTWGdEB4mEyvzi0e2nbcmcyA=
github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw=
-github.com/Microsoft/hcsshim v0.8.6 h1:ZfF0+zZeYdzMIVMZHKtDKJvLHj76XCuVae/jNkjj0IA=
-github.com/Microsoft/hcsshim v0.8.6/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg=
github.com/Microsoft/hcsshim v0.8.7 h1:ptnOoufxGSzauVTsdE+wMYnCWA301PdoN4xg5oRdZpg=
github.com/Microsoft/hcsshim v0.8.7/go.mod h1:OHd7sQqRFrYd3RmSgbgji+ctCwkbq2wbEYNSzOYtcBQ=
github.com/blang/semver v3.1.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
-github.com/checkpoint-restore/go-criu v0.0.0-20190109184317-bdb7599cd87b h1:T4nWG1TXIxeor8mAu5bFguPJgSIGhZqv/f0z55KCrJM=
-github.com/checkpoint-restore/go-criu v0.0.0-20190109184317-bdb7599cd87b/go.mod h1:TrMrLQfeENAPYPRsJuq3jsqdlRh3lvi6trTZJG8+tho=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/containerd/cgroups v0.0.0-20190919134610-bf292b21730f h1:tSNMc+rJDfmYntojat8lljbt1mgKNpTxUZJsSzJ9Y1s=
github.com/containerd/cgroups v0.0.0-20190919134610-bf292b21730f/go.mod h1:OApqhQ4XNSNC13gXIwDjhOQxjWa/NxkwZXJ1EvqT0ko=
github.com/containerd/console v0.0.0-20180822173158-c12b1e7919c1/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw=
-github.com/containerd/console v0.0.0-20181022165439-0650fd9eeb50 h1:WMpHmC6AxwWb9hMqhudkqG7A/p14KiMnl6d3r1iUMjU=
-github.com/containerd/console v0.0.0-20181022165439-0650fd9eeb50/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw=
github.com/containerd/containerd v1.3.0-beta.2.0.20190828155532-0293cbd26c69/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
github.com/containerd/fifo v0.0.0-20190226154929-a9fb20d87448/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI=
@@ -29,32 +17,18 @@ github.com/containerd/go-runc v0.0.0-20180907222934-5a6d9f37cfa3/go.mod h1:IV7qH
github.com/containerd/ttrpc v0.0.0-20190828154514-0e0f228740de/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o=
github.com/containerd/typeurl v0.0.0-20180627222232-a93fcdb778cd/go.mod h1:Cm3kwCdlkCfMSHURc+r6fwoGH6/F1hH3S4sg0rLFWPc=
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
-github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f h1:JOrtw2xFKzlg+cbHpyrpLDmnN1HqhBfnX7WDiW7eG2c=
-github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
-github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY=
-github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
-github.com/cyphar/filepath-securejoin v0.2.2 h1:jCwT2GTP+PY5nBz3c/YL5PAIbusElVrPujOBSCj8xRg=
-github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/docker/docker v0.0.0-20171019062838-86f080cff091 h1:QpxpTw4MJeOzbC7X00IFxnZhZx8oDOqXMrMAHiwNn54=
-github.com/docker/docker v0.0.0-20171019062838-86f080cff091/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw=
github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4=
-github.com/godbus/dbus v4.1.0+incompatible h1:WqqLRTsQic3apZUK9qC5sGNfXthmPXzUZ7nQPrNITa4=
-github.com/godbus/dbus v4.1.0+incompatible/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw=
github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE=
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
-github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
-github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
-github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ=
-github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/hashicorp/errwrap v0.0.0-20141028054710-7554cd9344ce/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
@@ -63,59 +37,34 @@ github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
-github.com/klauspost/compress v1.7.2 h1:liMOoeIvFpr9kEvalrZ7VVBA4wGf7zfOgwBjzz/5g2Y=
-github.com/klauspost/compress v1.7.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
-github.com/klauspost/compress v1.9.1 h1:TWy0o9J9c6LK9C8t7Msh6IAJNXbsU/nvKLTQUU5HdaY=
-github.com/klauspost/compress v1.9.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
-github.com/klauspost/compress v1.9.2 h1:LfVyl+ZlLlLDeQ/d2AqfGIIH4qEDu0Ed2S5GyhCWIWY=
-github.com/klauspost/compress v1.9.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
-github.com/klauspost/compress v1.9.3 h1:hkFELABwacUEgBfiguNeQydKv3M9pawBq8o24Ypw9+M=
-github.com/klauspost/compress v1.9.3/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
-github.com/klauspost/compress v1.9.4 h1:xhvAeUPQ2drNUhKtrGdTGNvV9nNafHMUkRyLkzxJoB4=
-github.com/klauspost/compress v1.9.4/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
-github.com/klauspost/compress v1.9.5 h1:U+CaK85mrNNb4k8BNOfgJtJ/gr6kswUCFj6miSzVC6M=
-github.com/klauspost/compress v1.9.5/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
-github.com/klauspost/compress v1.9.7 h1:hYW1gP94JUmAhBtJ+LNz5My+gBobDxPR1iVuKug26aA=
-github.com/klauspost/compress v1.9.7/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
-github.com/klauspost/cpuid v1.2.1 h1:vJi+O/nMdFt0vqm8NZBI6wzALWdA2X+egi0ogNyrC/w=
-github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
+github.com/klauspost/compress v1.10.2 h1:Znfn6hXZAHaLPNnlqUYRrBSReFHYybslgv4PTiyz6P0=
+github.com/klauspost/compress v1.10.2/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
+github.com/klauspost/compress v1.10.3 h1:OP96hzwJVBIHYU52pVTI6CczrxPvrGfgqF9N5eTO0Q8=
+github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
github.com/klauspost/pgzip v1.2.1 h1:oIPZROsWuPHpOdMVWLuJZXwgjhrW8r1yEX8UqMyeNHM=
github.com/klauspost/pgzip v1.2.1/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
+github.com/klauspost/pgzip v1.2.2 h1:8d4I0LDiieuGngsqlqOih9ker/NS0LX4V0i+EhiFWg0=
+github.com/klauspost/pgzip v1.2.2/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
+github.com/klauspost/pgzip v1.2.3 h1:Ce2to9wvs/cuJ2b86/CKQoTYr9VHfpanYosZ0UBJqdw=
+github.com/klauspost/pgzip v1.2.3/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
-github.com/mattn/go-shellwords v1.0.5 h1:JhhFTIOslh5ZsPrpa3Wdg8bF0WI3b44EMblmU9wIsXc=
-github.com/mattn/go-shellwords v1.0.5/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o=
-github.com/mattn/go-shellwords v1.0.6 h1:9Jok5pILi5S1MnDirGVTufYGtksUs/V2BWUP3ZkeUUI=
-github.com/mattn/go-shellwords v1.0.6/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o=
-github.com/mattn/go-shellwords v1.0.7 h1:KqhVjVZomx2puPACkj9vrGFqnp42Htvo9SEAWePHKOs=
-github.com/mattn/go-shellwords v1.0.7/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o=
+github.com/mattn/go-shellwords v1.0.10 h1:Y7Xqm8piKOO3v10Thp7Z36h4FYFjt5xB//6XvOrs2Gw=
+github.com/mattn/go-shellwords v1.0.10/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y=
github.com/mistifyio/go-zfs v2.1.1+incompatible h1:gAMO1HM9xBRONLHHYnu5iFsOJUiJdNZo6oqSENd4eW8=
github.com/mistifyio/go-zfs v2.1.1+incompatible/go.mod h1:8AuVvqP/mXw1px98n46wfvcGfQ4ci2FwoAjKYxuo3Z4=
-github.com/mrunalp/fileutils v0.0.0-20171103030105-7d4729fb3618 h1:7InQ7/zrOh6SlFjaXFubv0xX0HsuC9qJsdqm7bNQpYM=
-github.com/mrunalp/fileutils v0.0.0-20171103030105-7d4729fb3618/go.mod h1:x8F1gnqOkIEiO4rqoeEEEqQbo7HjGMTvyoq3gej4iT0=
github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
github.com/opencontainers/go-digest v1.0.0-rc1 h1:WzifXhOVOEOuFYOJAW6aQqW0TooG2iki3E3Ii+WN7gQ=
github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
github.com/opencontainers/runc v0.0.0-20190115041553-12f6a991201f/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
-github.com/opencontainers/runc v0.1.1 h1:GlxAyO6x8rfZYN9Tt0Kti5a/cP41iuiO2yYT0IJGY8Y=
-github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
-github.com/opencontainers/runc v1.0.0-rc8 h1:dDCFes8Hj1r/i5qnypONo5jdOme/8HWZC/aNDyhECt0=
-github.com/opencontainers/runc v1.0.0-rc8/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
github.com/opencontainers/runc v1.0.0-rc9 h1:/k06BMULKF5hidyoZymkoDCzdJzltZpz/UU4LguQVtc=
github.com/opencontainers/runc v1.0.0-rc9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
github.com/opencontainers/runtime-spec v0.1.2-0.20190507144316-5b71a03e2700/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
-github.com/opencontainers/runtime-spec v1.0.1 h1:wY4pOY8fBdSIvs9+IDHC55thBuEulhzfSgKeC1yFvzQ=
-github.com/opencontainers/runtime-spec v1.0.1/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
github.com/opencontainers/runtime-tools v0.0.0-20181011054405-1d69bd0f9c39/go.mod h1:r3f7wjNzSs2extwzU3Y+6pKfobzPh+kKFJ3ofN+3nfs=
-github.com/opencontainers/selinux v1.2.2 h1:Kx9J6eDG5/24A6DtUquGSpJQ+m2MUTahn4FtGEe8bFg=
-github.com/opencontainers/selinux v1.2.2/go.mod h1:+BLncwf63G4dgOzykXAxcmnFlUaOlkDdmw/CqsW6pjs=
-github.com/opencontainers/selinux v1.3.0 h1:xsI95WzPZu5exzA6JzkLSfdr/DilzOhCJOqGe5TgR0g=
-github.com/opencontainers/selinux v1.3.0/go.mod h1:+BLncwf63G4dgOzykXAxcmnFlUaOlkDdmw/CqsW6pjs=
-github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/opencontainers/selinux v1.4.0 h1:cpiX/2wWIju/6My60T6/z9CxNG7c8xTQyEmA9fChpUo=
+github.com/opencontainers/selinux v1.4.0/go.mod h1:yTcKuYAh6R95iDpefGLQaPaRwJFwyzAJufJyiTt7s0g=
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
-github.com/pkg/errors v0.9.0 h1:J8lpUdobwIeCI7OiSxHqEwJUKvJwicL5+3v1oe2Yb4k=
-github.com/pkg/errors v0.9.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
@@ -123,46 +72,31 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
github.com/pquerna/ffjson v0.0.0-20181028064349-e517b90714f7 h1:gGBSHPOU7g8YjTbhwn+lvFm2VDEhhA+PwDIlstkgSxE=
github.com/pquerna/ffjson v0.0.0-20181028064349-e517b90714f7/go.mod h1:YARuvh7BUWHNhzDq2OM5tzR2RiCcN2D7sapiKyCel/M=
github.com/prometheus/procfs v0.0.5/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=
-github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=
-github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
-github.com/seccomp/libseccomp-golang v0.9.1 h1:NJjM5DNFOs0s3kYE1WUOr6G8V97sdt46rlXTMfXGWBo=
-github.com/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvWlF4P2Ca7zGrPiEpWo=
-github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
-github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
-github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
+github.com/sirupsen/logrus v1.5.0 h1:1N5EYkVAPEywqZRJd7cwnRtCb6xJx7NH3T3WUTF980Q=
+github.com/sirupsen/logrus v1.5.0/go.mod h1:+F7Ogzej0PZc/94MaYx/nvG9jOFMD2osvC3s+Squfpo=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
-github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
-github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
-github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
-github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
+github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
+github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2 h1:b6uOv7YOFK0TYG7HtkIgExQo+2RdLuwRft63jn2HWj8=
github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
github.com/tchap/go-patricia v2.3.0+incompatible h1:GkY4dP3cEfEASBPPkWd+AmjYxhmDkqO9/zg7R0lSQRs=
github.com/tchap/go-patricia v2.3.0+incompatible/go.mod h1:bmLyhP68RS6kStMGxByiQ23RP/odRBOTVjwp2cDyi6I=
github.com/urfave/cli v0.0.0-20171014202726-7bc6a0acffa5/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
-github.com/urfave/cli v1.22.1 h1:+mkCCcOFKPnCmVYVcURKps1Xe+3zP90gSYGNfRkjoIY=
-github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
github.com/vbatts/tar-split v0.11.1 h1:0Odu65rhcZ3JZaPHxl7tCI3V/C/Q9Zf82UFravl02dE=
github.com/vbatts/tar-split v0.11.1/go.mod h1:LEuURwDEiWjRjwu46yU3KVGuUdVv/dcnpcEPSzR8z6g=
-github.com/vishvananda/netlink v1.0.0 h1:bqNY2lgheFIu1meHUFSH3d7vG93AFyqg3oGbJCOJgSM=
-github.com/vishvananda/netlink v1.0.0/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk=
-github.com/vishvananda/netns v0.0.0-20190625233234-7109fa855b0f h1:nBX3nTcmxEtHSERBJaIo1Qa26VwRaopnZmfDQUXsF4I=
-github.com/vishvananda/netns v0.0.0-20190625233234-7109fa855b0f/go.mod h1:ZjcWmFBXmLKZu9Nxj3WKYEafiSqer2rnvPr0en9UNpI=
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
github.com/xeipuuv/gojsonschema v0.0.0-20180618132009-1d523034197f/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs=
go.opencensus.io v0.22.0 h1:C9hSCOW830chIVkdja34wa6Ky+IzWllkUinR+BtRZd4=
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
-golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 h1:ObdrDkeb4kJdCP557AjRjq69pTHfNouLtWZG7j9rPN8=
-golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
@@ -171,7 +105,6 @@ golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73r
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
-golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190628185345-da137c7871d7 h1:rTIdg5QFRR7XCaK4LCjBiPbx8j4DQRpdYMnGn/bJUEU=
golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
@@ -183,23 +116,16 @@ golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190514135907-3a4b5fb9f71f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb h1:fgwFCsaw9buMuxNd6+DQfAuSFqbNiQZpcgJQAgJsK6k=
-golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3 h1:7TYNF4UdlohbFwpNH04CoPMp1cHUZgO1Ebq5r2hIjfo=
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20191025090151-53bf42e6b339 h1:zSqWKgm/o7HAnlAzBQ+aetp9fpuyytsXnKA8eiLHYQM=
-golang.org/x/sys v0.0.0-20191025090151-53bf42e6b339/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20191127021746-63cb32ae39b2 h1:/J2nHFg1MTqaRLFO7M+J78ASNsJoz3r0cvHBPQ77fsE=
-golang.org/x/sys v0.0.0-20191127021746-63cb32ae39b2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191115151921-52ab43148777 h1:wejkGHRTr38uaKRqECZlsCsJ1/TGxIyFbH32x5zUdu4=
+golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
-golang.org/x/tools v0.0.0-20180810170437-e96c4e24768d/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
@@ -210,11 +136,10 @@ google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoA
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-gotest.tools v0.0.0-20190624233834-05ebafbffc79 h1:C+K4iPg1rIvmCf4JjelkbWv2jeWevEwp05Lz8XfTYgE=
-gotest.tools v0.0.0-20190624233834-05ebafbffc79/go.mod h1:R//lfYlUuTOTfblYI3lGoAAAebUdzjvbmQsuB7Ykd90=
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
diff --git a/vendor/github.com/containers/storage/images.go b/vendor/github.com/containers/storage/images.go
index 6373ebb41..ef95598b8 100644
--- a/vendor/github.com/containers/storage/images.go
+++ b/vendor/github.com/containers/storage/images.go
@@ -214,17 +214,17 @@ func bigDataNameIsManifest(name string) bool {
// recomputeDigests takes a fixed digest and a name-to-digest map and builds a
// list of the unique values that would identify the image.
-func (image *Image) recomputeDigests() error {
- validDigests := make([]digest.Digest, 0, len(image.BigDataDigests)+1)
+func (i *Image) recomputeDigests() error {
+ validDigests := make([]digest.Digest, 0, len(i.BigDataDigests)+1)
digests := make(map[digest.Digest]struct{})
- if image.Digest != "" {
- if err := image.Digest.Validate(); err != nil {
- return errors.Wrapf(err, "error validating image digest %q", string(image.Digest))
+ if i.Digest != "" {
+ if err := i.Digest.Validate(); err != nil {
+ return errors.Wrapf(err, "error validating image digest %q", string(i.Digest))
}
- digests[image.Digest] = struct{}{}
- validDigests = append(validDigests, image.Digest)
+ digests[i.Digest] = struct{}{}
+ validDigests = append(validDigests, i.Digest)
}
- for name, digest := range image.BigDataDigests {
+ for name, digest := range i.BigDataDigests {
if !bigDataNameIsManifest(name) {
continue
}
@@ -237,10 +237,10 @@ func (image *Image) recomputeDigests() error {
validDigests = append(validDigests, digest)
}
}
- if image.Digest == "" && len(validDigests) > 0 {
- image.Digest = validDigests[0]
+ if i.Digest == "" && len(validDigests) > 0 {
+ i.Digest = validDigests[0]
}
- image.Digests = validDigests
+ i.Digests = validDigests
return nil
}
diff --git a/vendor/github.com/containers/storage/images_ffjson.go b/vendor/github.com/containers/storage/images_ffjson.go
index 0dde97c18..e1954ad04 100644
--- a/vendor/github.com/containers/storage/images_ffjson.go
+++ b/vendor/github.com/containers/storage/images_ffjson.go
@@ -1,5 +1,5 @@
// Code generated by ffjson <https://github.com/pquerna/ffjson>. DO NOT EDIT.
-// source: ./images.go
+// source: images.go
package storage
diff --git a/vendor/github.com/containers/storage/layers.go b/vendor/github.com/containers/storage/layers.go
index 0c5fcafde..dccfc169d 100644
--- a/vendor/github.com/containers/storage/layers.go
+++ b/vendor/github.com/containers/storage/layers.go
@@ -239,6 +239,10 @@ type LayerStore interface {
// ApplyDiff reads a tarstream which was created by a previous call to Diff and
// applies its changes to a specified layer.
ApplyDiff(to string, diff io.Reader) (int64, error)
+
+ // LoadLocked wraps Load in a locked state. This means it loads the store
+ // and cleans-up invalid layers if needed.
+ LoadLocked() error
}
type layerStore struct {
@@ -346,6 +350,7 @@ func (r *layerStore) Load() error {
r.byname = names
r.bycompressedsum = compressedsums
r.byuncompressedsum = uncompressedsums
+
// Load and merge information about which layers are mounted, and where.
if r.IsReadWrite() {
r.mountsLockfile.RLock()
@@ -353,22 +358,23 @@ func (r *layerStore) Load() error {
if err = r.loadMounts(); err != nil {
return err
}
- }
- // Last step: if we're writable, try to remove anything that a previous
- // user of this storage area marked for deletion but didn't manage to
- // actually delete.
- if r.IsReadWrite() && r.Locked() {
- for _, layer := range r.layers {
- if layer.Flags == nil {
- layer.Flags = make(map[string]interface{})
- }
- if cleanup, ok := layer.Flags[incompleteFlag]; ok {
- if b, ok := cleanup.(bool); ok && b {
- err = r.deleteInternal(layer.ID)
- if err != nil {
- break
+
+ // Last step: as we’re writable, try to remove anything that a previous
+ // user of this storage area marked for deletion but didn't manage to
+ // actually delete.
+ if r.Locked() {
+ for _, layer := range r.layers {
+ if layer.Flags == nil {
+ layer.Flags = make(map[string]interface{})
+ }
+ if cleanup, ok := layer.Flags[incompleteFlag]; ok {
+ if b, ok := cleanup.(bool); ok && b {
+ err = r.deleteInternal(layer.ID)
+ if err != nil {
+ break
+ }
+ shouldSave = true
}
- shouldSave = true
}
}
}
@@ -376,9 +382,16 @@ func (r *layerStore) Load() error {
return r.saveLayers()
}
}
+
return err
}
+func (r *layerStore) LoadLocked() error {
+ r.lockfile.Lock()
+ defer r.lockfile.Unlock()
+ return r.Load()
+}
+
func (r *layerStore) loadMounts() error {
mounts := make(map[string]*Layer)
mpath := r.mountspath()
@@ -487,8 +500,6 @@ func (s *store) newLayerStore(rundir string, layerdir string, driver drivers.Dri
if err != nil {
return nil, err
}
- lockfile.Lock()
- defer lockfile.Unlock()
mountsLockfile, err := GetLockfile(filepath.Join(rundir, "mountpoints.lock"))
if err != nil {
return nil, err
@@ -516,8 +527,6 @@ func newROLayerStore(rundir string, layerdir string, driver drivers.Driver) (ROL
if err != nil {
return nil, err
}
- lockfile.RLock()
- defer lockfile.Unlock()
rlstore := layerStore{
lockfile: lockfile,
mountsLockfile: nil,
diff --git a/vendor/github.com/containers/storage/pkg/archive/archive.go b/vendor/github.com/containers/storage/pkg/archive/archive.go
index 6e2618d1e..d9a2e473c 100644
--- a/vendor/github.com/containers/storage/pkg/archive/archive.go
+++ b/vendor/github.com/containers/storage/pkg/archive/archive.go
@@ -68,6 +68,12 @@ type (
}
)
+const (
+ tarExt = "tar"
+ solaris = "solaris"
+ windows = "windows"
+)
+
// Archiver allows the reuse of most utility functions of this package with a
// pluggable Untar function. To facilitate the passing of specific id mappings
// for untar, an archiver can be created with maps which will then be passed to
@@ -325,15 +331,15 @@ func ReplaceFileTarWrapper(inputTarStream io.ReadCloser, mods map[string]TarModi
func (compression *Compression) Extension() string {
switch *compression {
case Uncompressed:
- return "tar"
+ return tarExt
case Bzip2:
- return "tar.bz2"
+ return tarExt + ".bz2"
case Gzip:
- return "tar.gz"
+ return tarExt + ".gz"
case Xz:
- return "tar.xz"
+ return tarExt + ".xz"
case Zstd:
- return "tar.zst"
+ return tarExt + ".zst"
}
return ""
}
@@ -670,7 +676,7 @@ func createTarFile(path, extractDir string, hdr *tar.Header, reader io.Reader, L
}
// Lchown is not supported on Windows.
- if Lchown && runtime.GOOS != "windows" {
+ if Lchown && runtime.GOOS != windows {
if chownOpts == nil {
chownOpts = &idtools.IDPair{UID: hdr.Uid, GID: hdr.Gid}
}
diff --git a/vendor/github.com/containers/storage/pkg/archive/changes_unix.go b/vendor/github.com/containers/storage/pkg/archive/changes_unix.go
index 031ec341b..805fb960a 100644
--- a/vendor/github.com/containers/storage/pkg/archive/changes_unix.go
+++ b/vendor/github.com/containers/storage/pkg/archive/changes_unix.go
@@ -13,17 +13,17 @@ import (
func statDifferent(oldStat *system.StatT, oldInfo *FileInfo, newStat *system.StatT, newInfo *FileInfo) bool {
// Don't look at size for dirs, its not a good measure of change
- oldUid, oldGid := oldStat.UID(), oldStat.GID()
+ oldUID, oldGID := oldStat.UID(), oldStat.GID()
uid, gid := newStat.UID(), newStat.GID()
if cuid, cgid, err := newInfo.idMappings.ToContainer(idtools.IDPair{UID: int(uid), GID: int(gid)}); err == nil {
uid = uint32(cuid)
gid = uint32(cgid)
- if oldcuid, oldcgid, err := oldInfo.idMappings.ToContainer(idtools.IDPair{UID: int(oldUid), GID: int(oldGid)}); err == nil {
- oldUid = uint32(oldcuid)
- oldGid = uint32(oldcgid)
+ if oldcuid, oldcgid, err := oldInfo.idMappings.ToContainer(idtools.IDPair{UID: int(oldUID), GID: int(oldGID)}); err == nil {
+ oldUID = uint32(oldcuid)
+ oldGID = uint32(oldcgid)
}
}
- ownerChanged := uid != oldUid || gid != oldGid
+ ownerChanged := uid != oldUID || gid != oldGID
if oldStat.Mode() != newStat.Mode() ||
ownerChanged ||
oldStat.Rdev() != newStat.Rdev() ||
diff --git a/vendor/github.com/containers/storage/pkg/archive/diff.go b/vendor/github.com/containers/storage/pkg/archive/diff.go
index 3c2601dee..78e3d9102 100644
--- a/vendor/github.com/containers/storage/pkg/archive/diff.go
+++ b/vendor/github.com/containers/storage/pkg/archive/diff.go
@@ -68,7 +68,7 @@ func UnpackLayer(dest string, layer io.Reader, options *TarOptions) (size int64,
// specific or Linux-specific, this warning should be changed to an error
// to cater for the situation where someone does manage to upload a Linux
// image but have it tagged as Windows inadvertently.
- if runtime.GOOS == "windows" {
+ if runtime.GOOS == windows {
if strings.Contains(hdr.Name, ":") {
logrus.Warnf("Windows: Ignoring %s (is this a Linux image?)", hdr.Name)
continue
diff --git a/vendor/github.com/containers/storage/pkg/fileutils/fileutils.go b/vendor/github.com/containers/storage/pkg/fileutils/fileutils.go
index 388eaf9d5..a188c510d 100644
--- a/vendor/github.com/containers/storage/pkg/fileutils/fileutils.go
+++ b/vendor/github.com/containers/storage/pkg/fileutils/fileutils.go
@@ -1,7 +1,6 @@
package fileutils
import (
- "errors"
"fmt"
"io"
"os"
@@ -10,6 +9,7 @@ import (
"strings"
"text/scanner"
+ "github.com/pkg/errors"
"github.com/sirupsen/logrus"
)
@@ -226,8 +226,9 @@ func (p *Pattern) compile() error {
sl := string(os.PathSeparator)
escSL := sl
- if sl == `\` {
- escSL += `\`
+ const bs = `\`
+ if sl == bs {
+ escSL += bs
}
for scan.Peek() != scanner.EOF {
@@ -262,11 +263,11 @@ func (p *Pattern) compile() error {
} else if ch == '.' || ch == '$' {
// Escape some regexp special chars that have no meaning
// in golang's filepath.Match
- regStr += `\` + string(ch)
+ regStr += bs + string(ch)
} else if ch == '\\' {
// escape next char. Note that a trailing \ in the pattern
// will be left alone (but need to escape it)
- if sl == `\` {
+ if sl == bs {
// On windows map "\" to "\\", meaning an escaped backslash,
// and then just continue because filepath.Match on
// Windows doesn't allow escaping at all
@@ -274,9 +275,9 @@ func (p *Pattern) compile() error {
continue
}
if scan.Peek() != scanner.EOF {
- regStr += `\` + string(scan.Next())
+ regStr += bs + string(scan.Next())
} else {
- regStr += `\`
+ regStr += bs
}
} else {
regStr += string(ch)
@@ -357,6 +358,21 @@ func ReadSymlinkedDirectory(path string) (string, error) {
return realPath, nil
}
+// ReadSymlinkedPath returns the target directory of a symlink.
+// The target of the symbolic link can be a file and a directory.
+func ReadSymlinkedPath(path string) (realPath string, err error) {
+ if realPath, err = filepath.Abs(path); err != nil {
+ return "", errors.Wrapf(err, "unable to get absolute path for %q", path)
+ }
+ if realPath, err = filepath.EvalSymlinks(realPath); err != nil {
+ return "", errors.Wrapf(err, "failed to canonicalise path for %q", path)
+ }
+ if _, err := os.Stat(realPath); err != nil {
+ return "", errors.Wrapf(err, "failed to stat target %q of %q", realPath, path)
+ }
+ return realPath, nil
+}
+
// CreateIfNotExists creates a file or a directory only if it does not already exist.
func CreateIfNotExists(path string, isDir bool) error {
if _, err := os.Stat(path); err != nil {
diff --git a/vendor/github.com/containers/storage/pkg/homedir/homedir_linux.go b/vendor/github.com/containers/storage/pkg/homedir/homedir_linux.go
index c001fbecb..d28ba9d69 100644
--- a/vendor/github.com/containers/storage/pkg/homedir/homedir_linux.go
+++ b/vendor/github.com/containers/storage/pkg/homedir/homedir_linux.go
@@ -1,23 +1,96 @@
-// +build linux
-
package homedir
+// Copyright 2013-2018 Docker, Inc.
+// NOTE: this package has originally been copied from github.com/docker/docker.
+
import (
+ "errors"
"os"
-
- "github.com/containers/storage/pkg/idtools"
+ "path/filepath"
+ "strings"
)
-// GetStatic returns the home directory for the current user without calling
-// os/user.Current(). This is useful for static-linked binary on glibc-based
-// system, because a call to os/user.Current() in a static binary leads to
-// segfault due to a glibc issue that won't be fixed in a short term.
-// (#29344, golang/go#13470, https://sourceware.org/bugzilla/show_bug.cgi?id=19341)
-func GetStatic() (string, error) {
- uid := os.Getuid()
- usr, err := idtools.LookupUID(uid)
+// GetRuntimeDir returns XDG_RUNTIME_DIR.
+// XDG_RUNTIME_DIR is typically configured via pam_systemd.
+// GetRuntimeDir returns non-nil error if XDG_RUNTIME_DIR is not set.
+//
+// See also https://standards.freedesktop.org/basedir-spec/latest/ar01s03.html
+func GetRuntimeDir() (string, error) {
+ if xdgRuntimeDir := os.Getenv("XDG_RUNTIME_DIR"); xdgRuntimeDir != "" {
+ return xdgRuntimeDir, nil
+ }
+ return "", errors.New("could not get XDG_RUNTIME_DIR")
+}
+
+// StickRuntimeDirContents sets the sticky bit on files that are under
+// XDG_RUNTIME_DIR, so that the files won't be periodically removed by the system.
+//
+// StickyRuntimeDir returns slice of sticked files.
+// StickyRuntimeDir returns nil error if XDG_RUNTIME_DIR is not set.
+//
+// See also https://standards.freedesktop.org/basedir-spec/latest/ar01s03.html
+func StickRuntimeDirContents(files []string) ([]string, error) {
+ runtimeDir, err := GetRuntimeDir()
if err != nil {
- return "", err
+ // ignore error if runtimeDir is empty
+ return nil, nil
+ }
+ runtimeDir, err = filepath.Abs(runtimeDir)
+ if err != nil {
+ return nil, err
+ }
+ var sticked []string
+ for _, f := range files {
+ f, err = filepath.Abs(f)
+ if err != nil {
+ return sticked, err
+ }
+ if strings.HasPrefix(f, runtimeDir+"/") {
+ if err = stick(f); err != nil {
+ return sticked, err
+ }
+ sticked = append(sticked, f)
+ }
+ }
+ return sticked, nil
+}
+
+func stick(f string) error {
+ st, err := os.Stat(f)
+ if err != nil {
+ return err
+ }
+ m := st.Mode()
+ m |= os.ModeSticky
+ return os.Chmod(f, m)
+}
+
+// GetDataHome returns XDG_DATA_HOME.
+// GetDataHome returns $HOME/.local/share and nil error if XDG_DATA_HOME is not set.
+//
+// See also https://standards.freedesktop.org/basedir-spec/latest/ar01s03.html
+func GetDataHome() (string, error) {
+ if xdgDataHome := os.Getenv("XDG_DATA_HOME"); xdgDataHome != "" {
+ return xdgDataHome, nil
+ }
+ home := os.Getenv("HOME")
+ if home == "" {
+ return "", errors.New("could not get either XDG_DATA_HOME or HOME")
+ }
+ return filepath.Join(home, ".local", "share"), nil
+}
+
+// GetConfigHome returns XDG_CONFIG_HOME.
+// GetConfigHome returns $HOME/.config and nil error if XDG_CONFIG_HOME is not set.
+//
+// See also https://standards.freedesktop.org/basedir-spec/latest/ar01s03.html
+func GetConfigHome() (string, error) {
+ if xdgConfigHome := os.Getenv("XDG_CONFIG_HOME"); xdgConfigHome != "" {
+ return xdgConfigHome, nil
+ }
+ home := os.Getenv("HOME")
+ if home == "" {
+ return "", errors.New("could not get either XDG_CONFIG_HOME or HOME")
}
- return usr.Home, nil
+ return filepath.Join(home, ".config"), nil
}
diff --git a/vendor/github.com/containers/storage/pkg/homedir/homedir_others.go b/vendor/github.com/containers/storage/pkg/homedir/homedir_others.go
index 6b96b856f..f7bcfb878 100644
--- a/vendor/github.com/containers/storage/pkg/homedir/homedir_others.go
+++ b/vendor/github.com/containers/storage/pkg/homedir/homedir_others.go
@@ -2,12 +2,29 @@
package homedir
+// Copyright 2013-2018 Docker, Inc.
+// NOTE: this package has originally been copied from github.com/docker/docker.
+
import (
"errors"
)
-// GetStatic is not needed for non-linux systems.
-// (Precisely, it is needed only for glibc-based linux systems.)
-func GetStatic() (string, error) {
- return "", errors.New("homedir.GetStatic() is not supported on this system")
+// GetRuntimeDir is unsupported on non-linux system.
+func GetRuntimeDir() (string, error) {
+ return "", errors.New("homedir.GetRuntimeDir() is not supported on this system")
+}
+
+// StickRuntimeDirContents is unsupported on non-linux system.
+func StickRuntimeDirContents(files []string) ([]string, error) {
+ return nil, errors.New("homedir.StickRuntimeDirContents() is not supported on this system")
+}
+
+// GetDataHome is unsupported on non-linux system.
+func GetDataHome() (string, error) {
+ return "", errors.New("homedir.GetDataHome() is not supported on this system")
+}
+
+// GetConfigHome is unsupported on non-linux system.
+func GetConfigHome() (string, error) {
+ return "", errors.New("homedir.GetConfigHome() is not supported on this system")
}
diff --git a/vendor/github.com/containers/storage/pkg/homedir/homedir_unix.go b/vendor/github.com/containers/storage/pkg/homedir/homedir_unix.go
index f2a20ea8f..dcadb7e8d 100644
--- a/vendor/github.com/containers/storage/pkg/homedir/homedir_unix.go
+++ b/vendor/github.com/containers/storage/pkg/homedir/homedir_unix.go
@@ -2,10 +2,12 @@
package homedir
+// Copyright 2013-2018 Docker, Inc.
+// NOTE: this package has originally been copied from github.com/docker/docker.
+
import (
"os"
-
- "github.com/opencontainers/runc/libcontainer/user"
+ "os/user"
)
// Key returns the env var name for the user's home dir based on
@@ -17,11 +19,16 @@ func Key() string {
// Get returns the home directory of the current user with the help of
// environment variables depending on the target operating system.
// Returned path should be used with "path/filepath" to form new paths.
+//
+// If linking statically with cgo enabled against glibc, ensure the
+// osusergo build tag is used.
+//
+// If needing to do nss lookups, do not disable cgo or set osusergo.
func Get() string {
home := os.Getenv(Key())
if home == "" {
- if u, err := user.CurrentUser(); err == nil {
- return u.Home
+ if u, err := user.Current(); err == nil {
+ return u.HomeDir
}
}
return home
diff --git a/vendor/github.com/containers/storage/pkg/homedir/homedir_windows.go b/vendor/github.com/containers/storage/pkg/homedir/homedir_windows.go
index fafdb2bbf..4f2615ed3 100644
--- a/vendor/github.com/containers/storage/pkg/homedir/homedir_windows.go
+++ b/vendor/github.com/containers/storage/pkg/homedir/homedir_windows.go
@@ -1,5 +1,8 @@
package homedir
+// Copyright 2013-2018 Docker, Inc.
+// NOTE: this package has originally been copied from github.com/docker/docker.
+
import (
"os"
)
diff --git a/vendor/github.com/containers/storage/pkg/ioutils/fswriters.go b/vendor/github.com/containers/storage/pkg/ioutils/fswriters.go
index a56c46265..0df326b03 100644
--- a/vendor/github.com/containers/storage/pkg/ioutils/fswriters.go
+++ b/vendor/github.com/containers/storage/pkg/ioutils/fswriters.go
@@ -65,7 +65,7 @@ func (w *atomicFileWriter) Close() (retErr error) {
os.Remove(w.f.Name())
}
}()
- if err := w.f.Sync(); err != nil {
+ if err := fdatasync(w.f); err != nil {
w.f.Close()
return err
}
@@ -126,7 +126,7 @@ type syncFileCloser struct {
}
func (w syncFileCloser) Close() error {
- err := w.File.Sync()
+ err := fdatasync(w.File)
if err1 := w.File.Close(); err == nil {
err = err1
}
diff --git a/vendor/github.com/containers/storage/pkg/ioutils/fswriters_linux.go b/vendor/github.com/containers/storage/pkg/ioutils/fswriters_linux.go
new file mode 100644
index 000000000..0da78a063
--- /dev/null
+++ b/vendor/github.com/containers/storage/pkg/ioutils/fswriters_linux.go
@@ -0,0 +1,11 @@
+package ioutils
+
+import (
+ "os"
+
+ "golang.org/x/sys/unix"
+)
+
+func fdatasync(f *os.File) error {
+ return unix.Fdatasync(int(f.Fd()))
+}
diff --git a/vendor/github.com/containers/storage/pkg/ioutils/fswriters_unsupported.go b/vendor/github.com/containers/storage/pkg/ioutils/fswriters_unsupported.go
new file mode 100644
index 000000000..79a094035
--- /dev/null
+++ b/vendor/github.com/containers/storage/pkg/ioutils/fswriters_unsupported.go
@@ -0,0 +1,11 @@
+// +build !linux
+
+package ioutils
+
+import (
+ "os"
+)
+
+func fdatasync(f *os.File) error {
+ return f.Sync()
+}
diff --git a/vendor/github.com/containers/storage/pkg/lockfile/lockfile_unix.go b/vendor/github.com/containers/storage/pkg/lockfile/lockfile_unix.go
index 228c8cf24..6429d6254 100644
--- a/vendor/github.com/containers/storage/pkg/lockfile/lockfile_unix.go
+++ b/vendor/github.com/containers/storage/pkg/lockfile/lockfile_unix.go
@@ -77,14 +77,14 @@ func createLockerForPath(path string, ro bool) (Locker, error) {
// lock locks the lockfile via FCTNL(2) based on the specified type and
// command.
-func (l *lockfile) lock(l_type int16, recursive bool) {
+func (l *lockfile) lock(lType int16, recursive bool) {
lk := unix.Flock_t{
- Type: l_type,
+ Type: lType,
Whence: int16(os.SEEK_SET),
Start: 0,
Len: 0,
}
- switch l_type {
+ switch lType {
case unix.F_RDLCK:
l.rwMutex.RLock()
case unix.F_WRLCK:
@@ -96,7 +96,7 @@ func (l *lockfile) lock(l_type int16, recursive bool) {
l.rwMutex.Lock()
}
default:
- panic(fmt.Sprintf("attempted to acquire a file lock of unrecognized type %d", l_type))
+ panic(fmt.Sprintf("attempted to acquire a file lock of unrecognized type %d", lType))
}
l.stateMutex.Lock()
defer l.stateMutex.Unlock()
@@ -116,7 +116,7 @@ func (l *lockfile) lock(l_type int16, recursive bool) {
time.Sleep(10 * time.Millisecond)
}
}
- l.locktype = l_type
+ l.locktype = lType
l.locked = true
l.recursive = recursive
l.counter++
@@ -206,10 +206,6 @@ func (l *lockfile) Touch() error {
if n != len(id) {
return unix.ENOSPC
}
- err = unix.Fsync(int(l.fd))
- if err != nil {
- return err
- }
return nil
}
diff --git a/vendor/github.com/containers/storage/pkg/mount/flags_freebsd.go b/vendor/github.com/containers/storage/pkg/mount/flags_freebsd.go
deleted file mode 100644
index 5f76f331b..000000000
--- a/vendor/github.com/containers/storage/pkg/mount/flags_freebsd.go
+++ /dev/null
@@ -1,49 +0,0 @@
-// +build freebsd,cgo
-
-package mount
-
-/*
-#include <sys/mount.h>
-*/
-import "C"
-
-const (
- // RDONLY will mount the filesystem as read-only.
- RDONLY = C.MNT_RDONLY
-
- // NOSUID will not allow set-user-identifier or set-group-identifier bits to
- // take effect.
- NOSUID = C.MNT_NOSUID
-
- // NOEXEC will not allow execution of any binaries on the mounted file system.
- NOEXEC = C.MNT_NOEXEC
-
- // SYNCHRONOUS will allow any I/O to the file system to be done synchronously.
- SYNCHRONOUS = C.MNT_SYNCHRONOUS
-
- // NOATIME will not update the file access time when reading from a file.
- NOATIME = C.MNT_NOATIME
-)
-
-// These flags are unsupported.
-const (
- BIND = 0
- DIRSYNC = 0
- MANDLOCK = 0
- NODEV = 0
- NODIRATIME = 0
- UNBINDABLE = 0
- RUNBINDABLE = 0
- PRIVATE = 0
- RPRIVATE = 0
- SHARED = 0
- RSHARED = 0
- SLAVE = 0
- RSLAVE = 0
- RBIND = 0
- RELATIVE = 0
- RELATIME = 0
- REMOUNT = 0
- STRICTATIME = 0
- mntDetach = 0
-)
diff --git a/vendor/github.com/containers/storage/pkg/mount/flags_unsupported.go b/vendor/github.com/containers/storage/pkg/mount/flags_unsupported.go
index 9ed741e3f..9afd26d4c 100644
--- a/vendor/github.com/containers/storage/pkg/mount/flags_unsupported.go
+++ b/vendor/github.com/containers/storage/pkg/mount/flags_unsupported.go
@@ -1,4 +1,4 @@
-// +build !linux,!freebsd freebsd,!cgo solaris,!cgo
+// +build !linux
package mount
diff --git a/vendor/github.com/containers/storage/pkg/mount/mount.go b/vendor/github.com/containers/storage/pkg/mount/mount.go
index 7197448da..4b888dceb 100644
--- a/vendor/github.com/containers/storage/pkg/mount/mount.go
+++ b/vendor/github.com/containers/storage/pkg/mount/mount.go
@@ -2,12 +2,47 @@ package mount
import (
"sort"
+ "strconv"
"strings"
- "time"
"github.com/containers/storage/pkg/fileutils"
)
+// mountError holds an error from a mount or unmount operation
+type mountError struct {
+ op string
+ source, target string
+ flags uintptr
+ data string
+ err error
+}
+
+// Error returns a string representation of mountError
+func (e *mountError) Error() string {
+ out := e.op + " "
+
+ if e.source != "" {
+ out += e.source + ":" + e.target
+ } else {
+ out += e.target
+ }
+
+ if e.flags != uintptr(0) {
+ out += ", flags: 0x" + strconv.FormatUint(uint64(e.flags), 16)
+ }
+ if e.data != "" {
+ out += ", data: " + e.data
+ }
+
+ out += ": " + e.err.Error()
+ return out
+}
+
+// Cause returns the underlying cause of the error
+func (e *mountError) Cause() error {
+ return e.err
+}
+
// GetMounts retrieves a list of mounts for the current running process.
func GetMounts() ([]*Info, error) {
return parseMountTable()
@@ -21,10 +56,11 @@ func Mounted(mountpoint string) (bool, error) {
return false, err
}
- mountpoint, err = fileutils.ReadSymlinkedDirectory(mountpoint)
+ mountpoint, err = fileutils.ReadSymlinkedPath(mountpoint)
if err != nil {
return false, err
}
+
// Search the table for the mountpoint
for _, e := range entries {
if e.Mountpoint == mountpoint {
@@ -39,13 +75,13 @@ func Mounted(mountpoint string) (bool, error) {
// specified like the mount or fstab unix commands: "opt1=val1,opt2=val2". See
// flags.go for supported option flags.
func Mount(device, target, mType, options string) error {
- flag, _ := ParseOptions(options)
+ flag, data := ParseOptions(options)
if flag&REMOUNT != REMOUNT {
if mounted, err := Mounted(target); err != nil || mounted {
return err
}
}
- return ForceMount(device, target, mType, options)
+ return mount(device, target, mType, uintptr(flag), data)
}
// ForceMount will mount a filesystem according to the specified configuration,
@@ -60,14 +96,11 @@ func ForceMount(device, target, mType, options string) error {
// Unmount lazily unmounts a filesystem on supported platforms, otherwise
// does a normal unmount.
func Unmount(target string) error {
- if mounted, err := Mounted(target); err != nil || !mounted {
- return err
- }
- return ForceUnmount(target)
+ return unmount(target, mntDetach)
}
// RecursiveUnmount unmounts the target and all mounts underneath, starting with
-// the deepsest mount first.
+// the deepest mount first.
func RecursiveUnmount(target string) error {
mounts, err := GetMounts()
if err != nil {
@@ -75,16 +108,16 @@ func RecursiveUnmount(target string) error {
}
// Make the deepest mount be first
- sort.Sort(sort.Reverse(byMountpoint(mounts)))
+ sort.Slice(mounts, func(i, j int) bool {
+ return len(mounts[i].Mountpoint) > len(mounts[j].Mountpoint)
+ })
for i, m := range mounts {
if !strings.HasPrefix(m.Mountpoint, target) {
continue
}
if err := Unmount(m.Mountpoint); err != nil && i == len(mounts)-1 {
- if mounted, err := Mounted(m.Mountpoint); err != nil || mounted {
- return err
- }
+ return err
// Ignore errors for submounts and continue trying to unmount others
// The final unmount should fail if there ane any submounts remaining
}
@@ -92,15 +125,10 @@ func RecursiveUnmount(target string) error {
return nil
}
-// ForceUnmount will force an unmount of the target filesystem, regardless if
-// it is mounted or not.
-func ForceUnmount(target string) (err error) {
- // Simple retry logic for unmount
- for i := 0; i < 10; i++ {
- if err = unmount(target, 0); err == nil {
- return nil
- }
- time.Sleep(100 * time.Millisecond)
- }
- return nil
+// ForceUnmount lazily unmounts a filesystem on supported platforms,
+// otherwise does a normal unmount.
+//
+// Deprecated: please use Unmount instead, it is identical.
+func ForceUnmount(target string) error {
+ return unmount(target, mntDetach)
}
diff --git a/vendor/github.com/containers/storage/pkg/mount/mounter_freebsd.go b/vendor/github.com/containers/storage/pkg/mount/mounter_freebsd.go
index 814896cc9..b31cf99d0 100644
--- a/vendor/github.com/containers/storage/pkg/mount/mounter_freebsd.go
+++ b/vendor/github.com/containers/storage/pkg/mount/mounter_freebsd.go
@@ -14,8 +14,6 @@ import (
"fmt"
"strings"
"unsafe"
-
- "golang.org/x/sys/unix"
)
func allocateIOVecs(options []string) []C.struct_iovec {
@@ -54,7 +52,3 @@ func mount(device, target, mType string, flag uintptr, data string) error {
}
return nil
}
-
-func unmount(target string, flag int) error {
- return unix.Unmount(target, flag)
-}
diff --git a/vendor/github.com/containers/storage/pkg/mount/mounter_linux.go b/vendor/github.com/containers/storage/pkg/mount/mounter_linux.go
index 39c36d472..594cd0881 100644
--- a/vendor/github.com/containers/storage/pkg/mount/mounter_linux.go
+++ b/vendor/github.com/containers/storage/pkg/mount/mounter_linux.go
@@ -13,6 +13,8 @@ const (
// broflags is the combination of bind and read only
broflags = unix.MS_BIND | unix.MS_RDONLY
+
+ none = "none"
)
// isremount returns true if either device name or flags identify a remount request, false otherwise.
@@ -20,7 +22,7 @@ func isremount(device string, flags uintptr) bool {
switch {
// We treat device "" and "none" as a remount request to provide compatibility with
// requests that don't explicitly set MS_REMOUNT such as those manipulating bind mounts.
- case flags&unix.MS_REMOUNT != 0, device == "", device == "none":
+ case flags&unix.MS_REMOUNT != 0, device == "", device == none:
return true
default:
return false
@@ -33,25 +35,40 @@ func mount(device, target, mType string, flags uintptr, data string) error {
// Initial call applying all non-propagation flags for mount
// or remount with changed data
if err := unix.Mount(device, target, mType, oflags, data); err != nil {
- return err
+ return &mountError{
+ op: "mount",
+ source: device,
+ target: target,
+ flags: oflags,
+ data: data,
+ err: err,
+ }
}
}
if flags&ptypes != 0 {
// Change the propagation type.
if err := unix.Mount("", target, "", flags&pflags, ""); err != nil {
- return err
+ return &mountError{
+ op: "remount",
+ target: target,
+ flags: flags & pflags,
+ err: err,
+ }
}
}
if oflags&broflags == broflags {
// Remount the bind to apply read only.
- return unix.Mount("", target, "", oflags|unix.MS_REMOUNT, "")
+ if err := unix.Mount("", target, "", oflags|unix.MS_REMOUNT, ""); err != nil {
+ return &mountError{
+ op: "remount-ro",
+ target: target,
+ flags: oflags | unix.MS_REMOUNT,
+ err: err,
+ }
+ }
}
return nil
}
-
-func unmount(target string, flag int) error {
- return unix.Unmount(target, flag)
-}
diff --git a/vendor/github.com/containers/storage/pkg/mount/mounter_solaris.go b/vendor/github.com/containers/storage/pkg/mount/mounter_solaris.go
deleted file mode 100644
index 48b86771e..000000000
--- a/vendor/github.com/containers/storage/pkg/mount/mounter_solaris.go
+++ /dev/null
@@ -1,34 +0,0 @@
-// +build solaris,cgo
-
-package mount
-
-import (
- "unsafe"
-
- "golang.org/x/sys/unix"
-)
-
-// #include <stdlib.h>
-// #include <stdio.h>
-// #include <sys/mount.h>
-// int Mount(const char *spec, const char *dir, int mflag,
-// char *fstype, char *dataptr, int datalen, char *optptr, int optlen) {
-// return mount(spec, dir, mflag, fstype, dataptr, datalen, optptr, optlen);
-// }
-import "C"
-
-func mount(device, target, mType string, flag uintptr, data string) error {
- spec := C.CString(device)
- dir := C.CString(target)
- fstype := C.CString(mType)
- _, err := C.Mount(spec, dir, C.int(flag), fstype, nil, 0, nil, 0)
- C.free(unsafe.Pointer(spec))
- C.free(unsafe.Pointer(dir))
- C.free(unsafe.Pointer(fstype))
- return err
-}
-
-func unmount(target string, flag int) error {
- err := unix.Unmount(target, flag)
- return err
-}
diff --git a/vendor/github.com/containers/storage/pkg/mount/mounter_unsupported.go b/vendor/github.com/containers/storage/pkg/mount/mounter_unsupported.go
index a2a3bb457..42d1d422c 100644
--- a/vendor/github.com/containers/storage/pkg/mount/mounter_unsupported.go
+++ b/vendor/github.com/containers/storage/pkg/mount/mounter_unsupported.go
@@ -1,11 +1,7 @@
-// +build !linux,!freebsd,!solaris freebsd,!cgo solaris,!cgo
+// +build !linux
package mount
func mount(device, target, mType string, flag uintptr, data string) error {
panic("Not implemented")
}
-
-func unmount(target string, flag int) error {
- panic("Not implemented")
-}
diff --git a/vendor/github.com/containers/storage/pkg/mount/mountinfo.go b/vendor/github.com/containers/storage/pkg/mount/mountinfo.go
index ff4cc1d86..e3fc3535e 100644
--- a/vendor/github.com/containers/storage/pkg/mount/mountinfo.go
+++ b/vendor/github.com/containers/storage/pkg/mount/mountinfo.go
@@ -38,17 +38,3 @@ type Info struct {
// VfsOpts represents per super block options.
VfsOpts string
}
-
-type byMountpoint []*Info
-
-func (by byMountpoint) Len() int {
- return len(by)
-}
-
-func (by byMountpoint) Less(i, j int) bool {
- return by[i].Mountpoint < by[j].Mountpoint
-}
-
-func (by byMountpoint) Swap(i, j int) {
- by[i], by[j] = by[j], by[i]
-}
diff --git a/vendor/github.com/containers/storage/pkg/mount/mountinfo_linux.go b/vendor/github.com/containers/storage/pkg/mount/mountinfo_linux.go
index be69fee1d..19556d06b 100644
--- a/vendor/github.com/containers/storage/pkg/mount/mountinfo_linux.go
+++ b/vendor/github.com/containers/storage/pkg/mount/mountinfo_linux.go
@@ -1,5 +1,3 @@
-// +build linux
-
package mount
import (
@@ -7,25 +5,10 @@ import (
"fmt"
"io"
"os"
+ "strconv"
"strings"
-)
-const (
- /* 36 35 98:0 /mnt1 /mnt2 rw,noatime master:1 - ext3 /dev/root rw,errors=continue
- (1)(2)(3) (4) (5) (6) (7) (8) (9) (10) (11)
-
- (1) mount ID: unique identifier of the mount (may be reused after umount)
- (2) parent ID: ID of parent (or of self for the top of the mount tree)
- (3) major:minor: value of st_dev for files on filesystem
- (4) root: root of the mount within the filesystem
- (5) mount point: mount point relative to the process's root
- (6) mount options: per mount options
- (7) optional fields: zero or more fields of the form "tag[:value]"
- (8) separator: marks the end of the optional fields
- (9) filesystem type: name of filesystem of the form "type[.subtype]"
- (10) mount source: filesystem specific information or "none"
- (11) super options: per super block options*/
- mountinfoFormat = "%d %d %d:%d %s %s %s %s"
+ "github.com/pkg/errors"
)
// Parse /proc/self/mountinfo because comparing Dev and ino does not work from
@@ -41,43 +24,85 @@ func parseMountTable() ([]*Info, error) {
}
func parseInfoFile(r io.Reader) ([]*Info, error) {
- var (
- s = bufio.NewScanner(r)
- out = []*Info{}
- )
+ s := bufio.NewScanner(r)
+ out := []*Info{}
for s.Scan() {
- if err := s.Err(); err != nil {
- return nil, err
+ /*
+ 36 35 98:0 /mnt1 /mnt2 rw,noatime master:1 - ext3 /dev/root rw,errors=continue
+ (0)(1)(2) (3) (4) (5) (6) (7) (8) (9) (10)
+
+ (0) mount ID: unique identifier of the mount (may be reused after umount)
+ (1) parent ID: ID of parent (or of self for the top of the mount tree)
+ (2) major:minor: value of st_dev for files on filesystem
+ (3) root: root of the mount within the filesystem
+ (4) mount point: mount point relative to the process's root
+ (5) mount options: per mount options
+ (6) optional fields: zero or more fields of the form "tag[:value]"
+ (7) separator: marks the end of the optional fields
+ (8) filesystem type: name of filesystem of the form "type[.subtype]"
+ (9) mount source: filesystem specific information or "none"
+ (10) super options: per super block options
+ */
+ text := s.Text()
+ fields := strings.Split(text, " ")
+ numFields := len(fields)
+ if numFields < 10 {
+ // should be at least 10 fields
+ return nil, errors.Errorf("Parsing %q failed: not enough fields (%d)", text, numFields)
}
- var (
- p = &Info{}
- text = s.Text()
- optionalFields string
- )
+ p := &Info{}
+ // ignore any number parsing errors, there should not be any
+ p.ID, _ = strconv.Atoi(fields[0])
+ p.Parent, _ = strconv.Atoi(fields[1])
+ mm := strings.Split(fields[2], ":")
+ if len(mm) != 2 {
+ return nil, fmt.Errorf("Parsing %q failed: unexpected minor:major pair %s", text, mm)
+ }
+ p.Major, _ = strconv.Atoi(mm[0])
+ p.Minor, _ = strconv.Atoi(mm[1])
+ p.Root = fields[3]
+ p.Mountpoint = fields[4]
+ p.Opts = fields[5]
- if _, err := fmt.Sscanf(text, mountinfoFormat,
- &p.ID, &p.Parent, &p.Major, &p.Minor,
- &p.Root, &p.Mountpoint, &p.Opts, &optionalFields); err != nil {
- return nil, fmt.Errorf("Scanning '%s' failed: %s", text, err)
+ // one or more optional fields, when a separator (-)
+ i := 6
+ for ; i < numFields && fields[i] != "-"; i++ {
+ switch i {
+ case 6:
+ p.Optional = string(fields[6])
+ default:
+ /* NOTE there might be more optional fields before the separator,
+ such as fields[7] or fields[8], although as of Linux kernel 5.5
+ the only known ones are mount propagation flags in fields[6].
+ The correct behavior is to ignore any unknown optional fields.
+ */
+ }
}
- // Safe as mountinfo encodes mountpoints with spaces as \040.
- index := strings.Index(text, " - ")
- postSeparatorFields := strings.Fields(text[index+3:])
- if len(postSeparatorFields) < 3 {
- return nil, fmt.Errorf("Error found less than 3 fields post '-' in %q", text)
+ if i == numFields {
+ return nil, fmt.Errorf("Parsing %q failed: missing - separator", text)
}
- if optionalFields != "-" {
- p.Optional = optionalFields
+ // There should be 3 fields after the separator...
+ if i+4 > numFields {
+ return nil, fmt.Errorf("Parsing %q failed: not enough fields after a - separator", text)
}
+ // ... but in Linux <= 3.9 mounting a cifs with spaces in a share name
+ // (like "//serv/My Documents") _may_ end up having a space in the last field
+ // of mountinfo (like "unc=//serv/My Documents"). Since kernel 3.10-rc1, cifs
+ // option unc= is ignored, so a space should not appear. In here we ignore
+ // those "extra" fields caused by extra spaces.
+ p.Fstype = fields[i+1]
+ p.Source = fields[i+2]
+ p.VfsOpts = fields[i+3]
- p.Fstype = postSeparatorFields[0]
- p.Source = postSeparatorFields[1]
- p.VfsOpts = strings.Join(postSeparatorFields[2:], " ")
out = append(out, p)
}
+ if err := s.Err(); err != nil {
+ return nil, err
+ }
+
return out, nil
}
diff --git a/vendor/github.com/containers/storage/pkg/mount/mountinfo_solaris.go b/vendor/github.com/containers/storage/pkg/mount/mountinfo_solaris.go
deleted file mode 100644
index ad9ab57f8..000000000
--- a/vendor/github.com/containers/storage/pkg/mount/mountinfo_solaris.go
+++ /dev/null
@@ -1,37 +0,0 @@
-// +build solaris,cgo
-
-package mount
-
-/*
-#include <stdio.h>
-#include <sys/mnttab.h>
-*/
-import "C"
-
-import (
- "fmt"
-)
-
-func parseMountTable() ([]*Info, error) {
- mnttab := C.fopen(C.CString(C.MNTTAB), C.CString("r"))
- if mnttab == nil {
- return nil, fmt.Errorf("Failed to open %s", C.MNTTAB)
- }
-
- var out []*Info
- var mp C.struct_mnttab
-
- ret := C.getmntent(mnttab, &mp)
- for ret == 0 {
- var mountinfo Info
- mountinfo.Mountpoint = C.GoString(mp.mnt_mountp)
- mountinfo.Source = C.GoString(mp.mnt_special)
- mountinfo.Fstype = C.GoString(mp.mnt_fstype)
- mountinfo.Opts = C.GoString(mp.mnt_mntopts)
- out = append(out, &mountinfo)
- ret = C.getmntent(mnttab, &mp)
- }
-
- C.fclose(mnttab)
- return out, nil
-}
diff --git a/vendor/github.com/containers/storage/pkg/mount/mountinfo_unsupported.go b/vendor/github.com/containers/storage/pkg/mount/mountinfo_unsupported.go
index 7fbcf1921..6cde1ed77 100644
--- a/vendor/github.com/containers/storage/pkg/mount/mountinfo_unsupported.go
+++ b/vendor/github.com/containers/storage/pkg/mount/mountinfo_unsupported.go
@@ -1,4 +1,4 @@
-// +build !windows,!linux,!freebsd,!solaris freebsd,!cgo solaris,!cgo
+// +build !linux
package mount
diff --git a/vendor/github.com/containers/storage/pkg/mount/mountinfo_windows.go b/vendor/github.com/containers/storage/pkg/mount/mountinfo_windows.go
deleted file mode 100644
index dab8a37ed..000000000
--- a/vendor/github.com/containers/storage/pkg/mount/mountinfo_windows.go
+++ /dev/null
@@ -1,6 +0,0 @@
-package mount
-
-func parseMountTable() ([]*Info, error) {
- // Do NOT return an error!
- return nil, nil
-}
diff --git a/vendor/github.com/containers/storage/pkg/mount/sharedsubtree_linux.go b/vendor/github.com/containers/storage/pkg/mount/sharedsubtree_linux.go
index 8ceec84bc..80922ad5c 100644
--- a/vendor/github.com/containers/storage/pkg/mount/sharedsubtree_linux.go
+++ b/vendor/github.com/containers/storage/pkg/mount/sharedsubtree_linux.go
@@ -1,69 +1,64 @@
-// +build linux
-
package mount
// MakeShared ensures a mounted filesystem has the SHARED mount option enabled.
// See the supported options in flags.go for further reference.
func MakeShared(mountPoint string) error {
- return ensureMountedAs(mountPoint, "shared")
+ return ensureMountedAs(mountPoint, SHARED)
}
// MakeRShared ensures a mounted filesystem has the RSHARED mount option enabled.
// See the supported options in flags.go for further reference.
func MakeRShared(mountPoint string) error {
- return ensureMountedAs(mountPoint, "rshared")
+ return ensureMountedAs(mountPoint, RSHARED)
}
// MakePrivate ensures a mounted filesystem has the PRIVATE mount option enabled.
// See the supported options in flags.go for further reference.
func MakePrivate(mountPoint string) error {
- return ensureMountedAs(mountPoint, "private")
+ return ensureMountedAs(mountPoint, PRIVATE)
}
// MakeRPrivate ensures a mounted filesystem has the RPRIVATE mount option
// enabled. See the supported options in flags.go for further reference.
func MakeRPrivate(mountPoint string) error {
- return ensureMountedAs(mountPoint, "rprivate")
+ return ensureMountedAs(mountPoint, RPRIVATE)
}
// MakeSlave ensures a mounted filesystem has the SLAVE mount option enabled.
// See the supported options in flags.go for further reference.
func MakeSlave(mountPoint string) error {
- return ensureMountedAs(mountPoint, "slave")
+ return ensureMountedAs(mountPoint, SLAVE)
}
// MakeRSlave ensures a mounted filesystem has the RSLAVE mount option enabled.
// See the supported options in flags.go for further reference.
func MakeRSlave(mountPoint string) error {
- return ensureMountedAs(mountPoint, "rslave")
+ return ensureMountedAs(mountPoint, RSLAVE)
}
// MakeUnbindable ensures a mounted filesystem has the UNBINDABLE mount option
// enabled. See the supported options in flags.go for further reference.
func MakeUnbindable(mountPoint string) error {
- return ensureMountedAs(mountPoint, "unbindable")
+ return ensureMountedAs(mountPoint, UNBINDABLE)
}
// MakeRUnbindable ensures a mounted filesystem has the RUNBINDABLE mount
// option enabled. See the supported options in flags.go for further reference.
func MakeRUnbindable(mountPoint string) error {
- return ensureMountedAs(mountPoint, "runbindable")
+ return ensureMountedAs(mountPoint, RUNBINDABLE)
}
-func ensureMountedAs(mountPoint, options string) error {
- mounted, err := Mounted(mountPoint)
+func ensureMountedAs(mnt string, flags int) error {
+ mounted, err := Mounted(mnt)
if err != nil {
return err
}
if !mounted {
- if err := Mount(mountPoint, mountPoint, "none", "bind,rw"); err != nil {
+ if err := mount(mnt, mnt, "none", uintptr(BIND), ""); err != nil {
return err
}
}
- if _, err = Mounted(mountPoint); err != nil {
- return err
- }
- return ForceMount("", mountPoint, "none", options)
+ return mount("", mnt, "none", uintptr(flags), "")
}
diff --git a/vendor/github.com/containers/storage/pkg/mount/sharedsubtree_solaris.go b/vendor/github.com/containers/storage/pkg/mount/sharedsubtree_solaris.go
deleted file mode 100644
index 09f6b03cb..000000000
--- a/vendor/github.com/containers/storage/pkg/mount/sharedsubtree_solaris.go
+++ /dev/null
@@ -1,58 +0,0 @@
-// +build solaris
-
-package mount
-
-// MakeShared ensures a mounted filesystem has the SHARED mount option enabled.
-// See the supported options in flags.go for further reference.
-func MakeShared(mountPoint string) error {
- return ensureMountedAs(mountPoint, "shared")
-}
-
-// MakeRShared ensures a mounted filesystem has the RSHARED mount option enabled.
-// See the supported options in flags.go for further reference.
-func MakeRShared(mountPoint string) error {
- return ensureMountedAs(mountPoint, "rshared")
-}
-
-// MakePrivate ensures a mounted filesystem has the PRIVATE mount option enabled.
-// See the supported options in flags.go for further reference.
-func MakePrivate(mountPoint string) error {
- return ensureMountedAs(mountPoint, "private")
-}
-
-// MakeRPrivate ensures a mounted filesystem has the RPRIVATE mount option
-// enabled. See the supported options in flags.go for further reference.
-func MakeRPrivate(mountPoint string) error {
- return ensureMountedAs(mountPoint, "rprivate")
-}
-
-// MakeSlave ensures a mounted filesystem has the SLAVE mount option enabled.
-// See the supported options in flags.go for further reference.
-func MakeSlave(mountPoint string) error {
- return ensureMountedAs(mountPoint, "slave")
-}
-
-// MakeRSlave ensures a mounted filesystem has the RSLAVE mount option enabled.
-// See the supported options in flags.go for further reference.
-func MakeRSlave(mountPoint string) error {
- return ensureMountedAs(mountPoint, "rslave")
-}
-
-// MakeUnbindable ensures a mounted filesystem has the UNBINDABLE mount option
-// enabled. See the supported options in flags.go for further reference.
-func MakeUnbindable(mountPoint string) error {
- return ensureMountedAs(mountPoint, "unbindable")
-}
-
-// MakeRUnbindable ensures a mounted filesystem has the RUNBINDABLE mount
-// option enabled. See the supported options in flags.go for further reference.
-func MakeRUnbindable(mountPoint string) error {
- return ensureMountedAs(mountPoint, "runbindable")
-}
-
-func ensureMountedAs(mountPoint, options string) error {
- // TODO: Solaris does not support bind mounts.
- // Evaluate lofs and also look at the relevant
- // mount flags to be supported.
- return nil
-}
diff --git a/vendor/github.com/containers/storage/pkg/mount/unmount_unix.go b/vendor/github.com/containers/storage/pkg/mount/unmount_unix.go
new file mode 100644
index 000000000..1d1afeee2
--- /dev/null
+++ b/vendor/github.com/containers/storage/pkg/mount/unmount_unix.go
@@ -0,0 +1,22 @@
+// +build !windows
+
+package mount
+
+import "golang.org/x/sys/unix"
+
+func unmount(target string, flags int) error {
+ err := unix.Unmount(target, flags)
+ if err == nil || err == unix.EINVAL {
+ // Ignore "not mounted" error here. Note the same error
+ // can be returned if flags are invalid, so this code
+ // assumes that the flags value is always correct.
+ return nil
+ }
+
+ return &mountError{
+ op: "umount",
+ target: target,
+ flags: uintptr(flags),
+ err: err,
+ }
+}
diff --git a/vendor/github.com/containers/storage/pkg/mount/unmount_unsupported.go b/vendor/github.com/containers/storage/pkg/mount/unmount_unsupported.go
new file mode 100644
index 000000000..eebc4ab84
--- /dev/null
+++ b/vendor/github.com/containers/storage/pkg/mount/unmount_unsupported.go
@@ -0,0 +1,7 @@
+// +build windows
+
+package mount
+
+func unmount(target string, flag int) error {
+ panic("Not implemented")
+}
diff --git a/vendor/github.com/containers/storage/pkg/reexec/command_linux.go b/vendor/github.com/containers/storage/pkg/reexec/command_linux.go
index 1ae728a61..372bee732 100644
--- a/vendor/github.com/containers/storage/pkg/reexec/command_linux.go
+++ b/vendor/github.com/containers/storage/pkg/reexec/command_linux.go
@@ -5,9 +5,6 @@ package reexec
import (
"context"
"os/exec"
- "syscall"
-
- "golang.org/x/sys/unix"
)
// Self returns the path to the current process's binary.
@@ -16,28 +13,20 @@ func Self() string {
return "/proc/self/exe"
}
-// Command returns *exec.Cmd which has Path as current binary. Also it setting
-// SysProcAttr.Pdeathsig to SIGTERM.
+// Command returns *exec.Cmd which has Path as current binary.
// This will use the in-memory version (/proc/self/exe) of the current binary,
// it is thus safe to delete or replace the on-disk binary (os.Args[0]).
func Command(args ...string) *exec.Cmd {
cmd := exec.Command(Self())
cmd.Args = args
- cmd.SysProcAttr = &syscall.SysProcAttr{
- Pdeathsig: unix.SIGTERM,
- }
return cmd
}
-// CommandContext returns *exec.Cmd which has Path as current binary, and also
-// sets SysProcAttr.Pdeathsig to SIGTERM.
+// CommandContext returns *exec.Cmd which has Path as current binary.
// This will use the in-memory version (/proc/self/exe) of the current binary,
// it is thus safe to delete or replace the on-disk binary (os.Args[0]).
func CommandContext(ctx context.Context, args ...string) *exec.Cmd {
cmd := exec.CommandContext(ctx, Self())
cmd.Args = args
- cmd.SysProcAttr = &syscall.SysProcAttr{
- Pdeathsig: unix.SIGTERM,
- }
return cmd
}
diff --git a/vendor/github.com/containers/storage/pkg/system/lstat_unix.go b/vendor/github.com/containers/storage/pkg/system/lstat_unix.go
index bd23c4d50..e9d301f09 100644
--- a/vendor/github.com/containers/storage/pkg/system/lstat_unix.go
+++ b/vendor/github.com/containers/storage/pkg/system/lstat_unix.go
@@ -3,6 +3,7 @@
package system
import (
+ "os"
"syscall"
)
@@ -13,7 +14,7 @@ import (
func Lstat(path string) (*StatT, error) {
s := &syscall.Stat_t{}
if err := syscall.Lstat(path, s); err != nil {
- return nil, err
+ return nil, &os.PathError{"Lstat", path, err}
}
return fromStatT(s)
}
diff --git a/vendor/github.com/containers/storage/pkg/system/process_unix.go b/vendor/github.com/containers/storage/pkg/system/process_unix.go
index 26c8b42c1..a9a0dd751 100644
--- a/vendor/github.com/containers/storage/pkg/system/process_unix.go
+++ b/vendor/github.com/containers/storage/pkg/system/process_unix.go
@@ -20,5 +20,5 @@ func IsProcessAlive(pid int) bool {
// KillProcess force-stops a process.
func KillProcess(pid int) {
- unix.Kill(pid, unix.SIGKILL)
+ _ = unix.Kill(pid, unix.SIGKILL)
}
diff --git a/vendor/github.com/containers/storage/pkg/system/rm.go b/vendor/github.com/containers/storage/pkg/system/rm.go
index b1599d23f..510e71428 100644
--- a/vendor/github.com/containers/storage/pkg/system/rm.go
+++ b/vendor/github.com/containers/storage/pkg/system/rm.go
@@ -7,6 +7,7 @@ import (
"github.com/containers/storage/pkg/mount"
"github.com/pkg/errors"
+ "github.com/sirupsen/logrus"
)
// EnsureRemoveAll wraps `os.RemoveAll` to check for specific errors that can
@@ -29,12 +30,14 @@ func EnsureRemoveAll(dir string) error {
maxRetry := 100
// Attempt to unmount anything beneath this dir first
- mount.RecursiveUnmount(dir)
+ if err := mount.RecursiveUnmount(dir); err != nil {
+ logrus.Debugf("RecusiveUnmount on %s failed: %v", dir, err)
+ }
for {
err := os.RemoveAll(dir)
if err == nil {
- return err
+ return nil
}
pe, ok := err.(*os.PathError)
@@ -63,12 +66,8 @@ func EnsureRemoveAll(dir string) error {
return err
}
- if mounted, _ := mount.Mounted(pe.Path); mounted {
- if e := mount.Unmount(pe.Path); e != nil {
- if mounted, _ := mount.Mounted(pe.Path); mounted {
- return errors.Wrapf(e, "error while removing %s", dir)
- }
- }
+ if e := mount.Unmount(pe.Path); e != nil {
+ return errors.Wrapf(e, "error while removing %s", dir)
}
if exitOnErr[pe.Path] == maxRetry {
diff --git a/vendor/github.com/containers/storage/pkg/system/stat_unix.go b/vendor/github.com/containers/storage/pkg/system/stat_unix.go
index f9a1b4877..2fac918bf 100644
--- a/vendor/github.com/containers/storage/pkg/system/stat_unix.go
+++ b/vendor/github.com/containers/storage/pkg/system/stat_unix.go
@@ -3,6 +3,8 @@
package system
import (
+ "os"
+ "strconv"
"syscall"
)
@@ -54,7 +56,7 @@ func (s StatT) Mtim() syscall.Timespec {
func Stat(path string) (*StatT, error) {
s := &syscall.Stat_t{}
if err := syscall.Stat(path, s); err != nil {
- return nil, err
+ return nil, &os.PathError{Op: "Stat", Path: path, Err: err}
}
return fromStatT(s)
}
@@ -66,7 +68,7 @@ func Stat(path string) (*StatT, error) {
func Fstat(fd int) (*StatT, error) {
s := &syscall.Stat_t{}
if err := syscall.Fstat(fd, s); err != nil {
- return nil, err
+ return nil, &os.PathError{Op: "Fstat", Path: strconv.Itoa(fd), Err: err}
}
return fromStatT(s)
}
diff --git a/vendor/github.com/containers/storage/pkg/system/xattrs_linux.go b/vendor/github.com/containers/storage/pkg/system/xattrs_linux.go
index 24c3f37ef..e94bb5d5c 100644
--- a/vendor/github.com/containers/storage/pkg/system/xattrs_linux.go
+++ b/vendor/github.com/containers/storage/pkg/system/xattrs_linux.go
@@ -2,45 +2,43 @@ package system
import (
"bytes"
- "syscall"
"golang.org/x/sys/unix"
)
const (
// Value is larger than the maximum size allowed
- E2BIG syscall.Errno = unix.E2BIG
+ E2BIG unix.Errno = unix.E2BIG
// Operation not supported
- EOPNOTSUPP syscall.Errno = unix.EOPNOTSUPP
+ EOPNOTSUPP unix.Errno = unix.EOPNOTSUPP
)
// Lgetxattr retrieves the value of the extended attribute identified by attr
// and associated with the given path in the file system.
-// It will returns a nil slice and nil error if the xattr is not set.
+// Returns a []byte slice if the xattr is set and nil otherwise.
func Lgetxattr(path string, attr string) ([]byte, error) {
// Start with a 128 length byte array
dest := make([]byte, 128)
sz, errno := unix.Lgetxattr(path, attr, dest)
- switch {
- case errno == unix.ENODATA:
- return nil, nil
- case errno == unix.ERANGE:
- // 128 byte array might just not be good enough. A dummy buffer is used
- // to get the real size of the xattrs on disk
+ for errno == unix.ERANGE {
+ // Buffer too small, use zero-sized buffer to get the actual size
sz, errno = unix.Lgetxattr(path, attr, []byte{})
if errno != nil {
return nil, errno
}
dest = make([]byte, sz)
sz, errno = unix.Lgetxattr(path, attr, dest)
- if errno != nil {
- return nil, errno
- }
+ }
+
+ switch {
+ case errno == unix.ENODATA:
+ return nil, nil
case errno != nil:
return nil, errno
}
+
return dest[:sz], nil
}
@@ -53,24 +51,25 @@ func Lsetxattr(path string, attr string, data []byte, flags int) error {
// Llistxattr lists extended attributes associated with the given path
// in the file system.
func Llistxattr(path string) ([]string, error) {
- var dest []byte
+ dest := make([]byte, 128)
+ sz, errno := unix.Llistxattr(path, dest)
- for {
- sz, err := unix.Llistxattr(path, dest)
- if err != nil {
- return nil, err
+ for errno == unix.ERANGE {
+ // Buffer too small, use zero-sized buffer to get the actual size
+ sz, errno = unix.Llistxattr(path, []byte{})
+ if errno != nil {
+ return nil, errno
}
- if sz > len(dest) {
- dest = make([]byte, sz)
- } else {
- dest = dest[:sz]
- break
- }
+ dest = make([]byte, sz)
+ sz, errno = unix.Llistxattr(path, dest)
+ }
+ if errno != nil {
+ return nil, errno
}
var attrs []string
- for _, token := range bytes.Split(dest, []byte{0}) {
+ for _, token := range bytes.Split(dest[:sz], []byte{0}) {
if len(token) > 0 {
attrs = append(attrs, string(token))
}
diff --git a/vendor/github.com/containers/storage/storage.conf b/vendor/github.com/containers/storage/storage.conf
index b7b73ed38..895b479de 100644
--- a/vendor/github.com/containers/storage/storage.conf
+++ b/vendor/github.com/containers/storage/storage.conf
@@ -13,6 +13,10 @@ runroot = "/var/run/containers/storage"
# Primary Read/Write location of container storage
graphroot = "/var/lib/containers/storage"
+# Storage path for rootless users
+#
+# rootless_storage_path = "$HOME/.local/share/containers/storage"
+
[storage.options]
# Storage options to be passed to underlying storage drivers
@@ -107,7 +111,7 @@ mountopt = "nodev"
# Value 0% disables
# min_free_space = "10%"
-# mkfsarg specifies extra mkfs arguments to be used when creating the base.
+# mkfsarg specifies extra mkfs arguments to be used when creating the base
# device.
# mkfsarg = ""
@@ -115,7 +119,7 @@ mountopt = "nodev"
# size = ""
# use_deferred_removal marks devicemapper block device for deferred removal.
-# If the thinpool is in use when the driver attempts to remove it, the driver
+# If the thinpool is in use when the driver attempts to remove it, the driver
# tells the kernel to remove it as soon as possible. Note this does not free
# up the disk space, use deferred deletion to fully remove the thinpool.
# use_deferred_removal = "True"
diff --git a/vendor/github.com/containers/storage/store.go b/vendor/github.com/containers/storage/store.go
index 272153e51..9bf32cbaa 100644
--- a/vendor/github.com/containers/storage/store.go
+++ b/vendor/github.com/containers/storage/store.go
@@ -20,6 +20,7 @@ import (
"github.com/containers/storage/pkg/archive"
cfg "github.com/containers/storage/pkg/config"
"github.com/containers/storage/pkg/directory"
+ "github.com/containers/storage/pkg/homedir"
"github.com/containers/storage/pkg/idtools"
"github.com/containers/storage/pkg/ioutils"
"github.com/containers/storage/pkg/parsers"
@@ -138,6 +139,9 @@ type StoreOptions struct {
// GraphRoot is the filesystem path under which we will store the
// contents of layers, images, and containers.
GraphRoot string `json:"root,omitempty"`
+ // RootlessStoragePath is the storage path for rootless users
+ // default $HOME/.local/share/containers/storage
+ RootlessStoragePath string `toml:"rootless_storage_path"`
// GraphDriverName is the underlying storage driver that we'll be
// using. It only needs to be specified the first time a Store is
// initialized for a given RunRoot and GraphRoot.
@@ -2316,24 +2320,53 @@ func (s *store) DeleteContainer(id string) error {
if rcstore.Exists(id) {
if container, err := rcstore.Get(id); err == nil {
+ errChan := make(chan error)
+ var wg sync.WaitGroup
+
if rlstore.Exists(container.LayerID) {
- if err = rlstore.Delete(container.LayerID); err != nil {
- return err
- }
- }
- if err = rcstore.Delete(id); err != nil {
- return err
- }
+ wg.Add(1)
+ go func() {
+ errChan <- rlstore.Delete(container.LayerID)
+ wg.Done()
+ }()
+ }
+ wg.Add(1)
+ go func() {
+ errChan <- rcstore.Delete(id)
+ wg.Done()
+ }()
+
middleDir := s.graphDriverName + "-containers"
gcpath := filepath.Join(s.GraphRoot(), middleDir, container.ID)
- if err = os.RemoveAll(gcpath); err != nil {
- return err
- }
+ wg.Add(1)
+ go func() {
+ errChan <- os.RemoveAll(gcpath)
+ wg.Done()
+ }()
+
rcpath := filepath.Join(s.RunRoot(), middleDir, container.ID)
- if err = os.RemoveAll(rcpath); err != nil {
- return err
+ wg.Add(1)
+ go func() {
+ errChan <- os.RemoveAll(rcpath)
+ wg.Done()
+ }()
+
+ go func() {
+ wg.Wait()
+ close(errChan)
+ }()
+
+ for {
+ select {
+ case err, ok := <-errChan:
+ if !ok {
+ return nil
+ }
+ if err != nil {
+ return err
+ }
+ }
}
- return nil
}
}
return ErrNotAContainer
@@ -2783,18 +2816,24 @@ func (s *store) ContainerParentOwners(id string) ([]int, []int, error) {
}
func (s *store) Layers() ([]Layer, error) {
- var layers []Layer
lstore, err := s.LayerStore()
if err != nil {
return nil, err
}
+ if err := lstore.LoadLocked(); err != nil {
+ return nil, err
+ }
+ layers, err := lstore.Layers()
+ if err != nil {
+ return nil, err
+ }
lstores, err := s.ROLayerStores()
if err != nil {
return nil, err
}
- for _, s := range append([]ROLayerStore{lstore}, lstores...) {
+ for _, s := range lstores {
store := s
store.RLock()
defer store.Unlock()
@@ -3269,9 +3308,12 @@ const defaultConfigFile = "/etc/containers/storage.conf"
// DefaultConfigFile returns the path to the storage config file used
func DefaultConfigFile(rootless bool) (string, error) {
if rootless {
- home, err := homeDir()
- if err != nil {
- return "", errors.Wrapf(err, "cannot determine users homedir")
+ if configHome := os.Getenv("XDG_CONFIG_HOME"); configHome != "" {
+ return filepath.Join(configHome, "containers/storage.conf"), nil
+ }
+ home := homedir.Get()
+ if home == "" {
+ return "", errors.New("cannot determine user's homedir")
}
return filepath.Join(home, ".config/containers/storage.conf"), nil
}
@@ -3281,10 +3323,11 @@ func DefaultConfigFile(rootless bool) (string, error) {
// TOML-friendly explicit tables used for conversions.
type tomlConfig struct {
Storage struct {
- Driver string `toml:"driver"`
- RunRoot string `toml:"runroot"`
- GraphRoot string `toml:"graphroot"`
- Options cfg.OptionsConfig `toml:"options"`
+ Driver string `toml:"driver"`
+ RunRoot string `toml:"runroot"`
+ GraphRoot string `toml:"graphroot"`
+ RootlessStoragePath string `toml:"rootless_storage_path"`
+ Options cfg.OptionsConfig `toml:"options"`
} `toml:"storage"`
}
@@ -3305,6 +3348,9 @@ func ReloadConfigurationFile(configFile string, storeOptions *StoreOptions) {
fmt.Printf("Failed to parse %s %v\n", configFile, err.Error())
return
}
+ if os.Getenv("STORAGE_DRIVER") != "" {
+ config.Storage.Driver = os.Getenv("STORAGE_DRIVER")
+ }
if config.Storage.Driver != "" {
storeOptions.GraphDriverName = config.Storage.Driver
}
@@ -3314,6 +3360,9 @@ func ReloadConfigurationFile(configFile string, storeOptions *StoreOptions) {
if config.Storage.GraphRoot != "" {
storeOptions.GraphRoot = config.Storage.GraphRoot
}
+ if config.Storage.RootlessStoragePath != "" {
+ storeOptions.RootlessStoragePath = config.Storage.RootlessStoragePath
+ }
for _, s := range config.Storage.Options.AdditionalImageStores {
storeOptions.GraphDriverOptions = append(storeOptions.GraphDriverOptions, fmt.Sprintf("%s.imagestore=%s", config.Storage.Driver, s))
}
@@ -3357,11 +3406,8 @@ func ReloadConfigurationFile(configFile string, storeOptions *StoreOptions) {
} else {
storeOptions.GIDMap = append(storeOptions.GIDMap, gidmap...)
}
- if os.Getenv("STORAGE_DRIVER") != "" {
- storeOptions.GraphDriverName = os.Getenv("STORAGE_DRIVER")
- }
- storeOptions.GraphDriverOptions = cfg.GetGraphDriverOptions(storeOptions.GraphDriverName, config.Storage.Options)
+ storeOptions.GraphDriverOptions = append(storeOptions.GraphDriverOptions, cfg.GetGraphDriverOptions(storeOptions.GraphDriverName, config.Storage.Options)...)
if os.Getenv("STORAGE_OPTS") != "" {
storeOptions.GraphDriverOptions = append(storeOptions.GraphDriverOptions, strings.Split(os.Getenv("STORAGE_OPTS"), ",")...)
@@ -3371,12 +3417,44 @@ func ReloadConfigurationFile(configFile string, storeOptions *StoreOptions) {
}
}
+var prevReloadConfig = struct {
+ storeOptions *StoreOptions
+ mod time.Time
+ mutex sync.Mutex
+ configFile string
+}{}
+
+func reloadConfigurationFileIfNeeded(configFile string, storeOptions *StoreOptions) {
+ prevReloadConfig.mutex.Lock()
+ defer prevReloadConfig.mutex.Unlock()
+
+ fi, err := os.Stat(configFile)
+ if err != nil {
+ if !os.IsNotExist(err) {
+ fmt.Printf("Failed to read %s %v\n", configFile, err.Error())
+ }
+ return
+ }
+
+ mtime := fi.ModTime()
+ if prevReloadConfig.storeOptions != nil && prevReloadConfig.mod == mtime && prevReloadConfig.configFile == configFile {
+ *storeOptions = *prevReloadConfig.storeOptions
+ return
+ }
+
+ ReloadConfigurationFile(configFile, storeOptions)
+
+ prevReloadConfig.storeOptions = storeOptions
+ prevReloadConfig.mod = mtime
+ prevReloadConfig.configFile = configFile
+}
+
func init() {
defaultStoreOptions.RunRoot = "/var/run/containers/storage"
defaultStoreOptions.GraphRoot = "/var/lib/containers/storage"
defaultStoreOptions.GraphDriverName = ""
- ReloadConfigurationFile(defaultConfigFile, &defaultStoreOptions)
+ reloadConfigurationFileIfNeeded(defaultConfigFile, &defaultStoreOptions)
}
// GetDefaultMountOptions returns the default mountoptions defined in container/storage
diff --git a/vendor/github.com/containers/storage/utils.go b/vendor/github.com/containers/storage/utils.go
index 5aa7c0851..235bf6d41 100644
--- a/vendor/github.com/containers/storage/utils.go
+++ b/vendor/github.com/containers/storage/utils.go
@@ -6,10 +6,11 @@ import (
"os/exec"
"os/user"
"path/filepath"
+ "regexp"
"strconv"
"strings"
- "github.com/BurntSushi/toml"
+ "github.com/containers/storage/pkg/homedir"
"github.com/containers/storage/pkg/idtools"
"github.com/containers/storage/pkg/system"
"github.com/pkg/errors"
@@ -69,8 +70,8 @@ func ParseIDMapping(UIDMapSlice, GIDMapSlice []string, subUIDMap, subGIDMap stri
}
// GetRootlessRuntimeDir returns the runtime directory when running as non root
-func GetRootlessRuntimeDir(rootlessUid int) (string, error) {
- path, err := getRootlessRuntimeDir(rootlessUid)
+func GetRootlessRuntimeDir(rootlessUID int) (string, error) {
+ path, err := getRootlessRuntimeDir(rootlessUID)
if err != nil {
return "", err
}
@@ -81,25 +82,24 @@ func GetRootlessRuntimeDir(rootlessUid int) (string, error) {
return path, nil
}
-func getRootlessRuntimeDir(rootlessUid int) (string, error) {
- runtimeDir := os.Getenv("XDG_RUNTIME_DIR")
-
- if runtimeDir != "" {
+func getRootlessRuntimeDir(rootlessUID int) (string, error) {
+ runtimeDir, err := homedir.GetRuntimeDir()
+ if err == nil {
return runtimeDir, nil
}
- tmpDir := fmt.Sprintf("/run/user/%d", rootlessUid)
+ tmpDir := fmt.Sprintf("/run/user/%d", rootlessUID)
st, err := system.Stat(tmpDir)
if err == nil && int(st.UID()) == os.Getuid() && st.Mode()&0700 == 0700 && st.Mode()&0066 == 0000 {
return tmpDir, nil
}
- tmpDir = fmt.Sprintf("%s/%d", os.TempDir(), rootlessUid)
+ tmpDir = fmt.Sprintf("%s/%d", os.TempDir(), rootlessUID)
if err := os.MkdirAll(tmpDir, 0700); err != nil {
logrus.Errorf("failed to create %s: %v", tmpDir, err)
} else {
return tmpDir, nil
}
- home, err := homeDir()
- if err != nil {
+ home := homedir.Get()
+ if home == "" {
return "", errors.Wrapf(err, "neither XDG_RUNTIME_DIR nor HOME was set non-empty")
}
resolvedHome, err := filepath.EvalSymlinks(home)
@@ -111,39 +111,43 @@ func getRootlessRuntimeDir(rootlessUid int) (string, error) {
// getRootlessDirInfo returns the parent path of where the storage for containers and
// volumes will be in rootless mode
-func getRootlessDirInfo(rootlessUid int) (string, string, error) {
- rootlessRuntime, err := GetRootlessRuntimeDir(rootlessUid)
+func getRootlessDirInfo(rootlessUID int) (string, string, error) {
+ rootlessRuntime, err := GetRootlessRuntimeDir(rootlessUID)
if err != nil {
return "", "", err
}
- dataDir := os.Getenv("XDG_DATA_HOME")
- if dataDir == "" {
- home, err := homeDir()
- if err != nil {
- return "", "", errors.Wrapf(err, "neither XDG_DATA_HOME nor HOME was set non-empty")
- }
- // runc doesn't like symlinks in the rootfs path, and at least
- // on CoreOS /home is a symlink to /var/home, so resolve any symlink.
- resolvedHome, err := filepath.EvalSymlinks(home)
- if err != nil {
- return "", "", errors.Wrapf(err, "cannot resolve %s", home)
- }
- dataDir = filepath.Join(resolvedHome, ".local", "share")
+ dataDir, err := homedir.GetDataHome()
+ if err == nil {
+ return dataDir, rootlessRuntime, nil
}
+
+ home := homedir.Get()
+ if home == "" {
+ return "", "", errors.Wrapf(err, "neither XDG_DATA_HOME nor HOME was set non-empty")
+ }
+ // runc doesn't like symlinks in the rootfs path, and at least
+ // on CoreOS /home is a symlink to /var/home, so resolve any symlink.
+ resolvedHome, err := filepath.EvalSymlinks(home)
+ if err != nil {
+ return "", "", errors.Wrapf(err, "cannot resolve %s", home)
+ }
+ dataDir = filepath.Join(resolvedHome, ".local", "share")
+
return dataDir, rootlessRuntime, nil
}
// getRootlessStorageOpts returns the storage opts for containers running as non root
-func getRootlessStorageOpts(rootlessUid int) (StoreOptions, error) {
+func getRootlessStorageOpts(rootlessUID int) (StoreOptions, error) {
var opts StoreOptions
- dataDir, rootlessRuntime, err := getRootlessDirInfo(rootlessUid)
+ dataDir, rootlessRuntime, err := getRootlessDirInfo(rootlessUID)
if err != nil {
return opts, err
}
opts.RunRoot = rootlessRuntime
opts.GraphRoot = filepath.Join(dataDir, "containers", "storage")
+ opts.RootlessStoragePath = opts.GraphRoot
if path, err := exec.LookPath("fuse-overlayfs"); err == nil {
opts.GraphDriverName = "overlay"
opts.GraphDriverOptions = []string{fmt.Sprintf("overlay.mount_program=%s", path)}
@@ -153,26 +157,6 @@ func getRootlessStorageOpts(rootlessUid int) (StoreOptions, error) {
return opts, nil
}
-type tomlOptionsConfig struct {
- MountProgram string `toml:"mount_program"`
-}
-
-func getTomlStorage(storeOptions *StoreOptions) *tomlConfig {
- config := new(tomlConfig)
-
- config.Storage.Driver = storeOptions.GraphDriverName
- config.Storage.RunRoot = storeOptions.RunRoot
- config.Storage.GraphRoot = storeOptions.GraphRoot
- for _, i := range storeOptions.GraphDriverOptions {
- s := strings.Split(i, "=")
- if s[0] == "overlay.mount_program" {
- config.Storage.Options.MountProgram = s[1]
- }
- }
-
- return config
-}
-
func getRootlessUID() int {
uidEnv := os.Getenv("_CONTAINERS_ROOTLESS_UID")
if uidEnv != "" {
@@ -189,21 +173,21 @@ func DefaultStoreOptionsAutoDetectUID() (StoreOptions, error) {
}
// DefaultStoreOptions returns the default storage ops for containers
-func DefaultStoreOptions(rootless bool, rootlessUid int) (StoreOptions, error) {
+func DefaultStoreOptions(rootless bool, rootlessUID int) (StoreOptions, error) {
var (
defaultRootlessRunRoot string
defaultRootlessGraphRoot string
err error
)
storageOpts := defaultStoreOptions
- if rootless && rootlessUid != 0 {
- storageOpts, err = getRootlessStorageOpts(rootlessUid)
+ if rootless && rootlessUID != 0 {
+ storageOpts, err = getRootlessStorageOpts(rootlessUID)
if err != nil {
return storageOpts, err
}
}
- storageConf, err := DefaultConfigFile(rootless && rootlessUid != 0)
+ storageConf, err := DefaultConfigFile(rootless && rootlessUID != 0)
if err != nil {
return storageOpts, err
}
@@ -215,10 +199,10 @@ func DefaultStoreOptions(rootless bool, rootlessUid int) (StoreOptions, error) {
defaultRootlessRunRoot = storageOpts.RunRoot
defaultRootlessGraphRoot = storageOpts.GraphRoot
storageOpts = StoreOptions{}
- ReloadConfigurationFile(storageConf, &storageOpts)
+ reloadConfigurationFileIfNeeded(storageConf, &storageOpts)
}
- if rootless && rootlessUid != 0 {
+ if rootless && rootlessUID != 0 {
if err == nil {
// If the file did not specify a graphroot or runroot,
// set sane defaults so we don't try and use root-owned
@@ -229,36 +213,38 @@ func DefaultStoreOptions(rootless bool, rootlessUid int) (StoreOptions, error) {
if storageOpts.GraphRoot == "" {
storageOpts.GraphRoot = defaultRootlessGraphRoot
}
- } else {
- if err := os.MkdirAll(filepath.Dir(storageConf), 0755); err != nil {
- return storageOpts, errors.Wrapf(err, "cannot make directory %s", filepath.Dir(storageConf))
- }
- file, err := os.OpenFile(storageConf, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0666)
- if err != nil {
- return storageOpts, errors.Wrapf(err, "cannot open %s", storageConf)
- }
-
- tomlConfiguration := getTomlStorage(&storageOpts)
- defer file.Close()
- enc := toml.NewEncoder(file)
- if err := enc.Encode(tomlConfiguration); err != nil {
- os.Remove(storageConf)
-
- return storageOpts, errors.Wrapf(err, "failed to encode %s", storageConf)
+ if storageOpts.RootlessStoragePath != "" {
+ if err = validRootlessStoragePathFormat(storageOpts.RootlessStoragePath); err != nil {
+ return storageOpts, err
+ }
+ rootlessStoragePath := strings.Replace(storageOpts.RootlessStoragePath, "$HOME", homedir.Get(), -1)
+ rootlessStoragePath = strings.Replace(rootlessStoragePath, "$UID", strconv.Itoa(rootlessUID), -1)
+ usr, err := user.LookupId(strconv.Itoa(rootlessUID))
+ if err != nil {
+ return storageOpts, err
+ }
+ rootlessStoragePath = strings.Replace(rootlessStoragePath, "$USER", usr.Username, -1)
+ storageOpts.GraphRoot = rootlessStoragePath
}
}
}
return storageOpts, nil
}
-func homeDir() (string, error) {
- home := os.Getenv("HOME")
- if home == "" {
- usr, err := user.Current()
- if err != nil {
- return "", errors.Wrapf(err, "neither XDG_RUNTIME_DIR nor HOME was set non-empty")
+// validRootlessStoragePathFormat checks if the environments contained in the path are accepted
+func validRootlessStoragePathFormat(path string) error {
+ if !strings.Contains(path, "$") {
+ return nil
+ }
+
+ splitPaths := strings.SplitAfter(path, "$")
+ validEnv := regexp.MustCompile(`^(HOME|USER|UID)([^a-zA-Z]|$)`).MatchString
+ if len(splitPaths) > 1 {
+ for _, p := range splitPaths[1:] {
+ if !validEnv(p) {
+ return errors.Errorf("Unrecognized environment variable")
+ }
}
- home = usr.HomeDir
}
- return home, nil
+ return nil
}
diff --git a/vendor/github.com/coreos/go-systemd/LICENSE b/vendor/github.com/coreos/go-systemd/v22/LICENSE
index 37ec93a14..37ec93a14 100644
--- a/vendor/github.com/coreos/go-systemd/LICENSE
+++ b/vendor/github.com/coreos/go-systemd/v22/LICENSE
diff --git a/vendor/github.com/coreos/go-systemd/NOTICE b/vendor/github.com/coreos/go-systemd/v22/NOTICE
index 23a0ada2f..23a0ada2f 100644
--- a/vendor/github.com/coreos/go-systemd/NOTICE
+++ b/vendor/github.com/coreos/go-systemd/v22/NOTICE
diff --git a/vendor/github.com/coreos/go-systemd/activation/files.go b/vendor/github.com/coreos/go-systemd/v22/activation/files.go
index 29dd18def..29dd18def 100644
--- a/vendor/github.com/coreos/go-systemd/activation/files.go
+++ b/vendor/github.com/coreos/go-systemd/v22/activation/files.go
diff --git a/vendor/github.com/coreos/go-systemd/activation/listeners.go b/vendor/github.com/coreos/go-systemd/v22/activation/listeners.go
index 3dbe2b087..3dbe2b087 100644
--- a/vendor/github.com/coreos/go-systemd/activation/listeners.go
+++ b/vendor/github.com/coreos/go-systemd/v22/activation/listeners.go
diff --git a/vendor/github.com/coreos/go-systemd/activation/packetconns.go b/vendor/github.com/coreos/go-systemd/v22/activation/packetconns.go
index a97206785..a97206785 100644
--- a/vendor/github.com/coreos/go-systemd/activation/packetconns.go
+++ b/vendor/github.com/coreos/go-systemd/v22/activation/packetconns.go
diff --git a/vendor/github.com/coreos/go-systemd/dbus/dbus.go b/vendor/github.com/coreos/go-systemd/v22/dbus/dbus.go
index f652582e6..91584a166 100644
--- a/vendor/github.com/coreos/go-systemd/dbus/dbus.go
+++ b/vendor/github.com/coreos/go-systemd/v22/dbus/dbus.go
@@ -23,7 +23,7 @@ import (
"strings"
"sync"
- "github.com/godbus/dbus"
+ "github.com/godbus/dbus/v5"
)
const (
diff --git a/vendor/github.com/coreos/go-systemd/dbus/methods.go b/vendor/github.com/coreos/go-systemd/v22/dbus/methods.go
index 5859583eb..e38659d7b 100644
--- a/vendor/github.com/coreos/go-systemd/dbus/methods.go
+++ b/vendor/github.com/coreos/go-systemd/v22/dbus/methods.go
@@ -20,7 +20,7 @@ import (
"path"
"strconv"
- "github.com/godbus/dbus"
+ "github.com/godbus/dbus/v5"
)
func (c *Conn) jobComplete(signal *dbus.Signal) {
diff --git a/vendor/github.com/coreos/go-systemd/dbus/properties.go b/vendor/github.com/coreos/go-systemd/v22/dbus/properties.go
index 6c8189587..fb42b6273 100644
--- a/vendor/github.com/coreos/go-systemd/dbus/properties.go
+++ b/vendor/github.com/coreos/go-systemd/v22/dbus/properties.go
@@ -15,7 +15,7 @@
package dbus
import (
- "github.com/godbus/dbus"
+ "github.com/godbus/dbus/v5"
)
// From the systemd docs:
@@ -56,7 +56,7 @@ type execStart struct {
// http://www.freedesktop.org/software/systemd/man/systemd.service.html#ExecStart=
func PropExecStart(command []string, uncleanIsFailure bool) Property {
execStarts := []execStart{
- execStart{
+ {
Path: command[0],
Args: command,
UncleanIsFailure: uncleanIsFailure,
diff --git a/vendor/github.com/coreos/go-systemd/dbus/set.go b/vendor/github.com/coreos/go-systemd/v22/dbus/set.go
index 17c5d4856..17c5d4856 100644
--- a/vendor/github.com/coreos/go-systemd/dbus/set.go
+++ b/vendor/github.com/coreos/go-systemd/v22/dbus/set.go
diff --git a/vendor/github.com/coreos/go-systemd/dbus/subscription.go b/vendor/github.com/coreos/go-systemd/v22/dbus/subscription.go
index f6d7a08a1..7e370fea2 100644
--- a/vendor/github.com/coreos/go-systemd/dbus/subscription.go
+++ b/vendor/github.com/coreos/go-systemd/v22/dbus/subscription.go
@@ -19,7 +19,7 @@ import (
"log"
"time"
- "github.com/godbus/dbus"
+ "github.com/godbus/dbus/v5"
)
const (
diff --git a/vendor/github.com/coreos/go-systemd/dbus/subscription_set.go b/vendor/github.com/coreos/go-systemd/v22/dbus/subscription_set.go
index 5b408d584..5b408d584 100644
--- a/vendor/github.com/coreos/go-systemd/dbus/subscription_set.go
+++ b/vendor/github.com/coreos/go-systemd/v22/dbus/subscription_set.go
diff --git a/vendor/github.com/coreos/pkg/dlopen/dlopen.go b/vendor/github.com/coreos/go-systemd/v22/internal/dlopen/dlopen.go
index 23774f612..23774f612 100644
--- a/vendor/github.com/coreos/pkg/dlopen/dlopen.go
+++ b/vendor/github.com/coreos/go-systemd/v22/internal/dlopen/dlopen.go
diff --git a/vendor/github.com/coreos/go-systemd/journal/journal.go b/vendor/github.com/coreos/go-systemd/v22/journal/journal.go
index a0f4837a0..a0f4837a0 100644
--- a/vendor/github.com/coreos/go-systemd/journal/journal.go
+++ b/vendor/github.com/coreos/go-systemd/v22/journal/journal.go
diff --git a/vendor/github.com/coreos/go-systemd/sdjournal/functions.go b/vendor/github.com/coreos/go-systemd/v22/sdjournal/functions.go
index e132369c1..3cbd05658 100644
--- a/vendor/github.com/coreos/go-systemd/sdjournal/functions.go
+++ b/vendor/github.com/coreos/go-systemd/v22/sdjournal/functions.go
@@ -16,7 +16,7 @@
package sdjournal
import (
- "github.com/coreos/pkg/dlopen"
+ "github.com/coreos/go-systemd/v22/internal/dlopen"
"sync"
"unsafe"
)
diff --git a/vendor/github.com/coreos/go-systemd/sdjournal/journal.go b/vendor/github.com/coreos/go-systemd/v22/sdjournal/journal.go
index 7f840def8..7f840def8 100644
--- a/vendor/github.com/coreos/go-systemd/sdjournal/journal.go
+++ b/vendor/github.com/coreos/go-systemd/v22/sdjournal/journal.go
diff --git a/vendor/github.com/coreos/go-systemd/sdjournal/read.go b/vendor/github.com/coreos/go-systemd/v22/sdjournal/read.go
index 51a060fb5..51a060fb5 100644
--- a/vendor/github.com/coreos/go-systemd/sdjournal/read.go
+++ b/vendor/github.com/coreos/go-systemd/v22/sdjournal/read.go
diff --git a/vendor/github.com/coreos/pkg/LICENSE b/vendor/github.com/coreos/pkg/LICENSE
deleted file mode 100644
index e06d20818..000000000
--- a/vendor/github.com/coreos/pkg/LICENSE
+++ /dev/null
@@ -1,202 +0,0 @@
-Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
- APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "{}"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
- Copyright {yyyy} {name of copyright owner}
-
- 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.
-
diff --git a/vendor/github.com/coreos/pkg/NOTICE b/vendor/github.com/coreos/pkg/NOTICE
deleted file mode 100644
index b39ddfa5c..000000000
--- a/vendor/github.com/coreos/pkg/NOTICE
+++ /dev/null
@@ -1,5 +0,0 @@
-CoreOS Project
-Copyright 2014 CoreOS, Inc
-
-This product includes software developed at CoreOS, Inc.
-(http://www.coreos.com/).
diff --git a/vendor/github.com/coreos/pkg/dlopen/dlopen_example.go b/vendor/github.com/coreos/pkg/dlopen/dlopen_example.go
deleted file mode 100644
index 48a660104..000000000
--- a/vendor/github.com/coreos/pkg/dlopen/dlopen_example.go
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright 2015 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.
-//
-// +build linux
-
-package dlopen
-
-// #include <string.h>
-// #include <stdlib.h>
-//
-// int
-// my_strlen(void *f, const char *s)
-// {
-// size_t (*strlen)(const char *);
-//
-// strlen = (size_t (*)(const char *))f;
-// return strlen(s);
-// }
-import "C"
-
-import (
- "fmt"
- "unsafe"
-)
-
-func strlen(libs []string, s string) (int, error) {
- h, err := GetHandle(libs)
- if err != nil {
- return -1, fmt.Errorf(`couldn't get a handle to the library: %v`, err)
- }
- defer h.Close()
-
- f := "strlen"
- cs := C.CString(s)
- defer C.free(unsafe.Pointer(cs))
-
- strlen, err := h.GetSymbolPointer(f)
- if err != nil {
- return -1, fmt.Errorf(`couldn't get symbol %q: %v`, f, err)
- }
-
- len := C.my_strlen(strlen, cs)
-
- return int(len), nil
-}
diff --git a/vendor/github.com/docker/docker/oci/caps/defaults.go b/vendor/github.com/docker/docker/oci/caps/defaults.go
deleted file mode 100644
index 242ee5811..000000000
--- a/vendor/github.com/docker/docker/oci/caps/defaults.go
+++ /dev/null
@@ -1,21 +0,0 @@
-package caps // import "github.com/docker/docker/oci/caps"
-
-// DefaultCapabilities returns a Linux kernel default capabilities
-func DefaultCapabilities() []string {
- return []string{
- "CAP_CHOWN",
- "CAP_DAC_OVERRIDE",
- "CAP_FSETID",
- "CAP_FOWNER",
- "CAP_MKNOD",
- "CAP_NET_RAW",
- "CAP_SETGID",
- "CAP_SETUID",
- "CAP_SETFCAP",
- "CAP_SETPCAP",
- "CAP_NET_BIND_SERVICE",
- "CAP_SYS_CHROOT",
- "CAP_KILL",
- "CAP_AUDIT_WRITE",
- }
-}
diff --git a/vendor/github.com/docker/docker/oci/caps/utils.go b/vendor/github.com/docker/docker/oci/caps/utils.go
deleted file mode 100644
index ffd3f6f50..000000000
--- a/vendor/github.com/docker/docker/oci/caps/utils.go
+++ /dev/null
@@ -1,169 +0,0 @@
-package caps // import "github.com/docker/docker/oci/caps"
-
-import (
- "fmt"
- "strings"
-
- "github.com/docker/docker/errdefs"
- "github.com/syndtr/gocapability/capability"
-)
-
-var capabilityList Capabilities
-
-func init() {
- last := capability.CAP_LAST_CAP
- // hack for RHEL6 which has no /proc/sys/kernel/cap_last_cap
- if last == capability.Cap(63) {
- last = capability.CAP_BLOCK_SUSPEND
- }
- for _, cap := range capability.List() {
- if cap > last {
- continue
- }
- capabilityList = append(capabilityList,
- &CapabilityMapping{
- Key: "CAP_" + strings.ToUpper(cap.String()),
- Value: cap,
- },
- )
- }
-}
-
-type (
- // CapabilityMapping maps linux capability name to its value of capability.Cap type
- // Capabilities is one of the security systems in Linux Security Module (LSM)
- // framework provided by the kernel.
- // For more details on capabilities, see http://man7.org/linux/man-pages/man7/capabilities.7.html
- CapabilityMapping struct {
- Key string `json:"key,omitempty"`
- Value capability.Cap `json:"value,omitempty"`
- }
- // Capabilities contains all CapabilityMapping
- Capabilities []*CapabilityMapping
-)
-
-// String returns <key> of CapabilityMapping
-func (c *CapabilityMapping) String() string {
- return c.Key
-}
-
-// GetCapability returns CapabilityMapping which contains specific key
-func GetCapability(key string) *CapabilityMapping {
- for _, capp := range capabilityList {
- if capp.Key == key {
- cpy := *capp
- return &cpy
- }
- }
- return nil
-}
-
-// GetAllCapabilities returns all of the capabilities
-func GetAllCapabilities() []string {
- output := make([]string, len(capabilityList))
- for i, capability := range capabilityList {
- output[i] = capability.String()
- }
- return output
-}
-
-// inSlice tests whether a string is contained in a slice of strings or not.
-func inSlice(slice []string, s string) bool {
- for _, ss := range slice {
- if s == ss {
- return true
- }
- }
- return false
-}
-
-const allCapabilities = "ALL"
-
-// NormalizeLegacyCapabilities normalizes, and validates CapAdd/CapDrop capabilities
-// by upper-casing them, and adding a CAP_ prefix (if not yet present).
-//
-// This function also accepts the "ALL" magic-value, that's used by CapAdd/CapDrop.
-func NormalizeLegacyCapabilities(caps []string) ([]string, error) {
- var normalized []string
-
- valids := GetAllCapabilities()
- for _, c := range caps {
- c = strings.ToUpper(c)
- if c == allCapabilities {
- normalized = append(normalized, c)
- continue
- }
- if !strings.HasPrefix(c, "CAP_") {
- c = "CAP_" + c
- }
- if !inSlice(valids, c) {
- return nil, errdefs.InvalidParameter(fmt.Errorf("unknown capability: %q", c))
- }
- normalized = append(normalized, c)
- }
- return normalized, nil
-}
-
-// ValidateCapabilities validates if caps only contains valid capabilities
-func ValidateCapabilities(caps []string) error {
- valids := GetAllCapabilities()
- for _, c := range caps {
- if !inSlice(valids, c) {
- return errdefs.InvalidParameter(fmt.Errorf("unknown capability: %q", c))
- }
- }
- return nil
-}
-
-// TweakCapabilities tweaks capabilities by adding, dropping, or overriding
-// capabilities in the basics capabilities list.
-func TweakCapabilities(basics, adds, drops, capabilities []string, privileged bool) ([]string, error) {
- switch {
- case privileged:
- // Privileged containers get all capabilities
- return GetAllCapabilities(), nil
- case capabilities != nil:
- // Use custom set of capabilities
- if err := ValidateCapabilities(capabilities); err != nil {
- return nil, err
- }
- return capabilities, nil
- case len(adds) == 0 && len(drops) == 0:
- // Nothing to tweak; we're done
- return basics, nil
- }
-
- capDrop, err := NormalizeLegacyCapabilities(drops)
- if err != nil {
- return nil, err
- }
- capAdd, err := NormalizeLegacyCapabilities(adds)
- if err != nil {
- return nil, err
- }
-
- var caps []string
-
- switch {
- case inSlice(capAdd, allCapabilities):
- // Add all capabilities except ones on capDrop
- for _, c := range GetAllCapabilities() {
- if !inSlice(capDrop, c) {
- caps = append(caps, c)
- }
- }
- case inSlice(capDrop, allCapabilities):
- // "Drop" all capabilities; use what's in capAdd instead
- caps = capAdd
- default:
- // First drop some capabilities
- for _, c := range basics {
- if !inSlice(capDrop, c) {
- caps = append(caps, c)
- }
- }
- // Then add the list of capabilities from capAdd
- caps = append(caps, capAdd...)
- }
- return caps, nil
-}
diff --git a/vendor/github.com/docker/docker/pkg/signal/README.md b/vendor/github.com/docker/docker/pkg/signal/README.md
deleted file mode 100644
index 2b237a594..000000000
--- a/vendor/github.com/docker/docker/pkg/signal/README.md
+++ /dev/null
@@ -1 +0,0 @@
-This package provides helper functions for dealing with signals across various operating systems \ No newline at end of file
diff --git a/vendor/github.com/docker/docker/pkg/signal/signal.go b/vendor/github.com/docker/docker/pkg/signal/signal.go
deleted file mode 100644
index 88ef7b5ea..000000000
--- a/vendor/github.com/docker/docker/pkg/signal/signal.go
+++ /dev/null
@@ -1,54 +0,0 @@
-// Package signal provides helper functions for dealing with signals across
-// various operating systems.
-package signal // import "github.com/docker/docker/pkg/signal"
-
-import (
- "fmt"
- "os"
- "os/signal"
- "strconv"
- "strings"
- "syscall"
-)
-
-// CatchAll catches all signals and relays them to the specified channel.
-func CatchAll(sigc chan os.Signal) {
- var handledSigs []os.Signal
- for _, s := range SignalMap {
- handledSigs = append(handledSigs, s)
- }
- signal.Notify(sigc, handledSigs...)
-}
-
-// StopCatch stops catching the signals and closes the specified channel.
-func StopCatch(sigc chan os.Signal) {
- signal.Stop(sigc)
- close(sigc)
-}
-
-// ParseSignal translates a string to a valid syscall signal.
-// It returns an error if the signal map doesn't include the given signal.
-func ParseSignal(rawSignal string) (syscall.Signal, error) {
- s, err := strconv.Atoi(rawSignal)
- if err == nil {
- if s == 0 {
- return -1, fmt.Errorf("Invalid signal: %s", rawSignal)
- }
- return syscall.Signal(s), nil
- }
- signal, ok := SignalMap[strings.TrimPrefix(strings.ToUpper(rawSignal), "SIG")]
- if !ok {
- return -1, fmt.Errorf("Invalid signal: %s", rawSignal)
- }
- return signal, nil
-}
-
-// ValidSignalForPlatform returns true if a signal is valid on the platform
-func ValidSignalForPlatform(sig syscall.Signal) bool {
- for _, v := range SignalMap {
- if v == sig {
- return true
- }
- }
- return false
-}
diff --git a/vendor/github.com/docker/docker/pkg/signal/signal_darwin.go b/vendor/github.com/docker/docker/pkg/signal/signal_darwin.go
deleted file mode 100644
index ee5501e3d..000000000
--- a/vendor/github.com/docker/docker/pkg/signal/signal_darwin.go
+++ /dev/null
@@ -1,41 +0,0 @@
-package signal // import "github.com/docker/docker/pkg/signal"
-
-import (
- "syscall"
-)
-
-// SignalMap is a map of Darwin signals.
-var SignalMap = map[string]syscall.Signal{
- "ABRT": syscall.SIGABRT,
- "ALRM": syscall.SIGALRM,
- "BUG": syscall.SIGBUS,
- "CHLD": syscall.SIGCHLD,
- "CONT": syscall.SIGCONT,
- "EMT": syscall.SIGEMT,
- "FPE": syscall.SIGFPE,
- "HUP": syscall.SIGHUP,
- "ILL": syscall.SIGILL,
- "INFO": syscall.SIGINFO,
- "INT": syscall.SIGINT,
- "IO": syscall.SIGIO,
- "IOT": syscall.SIGIOT,
- "KILL": syscall.SIGKILL,
- "PIPE": syscall.SIGPIPE,
- "PROF": syscall.SIGPROF,
- "QUIT": syscall.SIGQUIT,
- "SEGV": syscall.SIGSEGV,
- "STOP": syscall.SIGSTOP,
- "SYS": syscall.SIGSYS,
- "TERM": syscall.SIGTERM,
- "TRAP": syscall.SIGTRAP,
- "TSTP": syscall.SIGTSTP,
- "TTIN": syscall.SIGTTIN,
- "TTOU": syscall.SIGTTOU,
- "URG": syscall.SIGURG,
- "USR1": syscall.SIGUSR1,
- "USR2": syscall.SIGUSR2,
- "VTALRM": syscall.SIGVTALRM,
- "WINCH": syscall.SIGWINCH,
- "XCPU": syscall.SIGXCPU,
- "XFSZ": syscall.SIGXFSZ,
-}
diff --git a/vendor/github.com/docker/docker/pkg/signal/signal_freebsd.go b/vendor/github.com/docker/docker/pkg/signal/signal_freebsd.go
deleted file mode 100644
index 764f90e26..000000000
--- a/vendor/github.com/docker/docker/pkg/signal/signal_freebsd.go
+++ /dev/null
@@ -1,43 +0,0 @@
-package signal // import "github.com/docker/docker/pkg/signal"
-
-import (
- "syscall"
-)
-
-// SignalMap is a map of FreeBSD signals.
-var SignalMap = map[string]syscall.Signal{
- "ABRT": syscall.SIGABRT,
- "ALRM": syscall.SIGALRM,
- "BUF": syscall.SIGBUS,
- "CHLD": syscall.SIGCHLD,
- "CONT": syscall.SIGCONT,
- "EMT": syscall.SIGEMT,
- "FPE": syscall.SIGFPE,
- "HUP": syscall.SIGHUP,
- "ILL": syscall.SIGILL,
- "INFO": syscall.SIGINFO,
- "INT": syscall.SIGINT,
- "IO": syscall.SIGIO,
- "IOT": syscall.SIGIOT,
- "KILL": syscall.SIGKILL,
- "LWP": syscall.SIGLWP,
- "PIPE": syscall.SIGPIPE,
- "PROF": syscall.SIGPROF,
- "QUIT": syscall.SIGQUIT,
- "SEGV": syscall.SIGSEGV,
- "STOP": syscall.SIGSTOP,
- "SYS": syscall.SIGSYS,
- "TERM": syscall.SIGTERM,
- "THR": syscall.SIGTHR,
- "TRAP": syscall.SIGTRAP,
- "TSTP": syscall.SIGTSTP,
- "TTIN": syscall.SIGTTIN,
- "TTOU": syscall.SIGTTOU,
- "URG": syscall.SIGURG,
- "USR1": syscall.SIGUSR1,
- "USR2": syscall.SIGUSR2,
- "VTALRM": syscall.SIGVTALRM,
- "WINCH": syscall.SIGWINCH,
- "XCPU": syscall.SIGXCPU,
- "XFSZ": syscall.SIGXFSZ,
-}
diff --git a/vendor/github.com/docker/docker/pkg/signal/signal_linux.go b/vendor/github.com/docker/docker/pkg/signal/signal_linux.go
deleted file mode 100644
index 4013bded1..000000000
--- a/vendor/github.com/docker/docker/pkg/signal/signal_linux.go
+++ /dev/null
@@ -1,83 +0,0 @@
-// +build !mips,!mipsle,!mips64,!mips64le
-
-package signal // import "github.com/docker/docker/pkg/signal"
-
-import (
- "syscall"
-
- "golang.org/x/sys/unix"
-)
-
-const (
- sigrtmin = 34
- sigrtmax = 64
-)
-
-// SignalMap is a map of Linux signals.
-var SignalMap = map[string]syscall.Signal{
- "ABRT": unix.SIGABRT,
- "ALRM": unix.SIGALRM,
- "BUS": unix.SIGBUS,
- "CHLD": unix.SIGCHLD,
- "CLD": unix.SIGCLD,
- "CONT": unix.SIGCONT,
- "FPE": unix.SIGFPE,
- "HUP": unix.SIGHUP,
- "ILL": unix.SIGILL,
- "INT": unix.SIGINT,
- "IO": unix.SIGIO,
- "IOT": unix.SIGIOT,
- "KILL": unix.SIGKILL,
- "PIPE": unix.SIGPIPE,
- "POLL": unix.SIGPOLL,
- "PROF": unix.SIGPROF,
- "PWR": unix.SIGPWR,
- "QUIT": unix.SIGQUIT,
- "SEGV": unix.SIGSEGV,
- "STKFLT": unix.SIGSTKFLT,
- "STOP": unix.SIGSTOP,
- "SYS": unix.SIGSYS,
- "TERM": unix.SIGTERM,
- "TRAP": unix.SIGTRAP,
- "TSTP": unix.SIGTSTP,
- "TTIN": unix.SIGTTIN,
- "TTOU": unix.SIGTTOU,
- "URG": unix.SIGURG,
- "USR1": unix.SIGUSR1,
- "USR2": unix.SIGUSR2,
- "VTALRM": unix.SIGVTALRM,
- "WINCH": unix.SIGWINCH,
- "XCPU": unix.SIGXCPU,
- "XFSZ": unix.SIGXFSZ,
- "RTMIN": sigrtmin,
- "RTMIN+1": sigrtmin + 1,
- "RTMIN+2": sigrtmin + 2,
- "RTMIN+3": sigrtmin + 3,
- "RTMIN+4": sigrtmin + 4,
- "RTMIN+5": sigrtmin + 5,
- "RTMIN+6": sigrtmin + 6,
- "RTMIN+7": sigrtmin + 7,
- "RTMIN+8": sigrtmin + 8,
- "RTMIN+9": sigrtmin + 9,
- "RTMIN+10": sigrtmin + 10,
- "RTMIN+11": sigrtmin + 11,
- "RTMIN+12": sigrtmin + 12,
- "RTMIN+13": sigrtmin + 13,
- "RTMIN+14": sigrtmin + 14,
- "RTMIN+15": sigrtmin + 15,
- "RTMAX-14": sigrtmax - 14,
- "RTMAX-13": sigrtmax - 13,
- "RTMAX-12": sigrtmax - 12,
- "RTMAX-11": sigrtmax - 11,
- "RTMAX-10": sigrtmax - 10,
- "RTMAX-9": sigrtmax - 9,
- "RTMAX-8": sigrtmax - 8,
- "RTMAX-7": sigrtmax - 7,
- "RTMAX-6": sigrtmax - 6,
- "RTMAX-5": sigrtmax - 5,
- "RTMAX-4": sigrtmax - 4,
- "RTMAX-3": sigrtmax - 3,
- "RTMAX-2": sigrtmax - 2,
- "RTMAX-1": sigrtmax - 1,
- "RTMAX": sigrtmax,
-}
diff --git a/vendor/github.com/docker/docker/pkg/signal/signal_linux_mipsx.go b/vendor/github.com/docker/docker/pkg/signal/signal_linux_mipsx.go
deleted file mode 100644
index 4c7989121..000000000
--- a/vendor/github.com/docker/docker/pkg/signal/signal_linux_mipsx.go
+++ /dev/null
@@ -1,84 +0,0 @@
-// +build linux
-// +build mips mipsle mips64 mips64le
-
-package signal // import "github.com/docker/docker/pkg/signal"
-
-import (
- "syscall"
-
- "golang.org/x/sys/unix"
-)
-
-const (
- sigrtmin = 34
- sigrtmax = 127
-)
-
-// SignalMap is a map of Linux signals.
-var SignalMap = map[string]syscall.Signal{
- "ABRT": unix.SIGABRT,
- "ALRM": unix.SIGALRM,
- "BUS": unix.SIGBUS,
- "CHLD": unix.SIGCHLD,
- "CLD": unix.SIGCLD,
- "CONT": unix.SIGCONT,
- "FPE": unix.SIGFPE,
- "HUP": unix.SIGHUP,
- "ILL": unix.SIGILL,
- "INT": unix.SIGINT,
- "IO": unix.SIGIO,
- "IOT": unix.SIGIOT,
- "KILL": unix.SIGKILL,
- "PIPE": unix.SIGPIPE,
- "POLL": unix.SIGPOLL,
- "PROF": unix.SIGPROF,
- "PWR": unix.SIGPWR,
- "QUIT": unix.SIGQUIT,
- "SEGV": unix.SIGSEGV,
- "SIGEMT": unix.SIGEMT,
- "STOP": unix.SIGSTOP,
- "SYS": unix.SIGSYS,
- "TERM": unix.SIGTERM,
- "TRAP": unix.SIGTRAP,
- "TSTP": unix.SIGTSTP,
- "TTIN": unix.SIGTTIN,
- "TTOU": unix.SIGTTOU,
- "URG": unix.SIGURG,
- "USR1": unix.SIGUSR1,
- "USR2": unix.SIGUSR2,
- "VTALRM": unix.SIGVTALRM,
- "WINCH": unix.SIGWINCH,
- "XCPU": unix.SIGXCPU,
- "XFSZ": unix.SIGXFSZ,
- "RTMIN": sigrtmin,
- "RTMIN+1": sigrtmin + 1,
- "RTMIN+2": sigrtmin + 2,
- "RTMIN+3": sigrtmin + 3,
- "RTMIN+4": sigrtmin + 4,
- "RTMIN+5": sigrtmin + 5,
- "RTMIN+6": sigrtmin + 6,
- "RTMIN+7": sigrtmin + 7,
- "RTMIN+8": sigrtmin + 8,
- "RTMIN+9": sigrtmin + 9,
- "RTMIN+10": sigrtmin + 10,
- "RTMIN+11": sigrtmin + 11,
- "RTMIN+12": sigrtmin + 12,
- "RTMIN+13": sigrtmin + 13,
- "RTMIN+14": sigrtmin + 14,
- "RTMIN+15": sigrtmin + 15,
- "RTMAX-14": sigrtmax - 14,
- "RTMAX-13": sigrtmax - 13,
- "RTMAX-12": sigrtmax - 12,
- "RTMAX-11": sigrtmax - 11,
- "RTMAX-10": sigrtmax - 10,
- "RTMAX-9": sigrtmax - 9,
- "RTMAX-8": sigrtmax - 8,
- "RTMAX-7": sigrtmax - 7,
- "RTMAX-6": sigrtmax - 6,
- "RTMAX-5": sigrtmax - 5,
- "RTMAX-4": sigrtmax - 4,
- "RTMAX-3": sigrtmax - 3,
- "RTMAX-2": sigrtmax - 2,
- "RTMAX-1": sigrtmax - 1,
- "RTMAX": sigrtmax,
-}
diff --git a/vendor/github.com/docker/docker/pkg/signal/signal_unix.go b/vendor/github.com/docker/docker/pkg/signal/signal_unix.go
deleted file mode 100644
index a2aa4248f..000000000
--- a/vendor/github.com/docker/docker/pkg/signal/signal_unix.go
+++ /dev/null
@@ -1,21 +0,0 @@
-// +build !windows
-
-package signal // import "github.com/docker/docker/pkg/signal"
-
-import (
- "syscall"
-)
-
-// Signals used in cli/command (no windows equivalent, use
-// invalid signals so they don't get handled)
-
-const (
- // SIGCHLD is a signal sent to a process when a child process terminates, is interrupted, or resumes after being interrupted.
- SIGCHLD = syscall.SIGCHLD
- // SIGWINCH is a signal sent to a process when its controlling terminal changes its size
- SIGWINCH = syscall.SIGWINCH
- // SIGPIPE is a signal sent to a process when a pipe is written to before the other end is open for reading
- SIGPIPE = syscall.SIGPIPE
- // DefaultStopSignal is the syscall signal used to stop a container in unix systems.
- DefaultStopSignal = "SIGTERM"
-)
diff --git a/vendor/github.com/docker/docker/pkg/signal/signal_unsupported.go b/vendor/github.com/docker/docker/pkg/signal/signal_unsupported.go
deleted file mode 100644
index 1fd25a83c..000000000
--- a/vendor/github.com/docker/docker/pkg/signal/signal_unsupported.go
+++ /dev/null
@@ -1,10 +0,0 @@
-// +build !linux,!darwin,!freebsd,!windows
-
-package signal // import "github.com/docker/docker/pkg/signal"
-
-import (
- "syscall"
-)
-
-// SignalMap is an empty map of signals for unsupported platform.
-var SignalMap = map[string]syscall.Signal{}
diff --git a/vendor/github.com/docker/docker/pkg/signal/signal_windows.go b/vendor/github.com/docker/docker/pkg/signal/signal_windows.go
deleted file mode 100644
index 65752f24a..000000000
--- a/vendor/github.com/docker/docker/pkg/signal/signal_windows.go
+++ /dev/null
@@ -1,26 +0,0 @@
-package signal // import "github.com/docker/docker/pkg/signal"
-
-import (
- "syscall"
-)
-
-// Signals used in cli/command (no windows equivalent, use
-// invalid signals so they don't get handled)
-const (
- SIGCHLD = syscall.Signal(0xff)
- SIGWINCH = syscall.Signal(0xff)
- SIGPIPE = syscall.Signal(0xff)
- // DefaultStopSignal is the syscall signal used to stop a container in windows systems.
- DefaultStopSignal = "15"
-)
-
-// SignalMap is a map of "supported" signals. As per the comment in GOLang's
-// ztypes_windows.go: "More invented values for signals". Windows doesn't
-// really support signals in any way, shape or form that Unix does.
-//
-// We have these so that docker kill can be used to gracefully (TERM) and
-// forcibly (KILL) terminate a container on Windows.
-var SignalMap = map[string]syscall.Signal{
- "KILL": syscall.SIGKILL,
- "TERM": syscall.SIGTERM,
-}
diff --git a/vendor/github.com/docker/docker/pkg/signal/trap.go b/vendor/github.com/docker/docker/pkg/signal/trap.go
deleted file mode 100644
index a277b9562..000000000
--- a/vendor/github.com/docker/docker/pkg/signal/trap.go
+++ /dev/null
@@ -1,104 +0,0 @@
-package signal // import "github.com/docker/docker/pkg/signal"
-
-import (
- "fmt"
- "os"
- gosignal "os/signal"
- "path/filepath"
- "runtime"
- "strings"
- "sync/atomic"
- "syscall"
- "time"
-
- "github.com/pkg/errors"
-)
-
-// Trap sets up a simplified signal "trap", appropriate for common
-// behavior expected from a vanilla unix command-line tool in general
-// (and the Docker engine in particular).
-//
-// * If SIGINT or SIGTERM are received, `cleanup` is called, then the process is terminated.
-// * If SIGINT or SIGTERM are received 3 times before cleanup is complete, then cleanup is
-// skipped and the process is terminated immediately (allows force quit of stuck daemon)
-// * A SIGQUIT always causes an exit without cleanup, with a goroutine dump preceding exit.
-// * Ignore SIGPIPE events. These are generated by systemd when journald is restarted while
-// the docker daemon is not restarted and also running under systemd.
-// Fixes https://github.com/docker/docker/issues/19728
-//
-func Trap(cleanup func(), logger interface {
- Info(args ...interface{})
-}) {
- c := make(chan os.Signal, 1)
- // we will handle INT, TERM, QUIT, SIGPIPE here
- signals := []os.Signal{os.Interrupt, syscall.SIGTERM, syscall.SIGQUIT, syscall.SIGPIPE}
- gosignal.Notify(c, signals...)
- go func() {
- interruptCount := uint32(0)
- for sig := range c {
- if sig == syscall.SIGPIPE {
- continue
- }
-
- go func(sig os.Signal) {
- logger.Info(fmt.Sprintf("Processing signal '%v'", sig))
- switch sig {
- case os.Interrupt, syscall.SIGTERM:
- if atomic.LoadUint32(&interruptCount) < 3 {
- // Initiate the cleanup only once
- if atomic.AddUint32(&interruptCount, 1) == 1 {
- // Call the provided cleanup handler
- cleanup()
- os.Exit(0)
- } else {
- return
- }
- } else {
- // 3 SIGTERM/INT signals received; force exit without cleanup
- logger.Info("Forcing docker daemon shutdown without cleanup; 3 interrupts received")
- }
- case syscall.SIGQUIT:
- DumpStacks("")
- logger.Info("Forcing docker daemon shutdown without cleanup on SIGQUIT")
- }
- // for the SIGINT/TERM, and SIGQUIT non-clean shutdown case, exit with 128 + signal #
- os.Exit(128 + int(sig.(syscall.Signal)))
- }(sig)
- }
- }()
-}
-
-const stacksLogNameTemplate = "goroutine-stacks-%s.log"
-
-// DumpStacks appends the runtime stack into file in dir and returns full path
-// to that file.
-func DumpStacks(dir string) (string, error) {
- var (
- buf []byte
- stackSize int
- )
- bufferLen := 16384
- for stackSize == len(buf) {
- buf = make([]byte, bufferLen)
- stackSize = runtime.Stack(buf, true)
- bufferLen *= 2
- }
- buf = buf[:stackSize]
- var f *os.File
- if dir != "" {
- path := filepath.Join(dir, fmt.Sprintf(stacksLogNameTemplate, strings.Replace(time.Now().Format(time.RFC3339), ":", "", -1)))
- var err error
- f, err = os.OpenFile(path, os.O_CREATE|os.O_WRONLY, 0666)
- if err != nil {
- return "", errors.Wrap(err, "failed to open file to write the goroutine stacks")
- }
- defer f.Close()
- defer f.Sync()
- } else {
- f = os.Stderr
- }
- if _, err := f.Write(buf); err != nil {
- return "", errors.Wrap(err, "failed to write goroutine stacks")
- }
- return f.Name(), nil
-}
diff --git a/vendor/github.com/docker/spdystream/connection.go b/vendor/github.com/docker/spdystream/connection.go
index 2023ecf84..6031a0db1 100644
--- a/vendor/github.com/docker/spdystream/connection.go
+++ b/vendor/github.com/docker/spdystream/connection.go
@@ -14,7 +14,7 @@ import (
var (
ErrInvalidStreamId = errors.New("Invalid stream id")
- ErrTimeout = errors.New("Timeout occurred")
+ ErrTimeout = errors.New("Timeout occured")
ErrReset = errors.New("Stream reset")
ErrWriteClosedStream = errors.New("Write on closed stream")
)
@@ -325,7 +325,7 @@ Loop:
readFrame, err := s.framer.ReadFrame()
if err != nil {
if err != io.EOF {
- debugMessage("frame read error: %s", err)
+ fmt.Errorf("frame read error: %s", err)
} else {
debugMessage("(%p) EOF received", s)
}
@@ -421,7 +421,7 @@ func (s *Connection) frameHandler(frameQueue *PriorityFrameQueue, newHandler Str
}
if frameErr != nil {
- debugMessage("frame handling error: %s", frameErr)
+ fmt.Errorf("frame handling error: %s", frameErr)
}
}
}
@@ -451,7 +451,6 @@ func (s *Connection) addStreamFrame(frame *spdy.SynStreamFrame) {
dataChan: make(chan []byte),
headerChan: make(chan http.Header),
closeChan: make(chan bool),
- priority: frame.Priority,
}
if frame.CFHeader.Flags&spdy.ControlFlagFin != 0x00 {
stream.closeRemoteChannels()
@@ -474,7 +473,7 @@ func (s *Connection) checkStreamFrame(frame *spdy.SynStreamFrame) bool {
go func() {
resetErr := s.sendResetFrame(spdy.ProtocolError, frame.StreamId)
if resetErr != nil {
- debugMessage("reset error: %s", resetErr)
+ fmt.Errorf("reset error: %s", resetErr)
}
}()
return false
@@ -719,7 +718,7 @@ func (s *Connection) shutdown(closeTimeout time.Duration) {
select {
case err, ok := <-s.shutdownChan:
if ok {
- debugMessage("Unhandled close error after %s: %s", duration, err)
+ fmt.Errorf("Unhandled close error after %s: %s", duration, err)
}
default:
}
diff --git a/vendor/github.com/docker/spdystream/handlers.go b/vendor/github.com/docker/spdystream/handlers.go
index d4ee7be81..b59fa5fdc 100644
--- a/vendor/github.com/docker/spdystream/handlers.go
+++ b/vendor/github.com/docker/spdystream/handlers.go
@@ -30,7 +30,9 @@ func MirrorStreamHandler(stream *Stream) {
}()
}
-// NoopStreamHandler does nothing when stream connects.
+// NoopStreamHandler does nothing when stream connects, most
+// likely used with RejectAuthHandler which will not allow any
+// streams to make it to the stream handler.
func NoOpStreamHandler(stream *Stream) {
stream.SendReply(http.Header{}, false)
}
diff --git a/vendor/github.com/fatih/camelcase/.travis.yml b/vendor/github.com/fatih/camelcase/.travis.yml
deleted file mode 100644
index 3489e3871..000000000
--- a/vendor/github.com/fatih/camelcase/.travis.yml
+++ /dev/null
@@ -1,3 +0,0 @@
-language: go
-go: 1.x
-
diff --git a/vendor/github.com/fatih/camelcase/LICENSE.md b/vendor/github.com/fatih/camelcase/LICENSE.md
deleted file mode 100644
index aa4a536ca..000000000
--- a/vendor/github.com/fatih/camelcase/LICENSE.md
+++ /dev/null
@@ -1,20 +0,0 @@
-The MIT License (MIT)
-
-Copyright (c) 2015 Fatih Arslan
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of
-this software and associated documentation files (the "Software"), to deal in
-the Software without restriction, including without limitation the rights to
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software is furnished to do so,
-subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
-FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
-COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/vendor/github.com/fatih/camelcase/README.md b/vendor/github.com/fatih/camelcase/README.md
deleted file mode 100644
index 105a6ae33..000000000
--- a/vendor/github.com/fatih/camelcase/README.md
+++ /dev/null
@@ -1,58 +0,0 @@
-# CamelCase [![GoDoc](http://img.shields.io/badge/go-documentation-blue.svg?style=flat-square)](http://godoc.org/github.com/fatih/camelcase) [![Build Status](http://img.shields.io/travis/fatih/camelcase.svg?style=flat-square)](https://travis-ci.org/fatih/camelcase)
-
-CamelCase is a Golang (Go) package to split the words of a camelcase type
-string into a slice of words. It can be used to convert a camelcase word (lower
-or upper case) into any type of word.
-
-## Splitting rules:
-
-1. If string is not valid UTF-8, return it without splitting as
- single item array.
-2. Assign all unicode characters into one of 4 sets: lower case
- letters, upper case letters, numbers, and all other characters.
-3. Iterate through characters of string, introducing splits
- between adjacent characters that belong to different sets.
-4. Iterate through array of split strings, and if a given string
- is upper case:
- * if subsequent string is lower case:
- * move last character of upper case string to beginning of
- lower case string
-
-## Install
-
-```bash
-go get github.com/fatih/camelcase
-```
-
-## Usage and examples
-
-```go
-splitted := camelcase.Split("GolangPackage")
-
-fmt.Println(splitted[0], splitted[1]) // prints: "Golang", "Package"
-```
-
-Both lower camel case and upper camel case are supported. For more info please
-check: [http://en.wikipedia.org/wiki/CamelCase](http://en.wikipedia.org/wiki/CamelCase)
-
-Below are some example cases:
-
-```
-"" => []
-"lowercase" => ["lowercase"]
-"Class" => ["Class"]
-"MyClass" => ["My", "Class"]
-"MyC" => ["My", "C"]
-"HTML" => ["HTML"]
-"PDFLoader" => ["PDF", "Loader"]
-"AString" => ["A", "String"]
-"SimpleXMLParser" => ["Simple", "XML", "Parser"]
-"vimRPCPlugin" => ["vim", "RPC", "Plugin"]
-"GL11Version" => ["GL", "11", "Version"]
-"99Bottles" => ["99", "Bottles"]
-"May5" => ["May", "5"]
-"BFG9000" => ["BFG", "9000"]
-"BöseÜberraschung" => ["Böse", "Überraschung"]
-"Two spaces" => ["Two", " ", "spaces"]
-"BadUTF8\xe2\xe2\xa1" => ["BadUTF8\xe2\xe2\xa1"]
-```
diff --git a/vendor/github.com/fatih/camelcase/camelcase.go b/vendor/github.com/fatih/camelcase/camelcase.go
deleted file mode 100644
index 02160c9a4..000000000
--- a/vendor/github.com/fatih/camelcase/camelcase.go
+++ /dev/null
@@ -1,90 +0,0 @@
-// Package camelcase is a micro package to split the words of a camelcase type
-// string into a slice of words.
-package camelcase
-
-import (
- "unicode"
- "unicode/utf8"
-)
-
-// Split splits the camelcase word and returns a list of words. It also
-// supports digits. Both lower camel case and upper camel case are supported.
-// For more info please check: http://en.wikipedia.org/wiki/CamelCase
-//
-// Examples
-//
-// "" => [""]
-// "lowercase" => ["lowercase"]
-// "Class" => ["Class"]
-// "MyClass" => ["My", "Class"]
-// "MyC" => ["My", "C"]
-// "HTML" => ["HTML"]
-// "PDFLoader" => ["PDF", "Loader"]
-// "AString" => ["A", "String"]
-// "SimpleXMLParser" => ["Simple", "XML", "Parser"]
-// "vimRPCPlugin" => ["vim", "RPC", "Plugin"]
-// "GL11Version" => ["GL", "11", "Version"]
-// "99Bottles" => ["99", "Bottles"]
-// "May5" => ["May", "5"]
-// "BFG9000" => ["BFG", "9000"]
-// "BöseÜberraschung" => ["Böse", "Überraschung"]
-// "Two spaces" => ["Two", " ", "spaces"]
-// "BadUTF8\xe2\xe2\xa1" => ["BadUTF8\xe2\xe2\xa1"]
-//
-// Splitting rules
-//
-// 1) If string is not valid UTF-8, return it without splitting as
-// single item array.
-// 2) Assign all unicode characters into one of 4 sets: lower case
-// letters, upper case letters, numbers, and all other characters.
-// 3) Iterate through characters of string, introducing splits
-// between adjacent characters that belong to different sets.
-// 4) Iterate through array of split strings, and if a given string
-// is upper case:
-// if subsequent string is lower case:
-// move last character of upper case string to beginning of
-// lower case string
-func Split(src string) (entries []string) {
- // don't split invalid utf8
- if !utf8.ValidString(src) {
- return []string{src}
- }
- entries = []string{}
- var runes [][]rune
- lastClass := 0
- class := 0
- // split into fields based on class of unicode character
- for _, r := range src {
- switch true {
- case unicode.IsLower(r):
- class = 1
- case unicode.IsUpper(r):
- class = 2
- case unicode.IsDigit(r):
- class = 3
- default:
- class = 4
- }
- if class == lastClass {
- runes[len(runes)-1] = append(runes[len(runes)-1], r)
- } else {
- runes = append(runes, []rune{r})
- }
- lastClass = class
- }
- // handle upper case -> lower case sequences, e.g.
- // "PDFL", "oader" -> "PDF", "Loader"
- for i := 0; i < len(runes)-1; i++ {
- if unicode.IsUpper(runes[i][0]) && unicode.IsLower(runes[i+1][0]) {
- runes[i+1] = append([]rune{runes[i][len(runes[i])-1]}, runes[i+1]...)
- runes[i] = runes[i][:len(runes[i])-1]
- }
- }
- // construct []string from results
- for _, s := range runes {
- if len(s) > 0 {
- entries = append(entries, string(s))
- }
- }
- return
-}
diff --git a/vendor/github.com/fsnotify/fsnotify/.editorconfig b/vendor/github.com/fsnotify/fsnotify/.editorconfig
index ba49e3c23..fad895851 100644
--- a/vendor/github.com/fsnotify/fsnotify/.editorconfig
+++ b/vendor/github.com/fsnotify/fsnotify/.editorconfig
@@ -1,5 +1,12 @@
root = true
-[*]
+[*.go]
indent_style = tab
indent_size = 4
+insert_final_newline = true
+
+[*.{yml,yaml}]
+indent_style = space
+indent_size = 2
+insert_final_newline = true
+trim_trailing_whitespace = true
diff --git a/vendor/github.com/fsnotify/fsnotify/.gitattributes b/vendor/github.com/fsnotify/fsnotify/.gitattributes
new file mode 100644
index 000000000..32f1001be
--- /dev/null
+++ b/vendor/github.com/fsnotify/fsnotify/.gitattributes
@@ -0,0 +1 @@
+go.sum linguist-generated
diff --git a/vendor/github.com/fsnotify/fsnotify/.travis.yml b/vendor/github.com/fsnotify/fsnotify/.travis.yml
index 981d1bb81..a9c30165c 100644
--- a/vendor/github.com/fsnotify/fsnotify/.travis.yml
+++ b/vendor/github.com/fsnotify/fsnotify/.travis.yml
@@ -2,29 +2,35 @@ sudo: false
language: go
go:
- - 1.8.x
- - 1.9.x
- - tip
+ - "stable"
+ - "1.11.x"
+ - "1.10.x"
+ - "1.9.x"
matrix:
+ include:
+ - go: "stable"
+ env: GOLINT=true
allow_failures:
- go: tip
fast_finish: true
-before_script:
- - go get -u github.com/golang/lint/golint
+
+before_install:
+ - if [ ! -z "${GOLINT}" ]; then go get -u golang.org/x/lint/golint; fi
script:
- - go test -v --race ./...
+ - go test --race ./...
after_script:
- test -z "$(gofmt -s -l -w . | tee /dev/stderr)"
- - test -z "$(golint ./... | tee /dev/stderr)"
+ - if [ ! -z "${GOLINT}" ]; then echo running golint; golint --set_exit_status ./...; else echo skipping golint; fi
- go vet ./...
os:
- linux
- osx
+ - windows
notifications:
email: false
diff --git a/vendor/github.com/fsnotify/fsnotify/LICENSE b/vendor/github.com/fsnotify/fsnotify/LICENSE
index f21e54080..e180c8fb0 100644
--- a/vendor/github.com/fsnotify/fsnotify/LICENSE
+++ b/vendor/github.com/fsnotify/fsnotify/LICENSE
@@ -1,5 +1,5 @@
Copyright (c) 2012 The Go Authors. All rights reserved.
-Copyright (c) 2012 fsnotify Authors. All rights reserved.
+Copyright (c) 2012-2019 fsnotify Authors. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
diff --git a/vendor/github.com/fsnotify/fsnotify/README.md b/vendor/github.com/fsnotify/fsnotify/README.md
index 399320741..b2629e522 100644
--- a/vendor/github.com/fsnotify/fsnotify/README.md
+++ b/vendor/github.com/fsnotify/fsnotify/README.md
@@ -10,16 +10,16 @@ go get -u golang.org/x/sys/...
Cross platform: Windows, Linux, BSD and macOS.
-|Adapter |OS |Status |
-|----------|----------|----------|
-|inotify |Linux 2.6.27 or later, Android\*|Supported [![Build Status](https://travis-ci.org/fsnotify/fsnotify.svg?branch=master)](https://travis-ci.org/fsnotify/fsnotify)|
-|kqueue |BSD, macOS, iOS\*|Supported [![Build Status](https://travis-ci.org/fsnotify/fsnotify.svg?branch=master)](https://travis-ci.org/fsnotify/fsnotify)|
-|ReadDirectoryChangesW|Windows|Supported [![Build status](https://ci.appveyor.com/api/projects/status/ivwjubaih4r0udeh/branch/master?svg=true)](https://ci.appveyor.com/project/NathanYoungman/fsnotify/branch/master)|
-|FSEvents |macOS |[Planned](https://github.com/fsnotify/fsnotify/issues/11)|
-|FEN |Solaris 11 |[In Progress](https://github.com/fsnotify/fsnotify/issues/12)|
-|fanotify |Linux 2.6.37+ | |
-|USN Journals |Windows |[Maybe](https://github.com/fsnotify/fsnotify/issues/53)|
-|Polling |*All* |[Maybe](https://github.com/fsnotify/fsnotify/issues/9)|
+| Adapter | OS | Status |
+| --------------------- | -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
+| inotify | Linux 2.6.27 or later, Android\* | Supported [![Build Status](https://travis-ci.org/fsnotify/fsnotify.svg?branch=master)](https://travis-ci.org/fsnotify/fsnotify) |
+| kqueue | BSD, macOS, iOS\* | Supported [![Build Status](https://travis-ci.org/fsnotify/fsnotify.svg?branch=master)](https://travis-ci.org/fsnotify/fsnotify) |
+| ReadDirectoryChangesW | Windows | Supported [![Build Status](https://travis-ci.org/fsnotify/fsnotify.svg?branch=master)](https://travis-ci.org/fsnotify/fsnotify) |
+| FSEvents | macOS | [Planned](https://github.com/fsnotify/fsnotify/issues/11) |
+| FEN | Solaris 11 | [In Progress](https://github.com/fsnotify/fsnotify/issues/12) |
+| fanotify | Linux 2.6.37+ | [Planned](https://github.com/fsnotify/fsnotify/issues/114) |
+| USN Journals | Windows | [Maybe](https://github.com/fsnotify/fsnotify/issues/53) |
+| Polling | *All* | [Maybe](https://github.com/fsnotify/fsnotify/issues/9) |
\* Android and iOS are untested.
@@ -33,6 +33,53 @@ All [releases](https://github.com/fsnotify/fsnotify/releases) are tagged based o
Go 1.6 supports dependencies located in the `vendor/` folder. Unless you are creating a library, it is recommended that you copy fsnotify into `vendor/github.com/fsnotify/fsnotify` within your project, and likewise for `golang.org/x/sys`.
+## Usage
+
+```go
+package main
+
+import (
+ "log"
+
+ "github.com/fsnotify/fsnotify"
+)
+
+func main() {
+ watcher, err := fsnotify.NewWatcher()
+ if err != nil {
+ log.Fatal(err)
+ }
+ defer watcher.Close()
+
+ done := make(chan bool)
+ go func() {
+ for {
+ select {
+ case event, ok := <-watcher.Events:
+ if !ok {
+ return
+ }
+ log.Println("event:", event)
+ if event.Op&fsnotify.Write == fsnotify.Write {
+ log.Println("modified file:", event.Name)
+ }
+ case err, ok := <-watcher.Errors:
+ if !ok {
+ return
+ }
+ log.Println("error:", err)
+ }
+ }
+ }()
+
+ err = watcher.Add("/tmp/foo")
+ if err != nil {
+ log.Fatal(err)
+ }
+ <-done
+}
+```
+
## Contributing
Please refer to [CONTRIBUTING][] before opening an issue or pull request.
@@ -65,6 +112,10 @@ There are OS-specific limits as to how many watches can be created:
* Linux: /proc/sys/fs/inotify/max_user_watches contains the limit, reaching this limit results in a "no space left on device" error.
* BSD / OSX: sysctl variables "kern.maxfiles" and "kern.maxfilesperproc", reaching these limits results in a "too many open files" error.
+**Why don't notifications work with NFS filesystems or filesystem in userspace (FUSE)?**
+
+fsnotify requires support from underlying OS to work. The current NFS protocol does not provide network level support for file notifications.
+
[#62]: https://github.com/howeyc/fsnotify/issues/62
[#18]: https://github.com/fsnotify/fsnotify/issues/18
[#11]: https://github.com/fsnotify/fsnotify/issues/11
diff --git a/vendor/github.com/fsnotify/fsnotify/fsnotify.go b/vendor/github.com/fsnotify/fsnotify/fsnotify.go
index 190bf0de5..89cab046d 100644
--- a/vendor/github.com/fsnotify/fsnotify/fsnotify.go
+++ b/vendor/github.com/fsnotify/fsnotify/fsnotify.go
@@ -63,4 +63,6 @@ func (e Event) String() string {
}
// Common errors that can be reported by a watcher
-var ErrEventOverflow = errors.New("fsnotify queue overflow")
+var (
+ ErrEventOverflow = errors.New("fsnotify queue overflow")
+)
diff --git a/vendor/github.com/fsnotify/fsnotify/go.mod b/vendor/github.com/fsnotify/fsnotify/go.mod
new file mode 100644
index 000000000..ff11e13f2
--- /dev/null
+++ b/vendor/github.com/fsnotify/fsnotify/go.mod
@@ -0,0 +1,5 @@
+module github.com/fsnotify/fsnotify
+
+go 1.13
+
+require golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9
diff --git a/vendor/github.com/fsnotify/fsnotify/go.sum b/vendor/github.com/fsnotify/fsnotify/go.sum
new file mode 100644
index 000000000..f60af9855
--- /dev/null
+++ b/vendor/github.com/fsnotify/fsnotify/go.sum
@@ -0,0 +1,2 @@
+golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9 h1:L2auWcuQIvxz9xSEqzESnV/QN/gNRXNApHi3fYwl2w0=
+golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
diff --git a/vendor/github.com/fsnotify/fsnotify/inotify_poller.go b/vendor/github.com/fsnotify/fsnotify/inotify_poller.go
index cc7db4b22..b33f2b4d4 100644
--- a/vendor/github.com/fsnotify/fsnotify/inotify_poller.go
+++ b/vendor/github.com/fsnotify/fsnotify/inotify_poller.go
@@ -40,12 +40,12 @@ func newFdPoller(fd int) (*fdPoller, error) {
poller.fd = fd
// Create epoll fd
- poller.epfd, errno = unix.EpollCreate1(0)
+ poller.epfd, errno = unix.EpollCreate1(unix.EPOLL_CLOEXEC)
if poller.epfd == -1 {
return nil, errno
}
// Create pipe; pipe[0] is the read end, pipe[1] the write end.
- errno = unix.Pipe2(poller.pipe[:], unix.O_NONBLOCK)
+ errno = unix.Pipe2(poller.pipe[:], unix.O_NONBLOCK|unix.O_CLOEXEC)
if errno != nil {
return nil, errno
}
diff --git a/vendor/github.com/fsnotify/fsnotify/open_mode_bsd.go b/vendor/github.com/fsnotify/fsnotify/open_mode_bsd.go
index 7d8de1451..2306c4620 100644
--- a/vendor/github.com/fsnotify/fsnotify/open_mode_bsd.go
+++ b/vendor/github.com/fsnotify/fsnotify/open_mode_bsd.go
@@ -8,4 +8,4 @@ package fsnotify
import "golang.org/x/sys/unix"
-const openMode = unix.O_NONBLOCK | unix.O_RDONLY
+const openMode = unix.O_NONBLOCK | unix.O_RDONLY | unix.O_CLOEXEC
diff --git a/vendor/github.com/fsnotify/fsnotify/open_mode_darwin.go b/vendor/github.com/fsnotify/fsnotify/open_mode_darwin.go
index 9139e1716..870c4d6d1 100644
--- a/vendor/github.com/fsnotify/fsnotify/open_mode_darwin.go
+++ b/vendor/github.com/fsnotify/fsnotify/open_mode_darwin.go
@@ -9,4 +9,4 @@ package fsnotify
import "golang.org/x/sys/unix"
// note: this constant is not defined on BSD
-const openMode = unix.O_EVTONLY
+const openMode = unix.O_EVTONLY | unix.O_CLOEXEC
diff --git a/vendor/github.com/fsouza/go-dockerclient/.golangci.yaml b/vendor/github.com/fsouza/go-dockerclient/.golangci.yaml
index aa3ab39e5..3a21b76f7 100644
--- a/vendor/github.com/fsouza/go-dockerclient/.golangci.yaml
+++ b/vendor/github.com/fsouza/go-dockerclient/.golangci.yaml
@@ -25,5 +25,6 @@ linters:
- gochecknoglobals
- gocognit
- goconst
+ - gomnd
- lll
- wsl
diff --git a/vendor/github.com/fsouza/go-dockerclient/.travis.yml b/vendor/github.com/fsouza/go-dockerclient/.travis.yml
index 060f9e6a8..dbd76b175 100644
--- a/vendor/github.com/fsouza/go-dockerclient/.travis.yml
+++ b/vendor/github.com/fsouza/go-dockerclient/.travis.yml
@@ -3,6 +3,7 @@ language: go
go:
- 1.12.x
- 1.13.x
+ - 1.14rc1
os:
- linux
- osx
diff --git a/vendor/github.com/fsouza/go-dockerclient/AUTHORS b/vendor/github.com/fsouza/go-dockerclient/AUTHORS
index 663410f95..08f89afde 100644
--- a/vendor/github.com/fsouza/go-dockerclient/AUTHORS
+++ b/vendor/github.com/fsouza/go-dockerclient/AUTHORS
@@ -139,6 +139,7 @@ Michal Fojtik
Mike Dillon
Mrunal Patel
Nate Jones
+Nathan Pemberton
Nguyen Sy Thanh Son
Nicholas Van Wiggeren
Nick Ethier
diff --git a/vendor/github.com/fsouza/go-dockerclient/LICENSE b/vendor/github.com/fsouza/go-dockerclient/LICENSE
index 80d56fc05..7a70a8c40 100644
--- a/vendor/github.com/fsouza/go-dockerclient/LICENSE
+++ b/vendor/github.com/fsouza/go-dockerclient/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2013-2019, go-dockerclient authors
+Copyright (c) 2013-2020, go-dockerclient authors
All rights reserved.
Redistribution and use in source and binary forms, with or without
diff --git a/vendor/github.com/fsouza/go-dockerclient/README.md b/vendor/github.com/fsouza/go-dockerclient/README.md
index f4ad8ca62..d1128335d 100644
--- a/vendor/github.com/fsouza/go-dockerclient/README.md
+++ b/vendor/github.com/fsouza/go-dockerclient/README.md
@@ -2,7 +2,7 @@
[![Travis Build Status](https://travis-ci.com/fsouza/go-dockerclient.svg?branch=master)](https://travis-ci.com/fsouza/go-dockerclient)
[![AppVeyor Build status](https://ci.appveyor.com/api/projects/status/4yusq1f9dqbicobt?svg=true)](https://ci.appveyor.com/project/fsouza/go-dockerclient)
-[![GoDoc](https://img.shields.io/badge/api-Godoc-blue.svg?style=flat-square)](https://godoc.org/github.com/fsouza/go-dockerclient)
+[![GoDoc](https://img.shields.io/badge/api-Godoc-blue.svg?style=flat-square)](https://pkg.go.dev/github.com/docker/docker/api/types?tab=doc#AuthConfig)
This package presents a client for the Docker remote API. It also provides
support for the extensions in the [Swarm API](https://docs.docker.com/swarm/swarm-api/).
diff --git a/vendor/github.com/fsouza/go-dockerclient/appveyor.yml b/vendor/github.com/fsouza/go-dockerclient/appveyor.yml
index e1574cfc2..f36478a5d 100644
--- a/vendor/github.com/fsouza/go-dockerclient/appveyor.yml
+++ b/vendor/github.com/fsouza/go-dockerclient/appveyor.yml
@@ -7,8 +7,9 @@ environment:
GOPROXY: https://proxy.golang.org
GO111MODULE: on
matrix:
- - GOVERSION: "1.12.13"
- - GOVERSION: "1.13.4"
+ - GOVERSION: "1.12.17"
+ - GOVERSION: "1.13.8"
+ - GOVERSION: "1.14rc1"
install:
- choco install make
- set PATH=%GOPATH%\bin;c:\go\bin;%PATH%
diff --git a/vendor/github.com/fsouza/go-dockerclient/auth.go b/vendor/github.com/fsouza/go-dockerclient/auth.go
index eb1a31716..cae2a020f 100644
--- a/vendor/github.com/fsouza/go-dockerclient/auth.go
+++ b/vendor/github.com/fsouza/go-dockerclient/auth.go
@@ -30,7 +30,7 @@ type AuthConfiguration struct {
ServerAddress string `json:"serveraddress,omitempty"`
// IdentityToken can be supplied with the identitytoken response of the AuthCheck call
- // see https://godoc.org/github.com/docker/docker/api/types#AuthConfig
+ // see https://pkg.go.dev/github.com/docker/docker/api/types?tab=doc#AuthConfig
// It can be used in place of password not in conjunction with it
IdentityToken string `json:"identitytoken,omitempty"`
@@ -170,9 +170,14 @@ func authConfigs(confs map[string]dockerConfig) (*AuthConfigurations, error) {
if conf.Auth == "" {
continue
}
+
+ // support both padded and unpadded encoding
data, err := base64.StdEncoding.DecodeString(conf.Auth)
if err != nil {
- return nil, err
+ data, err = base64.StdEncoding.WithPadding(base64.NoPadding).DecodeString(conf.Auth)
+ }
+ if err != nil {
+ return nil, errors.New("error decoding plaintext credentials")
}
userpass := strings.SplitN(string(data), ":", 2)
diff --git a/vendor/github.com/fsouza/go-dockerclient/container.go b/vendor/github.com/fsouza/go-dockerclient/container.go
index f6bfb59dc..309955fd5 100644
--- a/vendor/github.com/fsouza/go-dockerclient/container.go
+++ b/vendor/github.com/fsouza/go-dockerclient/container.go
@@ -730,6 +730,15 @@ type Device struct {
CgroupPermissions string `json:"CgroupPermissions,omitempty" yaml:"CgroupPermissions,omitempty" toml:"CgroupPermissions,omitempty"`
}
+// A list of requests for devices to be sent to device drivers
+type DeviceRequest struct {
+ Driver string `json:"Driver,omitempty" yaml:"Driver,omitempty" toml:"Driver,omitempty"`
+ Count int `json:"Count,omitempty" yaml:"Count,omitempty" toml:"Count,omitempty"`
+ DeviceIDs []string `json:"DeviceIDs,omitempty" yaml:"DeviceIDs,omitempty" toml:"DeviceIDs,omitempty"`
+ Capabilities [][]string `json:"Capabilities,omitempty" yaml:"Capabilities,omitempty" toml:"Capabilities,omitempty"`
+ Options map[string]string `json:"Options,omitempty" yaml:"Options,omitempty" toml:"Options,omitempty"`
+}
+
// BlockWeight represents a relative device weight for an individual device inside
// of a container
type BlockWeight struct {
@@ -771,6 +780,7 @@ type HostConfig struct {
RestartPolicy RestartPolicy `json:"RestartPolicy,omitempty" yaml:"RestartPolicy,omitempty" toml:"RestartPolicy,omitempty"`
Devices []Device `json:"Devices,omitempty" yaml:"Devices,omitempty" toml:"Devices,omitempty"`
DeviceCgroupRules []string `json:"DeviceCgroupRules,omitempty" yaml:"DeviceCgroupRules,omitempty" toml:"DeviceCgroupRules,omitempty"`
+ DeviceRequests []DeviceRequest `json:"DeviceRequests,omitempty" yaml:"DeviceRequests,omitempty" toml:"DeviceRequests,omitempty"`
LogConfig LogConfig `json:"LogConfig,omitempty" yaml:"LogConfig,omitempty" toml:"LogConfig,omitempty"`
SecurityOpt []string `json:"SecurityOpt,omitempty" yaml:"SecurityOpt,omitempty" toml:"SecurityOpt,omitempty"`
CgroupnsMode string `json:"CgroupnsMode,omitempty" yaml:"CgroupnsMode,omitempty" toml:"CgroupnsMode,omitempty"` // v1.40+
@@ -788,6 +798,7 @@ type HostConfig struct {
CPUPeriod int64 `json:"CpuPeriod,omitempty" yaml:"CpuPeriod,omitempty" toml:"CpuPeriod,omitempty"`
CPURealtimePeriod int64 `json:"CpuRealtimePeriod,omitempty" yaml:"CpuRealtimePeriod,omitempty" toml:"CpuRealtimePeriod,omitempty"`
CPURealtimeRuntime int64 `json:"CpuRealtimeRuntime,omitempty" yaml:"CpuRealtimeRuntime,omitempty" toml:"CpuRealtimeRuntime,omitempty"`
+ NanoCPUs int64 `json:"NanoCpus,omitempty" yaml:"NanoCpus,omitempty" toml:"NanoCpus,omitempty"`
BlkioWeight int64 `json:"BlkioWeight,omitempty" yaml:"BlkioWeight,omitempty" toml:"BlkioWeight,omitempty"`
BlkioWeightDevice []BlockWeight `json:"BlkioWeightDevice,omitempty" yaml:"BlkioWeightDevice,omitempty" toml:"BlkioWeightDevice,omitempty"`
BlkioDeviceReadBps []BlockLimit `json:"BlkioDeviceReadBps,omitempty" yaml:"BlkioDeviceReadBps,omitempty" toml:"BlkioDeviceReadBps,omitempty"`
diff --git a/vendor/github.com/fsouza/go-dockerclient/go.mod b/vendor/github.com/fsouza/go-dockerclient/go.mod
index 7bb88972c..37ddd03c2 100644
--- a/vendor/github.com/fsouza/go-dockerclient/go.mod
+++ b/vendor/github.com/fsouza/go-dockerclient/go.mod
@@ -11,12 +11,12 @@ require (
github.com/docker/docker v1.4.2-0.20191101170500-ac7306503d23
github.com/docker/go-connections v0.4.0 // indirect
github.com/docker/go-units v0.4.0
- github.com/google/go-cmp v0.3.1
- github.com/gorilla/mux v1.7.3
+ github.com/google/go-cmp v0.4.0
+ github.com/gorilla/mux v1.7.4
github.com/morikuni/aec v0.0.0-20170113033406-39771216ff4c // indirect
github.com/opencontainers/go-digest v1.0.0-rc1 // indirect
github.com/opencontainers/image-spec v1.0.1 // indirect
github.com/opencontainers/runc v0.1.1 // indirect
- golang.org/x/crypto v0.0.0-20190927123631-a832865fa7ad
+ golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975
google.golang.org/grpc v1.22.0 // indirect
)
diff --git a/vendor/github.com/fsouza/go-dockerclient/go.sum b/vendor/github.com/fsouza/go-dockerclient/go.sum
index ce78fee7a..6fcd9b008 100644
--- a/vendor/github.com/fsouza/go-dockerclient/go.sum
+++ b/vendor/github.com/fsouza/go-dockerclient/go.sum
@@ -41,10 +41,10 @@ github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
-github.com/google/go-cmp v0.3.1 h1:Xye71clBPdm5HgqGwUkwhbynsUJZhDbS20FvLhQ2izg=
-github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
-github.com/gorilla/mux v1.7.3 h1:gnP5JzjVOuiZD07fKKToCAOjS0yOpj/qPETTXCCS6hw=
-github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
+github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
+github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/gorilla/mux v1.7.4 h1:VuZ8uybHlWmqV03+zRzdwKL4tUnIp1MAQtp1mIFE1bc=
+github.com/gorilla/mux v1.7.4/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
github.com/hashicorp/errwrap v0.0.0-20141028054710-7554cd9344ce/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-multierror v0.0.0-20161216184304-ed905158d874/go.mod h1:JMRHfdO9jKNzS/+BTlxCjKNQHg/jZAft8U7LloJvN7I=
github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU=
@@ -84,8 +84,8 @@ go.opencensus.io v0.22.0 h1:C9hSCOW830chIVkdja34wa6Ky+IzWllkUinR+BtRZd4=
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
-golang.org/x/crypto v0.0.0-20190927123631-a832865fa7ad h1:5E5raQxcv+6CZ11RrBYQe5WRbUIWpScjh0kvHZkZIrQ=
-golang.org/x/crypto v0.0.0-20190927123631-a832865fa7ad/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975 h1:/Tl7pH94bvbAAHBdZJT947M/+gp0+CqQXDtMRC0fseo=
+golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
@@ -119,6 +119,8 @@ golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGm
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
+golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
+golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
diff --git a/vendor/github.com/fsouza/go-dockerclient/swarm_service.go b/vendor/github.com/fsouza/go-dockerclient/swarm_service.go
index cedbe41e3..4accb2cb8 100644
--- a/vendor/github.com/fsouza/go-dockerclient/swarm_service.go
+++ b/vendor/github.com/fsouza/go-dockerclient/swarm_service.go
@@ -147,6 +147,7 @@ func (c *Client) InspectService(id string) (*swarm.Service, error) {
// See https://goo.gl/DwvNMd for more details.
type ListServicesOptions struct {
Filters map[string][]string
+ Status bool
Context context.Context
}
diff --git a/vendor/github.com/fsouza/go-dockerclient/tls.go b/vendor/github.com/fsouza/go-dockerclient/tls.go
index 08e7f8ec2..8a76f0dbf 100644
--- a/vendor/github.com/fsouza/go-dockerclient/tls.go
+++ b/vendor/github.com/fsouza/go-dockerclient/tls.go
@@ -106,7 +106,6 @@ func copyTLSConfig(cfg *tls.Config) *tls.Config {
InsecureSkipVerify: cfg.InsecureSkipVerify, //nolint:gosec
MaxVersion: cfg.MaxVersion,
MinVersion: cfg.MinVersion,
- NameToCertificate: cfg.NameToCertificate,
NextProtos: cfg.NextProtos,
PreferServerCipherSuites: cfg.PreferServerCipherSuites,
Rand: cfg.Rand,
diff --git a/vendor/github.com/godbus/dbus/.travis.yml b/vendor/github.com/godbus/dbus/.travis.yml
deleted file mode 100644
index 9cd57f432..000000000
--- a/vendor/github.com/godbus/dbus/.travis.yml
+++ /dev/null
@@ -1,46 +0,0 @@
-dist: precise
-language: go
-go_import_path: github.com/godbus/dbus
-sudo: true
-
-go:
- - 1.7.3
- - 1.8.7
- - 1.9.5
- - 1.10.1
- - tip
-
-env:
- global:
- matrix:
- - TARGET=amd64
- - TARGET=arm64
- - TARGET=arm
- - TARGET=386
- - TARGET=ppc64le
-
-matrix:
- fast_finish: true
- allow_failures:
- - go: tip
- exclude:
- - go: tip
- env: TARGET=arm
- - go: tip
- env: TARGET=arm64
- - go: tip
- env: TARGET=386
- - go: tip
- env: TARGET=ppc64le
-
-addons:
- apt:
- packages:
- - dbus
- - dbus-x11
-
-before_install:
-
-script:
- - go test -v -race ./... # Run all the tests with the race detector enabled
- - go vet ./... # go vet is the official Go static analyzer
diff --git a/vendor/github.com/godbus/dbus/go.mod b/vendor/github.com/godbus/dbus/go.mod
deleted file mode 100644
index 57014e4ac..000000000
--- a/vendor/github.com/godbus/dbus/go.mod
+++ /dev/null
@@ -1,3 +0,0 @@
-module github.com/godbus/dbus
-
-go 1.12
diff --git a/vendor/github.com/godbus/dbus/v5/.travis.yml b/vendor/github.com/godbus/dbus/v5/.travis.yml
new file mode 100644
index 000000000..dd6767204
--- /dev/null
+++ b/vendor/github.com/godbus/dbus/v5/.travis.yml
@@ -0,0 +1,50 @@
+dist: bionic
+language: go
+go_import_path: github.com/godbus/dbus
+
+go:
+ - 1.11.x
+ - 1.12.x
+ - 1.13.x
+ - tip
+
+matrix:
+ fast_finish: true
+ allow_failures:
+ - go: tip
+
+addons:
+ apt:
+ packages:
+ - dbus
+ - dbus-x11
+
+before_install:
+ - export GO111MODULE=on
+
+script:
+ - go test -v -race -mod=readonly ./... # Run all the tests with the race detector enabled
+ - go vet ./... # go vet is the official Go static analyzer
+
+jobs:
+ include:
+ # The build matrix doesn't cover build stages, so manually expand
+ # the jobs with anchors
+ - &multiarch
+ stage: "Multiarch Test"
+ go: 1.11.x
+ env: TARGETS="386 arm arm64 ppc64le"
+ before_install:
+ - docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
+ script:
+ - |
+ set -e
+ for target in $TARGETS; do
+ printf "\e[1mRunning test suite under ${target}.\e[0m\n"
+ GOARCH="$target" go test -v ./...
+ printf "\n\n"
+ done
+ - <<: *multiarch
+ go: 1.12.x
+ - <<: *multiarch
+ go: 1.13.x
diff --git a/vendor/github.com/godbus/dbus/CONTRIBUTING.md b/vendor/github.com/godbus/dbus/v5/CONTRIBUTING.md
index c88f9b2bd..c88f9b2bd 100644
--- a/vendor/github.com/godbus/dbus/CONTRIBUTING.md
+++ b/vendor/github.com/godbus/dbus/v5/CONTRIBUTING.md
diff --git a/vendor/github.com/godbus/dbus/LICENSE b/vendor/github.com/godbus/dbus/v5/LICENSE
index 670d88fca..670d88fca 100644
--- a/vendor/github.com/godbus/dbus/LICENSE
+++ b/vendor/github.com/godbus/dbus/v5/LICENSE
diff --git a/vendor/github.com/godbus/dbus/MAINTAINERS b/vendor/github.com/godbus/dbus/v5/MAINTAINERS
index 27618c9cd..27618c9cd 100644
--- a/vendor/github.com/godbus/dbus/MAINTAINERS
+++ b/vendor/github.com/godbus/dbus/v5/MAINTAINERS
diff --git a/vendor/github.com/godbus/dbus/README.markdown b/vendor/github.com/godbus/dbus/v5/README.markdown
index fd2964875..fd2964875 100644
--- a/vendor/github.com/godbus/dbus/README.markdown
+++ b/vendor/github.com/godbus/dbus/v5/README.markdown
diff --git a/vendor/github.com/godbus/dbus/auth.go b/vendor/github.com/godbus/dbus/v5/auth.go
index b0dcb54e6..31abac629 100644
--- a/vendor/github.com/godbus/dbus/auth.go
+++ b/vendor/github.com/godbus/dbus/v5/auth.go
@@ -77,7 +77,7 @@ func (conn *Conn) Auth(methods []Auth) error {
for _, m := range methods {
if name, data, status := m.FirstData(); bytes.Equal(v, name) {
var ok bool
- err = authWriteLine(conn.transport, []byte("AUTH"), []byte(v), data)
+ err = authWriteLine(conn.transport, []byte("AUTH"), v, data)
if err != nil {
return err
}
@@ -127,7 +127,7 @@ func (conn *Conn) Auth(methods []Auth) error {
// tryAuth tries to authenticate with m as the mechanism, using state as the
// initial authState and in for reading input. It returns (nil, true) on
// success, (nil, false) on a REJECTED and (someErr, false) if some other
-// error occured.
+// error occurred.
func (conn *Conn) tryAuth(m Auth, state authState, in *bufio.Reader) (error, bool) {
for {
s, err := authReadLine(in)
diff --git a/vendor/github.com/godbus/dbus/auth_anonymous.go b/vendor/github.com/godbus/dbus/v5/auth_anonymous.go
index 75f3ad34d..75f3ad34d 100644
--- a/vendor/github.com/godbus/dbus/auth_anonymous.go
+++ b/vendor/github.com/godbus/dbus/v5/auth_anonymous.go
diff --git a/vendor/github.com/godbus/dbus/auth_external.go b/vendor/github.com/godbus/dbus/v5/auth_external.go
index 7e376d3ef..7e376d3ef 100644
--- a/vendor/github.com/godbus/dbus/auth_external.go
+++ b/vendor/github.com/godbus/dbus/v5/auth_external.go
diff --git a/vendor/github.com/godbus/dbus/auth_sha1.go b/vendor/github.com/godbus/dbus/v5/auth_sha1.go
index df15b4611..80286700b 100644
--- a/vendor/github.com/godbus/dbus/auth_sha1.go
+++ b/vendor/github.com/godbus/dbus/v5/auth_sha1.go
@@ -60,7 +60,7 @@ func (a authCookieSha1) HandleData(data []byte) ([]byte, AuthStatus) {
// getCookie searches for the cookie identified by id in context and returns
// the cookie content or nil. (Since HandleData can't return a specific error,
-// but only whether an error occured, this function also doesn't bother to
+// but only whether an error occurred, this function also doesn't bother to
// return an error.)
func (a authCookieSha1) getCookie(context, id []byte) []byte {
file, err := os.Open(a.home + "/.dbus-keyrings/" + string(context))
diff --git a/vendor/github.com/godbus/dbus/call.go b/vendor/github.com/godbus/dbus/v5/call.go
index 2cb189012..2cb189012 100644
--- a/vendor/github.com/godbus/dbus/call.go
+++ b/vendor/github.com/godbus/dbus/v5/call.go
diff --git a/vendor/github.com/godbus/dbus/conn.go b/vendor/github.com/godbus/dbus/v5/conn.go
index 9dced0cc4..b55bc99c8 100644
--- a/vendor/github.com/godbus/dbus/conn.go
+++ b/vendor/github.com/godbus/dbus/v5/conn.go
@@ -5,7 +5,6 @@ import (
"errors"
"io"
"os"
- "reflect"
"strings"
"sync"
)
@@ -31,6 +30,12 @@ var ErrClosed = errors.New("dbus: connection closed by user")
type Conn struct {
transport
+ ctx context.Context
+ cancelCtx context.CancelFunc
+
+ closeOnce sync.Once
+ closeErr error
+
busObj BusObject
unixFD bool
uuid string
@@ -38,6 +43,8 @@ type Conn struct {
handler Handler
signalHandler SignalHandler
serialGen SerialGenerator
+ inInt Interceptor
+ outInt Interceptor
names *nameTracker
calls *callTracker
@@ -190,6 +197,33 @@ func WithSerialGenerator(gen SerialGenerator) ConnOption {
}
}
+// Interceptor intercepts incoming and outgoing messages.
+type Interceptor func(msg *Message)
+
+// WithIncomingInterceptor sets the given interceptor for incoming messages.
+func WithIncomingInterceptor(interceptor Interceptor) ConnOption {
+ return func(conn *Conn) error {
+ conn.inInt = interceptor
+ return nil
+ }
+}
+
+// WithOutgoingInterceptor sets the given interceptor for outgoing messages.
+func WithOutgoingInterceptor(interceptor Interceptor) ConnOption {
+ return func(conn *Conn) error {
+ conn.outInt = interceptor
+ return nil
+ }
+}
+
+// WithContext overrides the default context for the connection.
+func WithContext(ctx context.Context) ConnOption {
+ return func(conn *Conn) error {
+ conn.ctx = ctx
+ return nil
+ }
+}
+
// NewConn creates a new private *Conn from an already established connection.
func NewConn(conn io.ReadWriteCloser, opts ...ConnOption) (*Conn, error) {
return newConn(genericTransport{conn}, opts...)
@@ -211,6 +245,15 @@ func newConn(tr transport, opts ...ConnOption) (*Conn, error) {
return nil, err
}
}
+ if conn.ctx == nil {
+ conn.ctx = context.Background()
+ }
+ conn.ctx, conn.cancelCtx = context.WithCancel(conn.ctx)
+ go func() {
+ <-conn.ctx.Done()
+ conn.Close()
+ }()
+
conn.calls = newCallTracker()
if conn.handler == nil {
conn.handler = NewDefaultHandler()
@@ -237,27 +280,38 @@ func (conn *Conn) BusObject() BusObject {
// and the channels passed to Eavesdrop and Signal are closed. This method must
// not be called on shared connections.
func (conn *Conn) Close() error {
- conn.outHandler.close()
- if term, ok := conn.signalHandler.(Terminator); ok {
- term.Terminate()
- }
+ conn.closeOnce.Do(func() {
+ conn.outHandler.close()
+ if term, ok := conn.signalHandler.(Terminator); ok {
+ term.Terminate()
+ }
- if term, ok := conn.handler.(Terminator); ok {
- term.Terminate()
- }
+ if term, ok := conn.handler.(Terminator); ok {
+ term.Terminate()
+ }
- conn.eavesdroppedLck.Lock()
- if conn.eavesdropped != nil {
- close(conn.eavesdropped)
- }
- conn.eavesdroppedLck.Unlock()
+ conn.eavesdroppedLck.Lock()
+ if conn.eavesdropped != nil {
+ close(conn.eavesdropped)
+ }
+ conn.eavesdroppedLck.Unlock()
+
+ conn.cancelCtx()
+
+ conn.closeErr = conn.transport.Close()
+ })
+ return conn.closeErr
+}
- return conn.transport.Close()
+// Context returns the context associated with the connection. The
+// context will be cancelled when the connection is closed.
+func (conn *Conn) Context() context.Context {
+ return conn.ctx
}
// Eavesdrop causes conn to send all incoming messages to the given channel
// without further processing. Method replies, errors and signals will not be
-// sent to the appropiate channels and method calls will not be handled. If nil
+// sent to the appropriate channels and method calls will not be handled. If nil
// is passed, the normal behaviour is restored.
//
// The caller has to make sure that ch is sufficiently buffered;
@@ -294,7 +348,7 @@ func (conn *Conn) inWorker() {
msg, err := conn.ReadMessage()
if err != nil {
if _, ok := err.(InvalidMessageError); !ok {
- // Some read error occured (usually EOF); we can't really do
+ // Some read error occurred (usually EOF); we can't really do
// anything but to shut down all stuff and returns errors to all
// pending replies.
conn.Close()
@@ -323,6 +377,10 @@ func (conn *Conn) inWorker() {
// Ignore it.
continue
}
+
+ if conn.inInt != nil {
+ conn.inInt(msg)
+ }
switch msg.Type {
case TypeError:
conn.serialGen.RetireSerial(conn.calls.handleDBusError(msg))
@@ -383,11 +441,10 @@ func (conn *Conn) Object(dest string, path ObjectPath) BusObject {
return &Object{conn, dest, path}
}
-func (conn *Conn) sendMessage(msg *Message) {
- conn.sendMessageAndIfClosed(msg, func() {})
-}
-
func (conn *Conn) sendMessageAndIfClosed(msg *Message, ifClosed func()) {
+ if conn.outInt != nil {
+ conn.outInt(msg)
+ }
err := conn.outHandler.sendAndIfClosed(msg, ifClosed)
conn.calls.handleSendError(msg, err)
if err != nil {
@@ -483,7 +540,7 @@ func (conn *Conn) sendError(err error, dest string, serial uint32) {
if len(e.Body) > 0 {
msg.Headers[FieldSignature] = MakeVariant(SignatureOf(e.Body...))
}
- conn.sendMessage(msg)
+ conn.sendMessageAndIfClosed(msg, nil)
}
// sendReply creates a method reply message corresponding to the parameters and
@@ -501,33 +558,54 @@ func (conn *Conn) sendReply(dest string, serial uint32, values ...interface{}) {
if len(values) > 0 {
msg.Headers[FieldSignature] = MakeVariant(SignatureOf(values...))
}
- conn.sendMessage(msg)
+ conn.sendMessageAndIfClosed(msg, nil)
}
-func (conn *Conn) defaultSignalAction(fn func(h *defaultSignalHandler, ch chan<- *Signal), ch chan<- *Signal) {
- if !isDefaultSignalHandler(conn.signalHandler) {
- return
- }
- handler := conn.signalHandler.(*defaultSignalHandler)
- fn(handler, ch)
+// AddMatchSignal registers the given match rule to receive broadcast
+// signals based on their contents.
+func (conn *Conn) AddMatchSignal(options ...MatchOption) error {
+ options = append([]MatchOption{withMatchType("signal")}, options...)
+ return conn.busObj.Call(
+ "org.freedesktop.DBus.AddMatch", 0,
+ formatMatchOptions(options),
+ ).Store()
+}
+
+// RemoveMatchSignal removes the first rule that matches previously registered with AddMatchSignal.
+func (conn *Conn) RemoveMatchSignal(options ...MatchOption) error {
+ options = append([]MatchOption{withMatchType("signal")}, options...)
+ return conn.busObj.Call(
+ "org.freedesktop.DBus.RemoveMatch", 0,
+ formatMatchOptions(options),
+ ).Store()
}
// Signal registers the given channel to be passed all received signal messages.
-// The caller has to make sure that ch is sufficiently buffered; if a message
-// arrives when a write to c is not possible, it is discarded.
//
// Multiple of these channels can be registered at the same time.
//
// These channels are "overwritten" by Eavesdrop; i.e., if there currently is a
// channel for eavesdropped messages, this channel receives all signals, and
// none of the channels passed to Signal will receive any signals.
+//
+// Panics if the signal handler is not a `SignalRegistrar`.
func (conn *Conn) Signal(ch chan<- *Signal) {
- conn.defaultSignalAction((*defaultSignalHandler).addSignal, ch)
+ handler, ok := conn.signalHandler.(SignalRegistrar)
+ if !ok {
+ panic("cannot use this method with a non SignalRegistrar handler")
+ }
+ handler.AddSignal(ch)
}
// RemoveSignal removes the given channel from the list of the registered channels.
+//
+// Panics if the signal handler is not a `SignalRegistrar`.
func (conn *Conn) RemoveSignal(ch chan<- *Signal) {
- conn.defaultSignalAction((*defaultSignalHandler).removeSignal, ch)
+ handler, ok := conn.signalHandler.(SignalRegistrar)
+ if !ok {
+ panic("cannot use this method with a non SignalRegistrar handler")
+ }
+ handler.RemoveSignal(ch)
}
// SupportsUnixFDs returns whether the underlying transport supports passing of
@@ -614,18 +692,6 @@ func getTransport(address string) (transport, error) {
return nil, err
}
-// dereferenceAll returns a slice that, assuming that vs is a slice of pointers
-// of arbitrary types, containes the values that are obtained from dereferencing
-// all elements in vs.
-func dereferenceAll(vs []interface{}) []interface{} {
- for i := range vs {
- v := reflect.ValueOf(vs[i])
- v = v.Elem()
- vs[i] = v.Interface()
- }
- return vs
-}
-
// getKey gets a key from a the list of keys. Returns "" on error / not found...
func getKey(s, key string) string {
for _, keyEqualsValue := range strings.Split(s, ",") {
@@ -650,7 +716,9 @@ func (h *outputHandler) sendAndIfClosed(msg *Message, ifClosed func()) error {
h.closed.lck.RLock()
defer h.closed.lck.RUnlock()
if h.closed.isClosed {
- ifClosed()
+ if ifClosed != nil {
+ ifClosed()
+ }
return nil
}
h.sendLck.Lock()
@@ -801,7 +869,6 @@ func (tracker *callTracker) finalize(sn uint32) {
delete(tracker.calls, sn)
c.ContextCancel()
}
- return
}
func (tracker *callTracker) finalizeWithBody(sn uint32, body []interface{}) {
@@ -815,7 +882,6 @@ func (tracker *callTracker) finalizeWithBody(sn uint32, body []interface{}) {
c.Body = body
c.done()
}
- return
}
func (tracker *callTracker) finalizeWithError(sn uint32, err error) {
@@ -829,7 +895,6 @@ func (tracker *callTracker) finalizeWithError(sn uint32, err error) {
c.Err = err
c.done()
}
- return
}
func (tracker *callTracker) finalizeAllWithError(err error) {
diff --git a/vendor/github.com/godbus/dbus/conn_darwin.go b/vendor/github.com/godbus/dbus/v5/conn_darwin.go
index 6e2e40202..6e2e40202 100644
--- a/vendor/github.com/godbus/dbus/conn_darwin.go
+++ b/vendor/github.com/godbus/dbus/v5/conn_darwin.go
diff --git a/vendor/github.com/godbus/dbus/conn_other.go b/vendor/github.com/godbus/dbus/v5/conn_other.go
index 616dcf664..616dcf664 100644
--- a/vendor/github.com/godbus/dbus/conn_other.go
+++ b/vendor/github.com/godbus/dbus/v5/conn_other.go
diff --git a/vendor/github.com/godbus/dbus/conn_unix.go b/vendor/github.com/godbus/dbus/v5/conn_unix.go
index 4cba8ae8e..58aee7d2a 100644
--- a/vendor/github.com/godbus/dbus/conn_unix.go
+++ b/vendor/github.com/godbus/dbus/v5/conn_unix.go
@@ -4,7 +4,6 @@ package dbus
import (
"os"
- "fmt"
)
const defaultSystemBusAddress = "unix:path=/var/run/dbus/system_bus_socket"
@@ -12,7 +11,7 @@ const defaultSystemBusAddress = "unix:path=/var/run/dbus/system_bus_socket"
func getSystemBusPlatformAddress() string {
address := os.Getenv("DBUS_SYSTEM_BUS_ADDRESS")
if address != "" {
- return fmt.Sprintf("unix:path=%s", address)
+ return address
}
return defaultSystemBusAddress
-} \ No newline at end of file
+}
diff --git a/vendor/github.com/godbus/dbus/conn_windows.go b/vendor/github.com/godbus/dbus/v5/conn_windows.go
index 4291e4519..4291e4519 100644
--- a/vendor/github.com/godbus/dbus/conn_windows.go
+++ b/vendor/github.com/godbus/dbus/v5/conn_windows.go
diff --git a/vendor/github.com/godbus/dbus/dbus.go b/vendor/github.com/godbus/dbus/v5/dbus.go
index c6d0d3ce0..428923d26 100644
--- a/vendor/github.com/godbus/dbus/dbus.go
+++ b/vendor/github.com/godbus/dbus/v5/dbus.go
@@ -87,6 +87,7 @@ func setDest(dest, src reflect.Value) error {
}
if isVariant(src.Type()) && !isVariant(dest.Type()) {
src = getVariantValue(src)
+ return store(dest, src)
}
if !src.Type().ConvertibleTo(dest.Type()) {
return fmt.Errorf(
diff --git a/vendor/github.com/godbus/dbus/decoder.go b/vendor/github.com/godbus/dbus/v5/decoder.go
index ede91575b..ede91575b 100644
--- a/vendor/github.com/godbus/dbus/decoder.go
+++ b/vendor/github.com/godbus/dbus/v5/decoder.go
diff --git a/vendor/github.com/godbus/dbus/default_handler.go b/vendor/github.com/godbus/dbus/v5/default_handler.go
index 890b6f4e0..6d8bf32f9 100644
--- a/vendor/github.com/godbus/dbus/default_handler.go
+++ b/vendor/github.com/godbus/dbus/v5/default_handler.go
@@ -47,7 +47,7 @@ func (h *defaultHandler) introspectPath(path ObjectPath) string {
subpath := make(map[string]struct{})
var xml bytes.Buffer
xml.WriteString("<node>")
- for obj, _ := range h.objects {
+ for obj := range h.objects {
p := string(path)
if p != "/" {
p += "/"
@@ -57,7 +57,7 @@ func (h *defaultHandler) introspectPath(path ObjectPath) string {
subpath[node_name] = struct{}{}
}
}
- for s, _ := range subpath {
+ for s := range subpath {
xml.WriteString("\n\t<node name=\"" + s + "\"/>")
}
xml.WriteString("\n</node>")
@@ -234,88 +234,95 @@ func (obj *exportedIntf) isFallbackInterface() bool {
//
// Deprecated: this is the default value, don't use it, it will be unexported.
func NewDefaultSignalHandler() *defaultSignalHandler {
- return &defaultSignalHandler{
- closeChan: make(chan struct{}),
- }
-}
-
-func isDefaultSignalHandler(handler SignalHandler) bool {
- _, ok := handler.(*defaultSignalHandler)
- return ok
+ return &defaultSignalHandler{}
}
type defaultSignalHandler struct {
- sync.RWMutex
- closed bool
- signals []chan<- *Signal
- closeChan chan struct{}
+ mu sync.RWMutex
+ closed bool
+ signals []*signalChannelData
}
func (sh *defaultSignalHandler) DeliverSignal(intf, name string, signal *Signal) {
- sh.RLock()
- defer sh.RUnlock()
+ sh.mu.RLock()
+ defer sh.mu.RUnlock()
if sh.closed {
return
}
- for _, ch := range sh.signals {
- select {
- case ch <- signal:
- case <-sh.closeChan:
- return
- default:
- go func(ch chan<- *Signal) {
- select {
- case ch <- signal:
- case <-sh.closeChan:
- return
- }
- }(ch)
- }
+ for _, scd := range sh.signals {
+ scd.deliver(signal)
}
}
-func (sh *defaultSignalHandler) Init() error {
- sh.Lock()
- sh.signals = make([]chan<- *Signal, 0)
- sh.closeChan = make(chan struct{})
- sh.Unlock()
- return nil
-}
-
func (sh *defaultSignalHandler) Terminate() {
- sh.Lock()
- if !sh.closed {
- close(sh.closeChan)
+ sh.mu.Lock()
+ defer sh.mu.Unlock()
+ if sh.closed {
+ return
}
- sh.closed = true
- for _, ch := range sh.signals {
- close(ch)
+
+ for _, scd := range sh.signals {
+ scd.close()
+ close(scd.ch)
}
+ sh.closed = true
sh.signals = nil
- sh.Unlock()
}
-func (sh *defaultSignalHandler) addSignal(ch chan<- *Signal) {
- sh.Lock()
- defer sh.Unlock()
+func (sh *defaultSignalHandler) AddSignal(ch chan<- *Signal) {
+ sh.mu.Lock()
+ defer sh.mu.Unlock()
if sh.closed {
return
}
- sh.signals = append(sh.signals, ch)
-
+ sh.signals = append(sh.signals, &signalChannelData{
+ ch: ch,
+ done: make(chan struct{}),
+ })
}
-func (sh *defaultSignalHandler) removeSignal(ch chan<- *Signal) {
- sh.Lock()
- defer sh.Unlock()
+func (sh *defaultSignalHandler) RemoveSignal(ch chan<- *Signal) {
+ sh.mu.Lock()
+ defer sh.mu.Unlock()
if sh.closed {
return
}
for i := len(sh.signals) - 1; i >= 0; i-- {
- if ch == sh.signals[i] {
+ if ch == sh.signals[i].ch {
+ sh.signals[i].close()
copy(sh.signals[i:], sh.signals[i+1:])
sh.signals[len(sh.signals)-1] = nil
sh.signals = sh.signals[:len(sh.signals)-1]
}
}
}
+
+type signalChannelData struct {
+ wg sync.WaitGroup
+ ch chan<- *Signal
+ done chan struct{}
+}
+
+func (scd *signalChannelData) deliver(signal *Signal) {
+ select {
+ case scd.ch <- signal:
+ case <-scd.done:
+ return
+ default:
+ scd.wg.Add(1)
+ go scd.deferredDeliver(signal)
+ }
+}
+
+func (scd *signalChannelData) deferredDeliver(signal *Signal) {
+ select {
+ case scd.ch <- signal:
+ case <-scd.done:
+ }
+ scd.wg.Done()
+}
+
+func (scd *signalChannelData) close() {
+ close(scd.done)
+ scd.wg.Wait() // wait until all spawned goroutines return
+}
diff --git a/vendor/github.com/godbus/dbus/doc.go b/vendor/github.com/godbus/dbus/v5/doc.go
index 895036a8c..ade1df951 100644
--- a/vendor/github.com/godbus/dbus/doc.go
+++ b/vendor/github.com/godbus/dbus/v5/doc.go
@@ -61,7 +61,7 @@ Handling Unix file descriptors deserves special mention. To use them, you should
first check that they are supported on a connection by calling SupportsUnixFDs.
If it returns true, all method of Connection will translate messages containing
UnixFD's to messages that are accompanied by the given file descriptors with the
-UnixFD values being substituted by the correct indices. Similarily, the indices
+UnixFD values being substituted by the correct indices. Similarly, the indices
of incoming messages are automatically resolved. It shouldn't be necessary to use
UnixFDIndex.
diff --git a/vendor/github.com/godbus/dbus/encoder.go b/vendor/github.com/godbus/dbus/v5/encoder.go
index 8bb717761..adfbb75c5 100644
--- a/vendor/github.com/godbus/dbus/encoder.go
+++ b/vendor/github.com/godbus/dbus/v5/encoder.go
@@ -60,7 +60,7 @@ func (enc *encoder) binwrite(v interface{}) {
}
}
-// Encode encodes the given values to the underyling reader. All written values
+// Encode encodes the given values to the underlying reader. All written values
// are aligned properly as required by the D-Bus spec.
func (enc *encoder) Encode(vs ...interface{}) (err error) {
defer func() {
diff --git a/vendor/github.com/godbus/dbus/export.go b/vendor/github.com/godbus/dbus/v5/export.go
index 95d0e2958..c277ab142 100644
--- a/vendor/github.com/godbus/dbus/export.go
+++ b/vendor/github.com/godbus/dbus/v5/export.go
@@ -171,7 +171,7 @@ func (conn *Conn) handleCall(msg *Message) {
}
reply.Headers[FieldSignature] = MakeVariant(SignatureOf(reply.Body...))
- conn.sendMessage(reply)
+ conn.sendMessageAndIfClosed(reply, nil)
}
}
diff --git a/vendor/github.com/godbus/dbus/v5/go.mod b/vendor/github.com/godbus/dbus/v5/go.mod
new file mode 100644
index 000000000..15b920203
--- /dev/null
+++ b/vendor/github.com/godbus/dbus/v5/go.mod
@@ -0,0 +1,3 @@
+module github.com/godbus/dbus/v5
+
+go 1.12
diff --git a/vendor/github.com/godbus/dbus/v5/go.sum b/vendor/github.com/godbus/dbus/v5/go.sum
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/vendor/github.com/godbus/dbus/v5/go.sum
diff --git a/vendor/github.com/godbus/dbus/homedir.go b/vendor/github.com/godbus/dbus/v5/homedir.go
index 0b745f931..0b745f931 100644
--- a/vendor/github.com/godbus/dbus/homedir.go
+++ b/vendor/github.com/godbus/dbus/v5/homedir.go
diff --git a/vendor/github.com/godbus/dbus/homedir_dynamic.go b/vendor/github.com/godbus/dbus/v5/homedir_dynamic.go
index 2732081e7..2732081e7 100644
--- a/vendor/github.com/godbus/dbus/homedir_dynamic.go
+++ b/vendor/github.com/godbus/dbus/v5/homedir_dynamic.go
diff --git a/vendor/github.com/godbus/dbus/homedir_static.go b/vendor/github.com/godbus/dbus/v5/homedir_static.go
index b9d9cb552..b9d9cb552 100644
--- a/vendor/github.com/godbus/dbus/homedir_static.go
+++ b/vendor/github.com/godbus/dbus/v5/homedir_static.go
diff --git a/vendor/github.com/godbus/dbus/v5/match.go b/vendor/github.com/godbus/dbus/v5/match.go
new file mode 100644
index 000000000..086ee336a
--- /dev/null
+++ b/vendor/github.com/godbus/dbus/v5/match.go
@@ -0,0 +1,62 @@
+package dbus
+
+import (
+ "strings"
+)
+
+// MatchOption specifies option for dbus routing match rule. Options can be constructed with WithMatch* helpers.
+// For full list of available options consult
+// https://dbus.freedesktop.org/doc/dbus-specification.html#message-bus-routing-match-rules
+type MatchOption struct {
+ key string
+ value string
+}
+
+func formatMatchOptions(options []MatchOption) string {
+ items := make([]string, 0, len(options))
+ for _, option := range options {
+ items = append(items, option.key+"='"+option.value+"'")
+ }
+ return strings.Join(items, ",")
+}
+
+// WithMatchOption creates match option with given key and value
+func WithMatchOption(key, value string) MatchOption {
+ return MatchOption{key, value}
+}
+
+// doesn't make sense to export this option because clients can only
+// subscribe to messages with signal type.
+func withMatchType(typ string) MatchOption {
+ return WithMatchOption("type", typ)
+}
+
+// WithMatchSender sets sender match option.
+func WithMatchSender(sender string) MatchOption {
+ return WithMatchOption("sender", sender)
+}
+
+// WithMatchSender sets interface match option.
+func WithMatchInterface(iface string) MatchOption {
+ return WithMatchOption("interface", iface)
+}
+
+// WithMatchMember sets member match option.
+func WithMatchMember(member string) MatchOption {
+ return WithMatchOption("member", member)
+}
+
+// WithMatchObjectPath creates match option that filters events based on given path
+func WithMatchObjectPath(path ObjectPath) MatchOption {
+ return WithMatchOption("path", string(path))
+}
+
+// WithMatchPathNamespace sets path_namespace match option.
+func WithMatchPathNamespace(namespace ObjectPath) MatchOption {
+ return WithMatchOption("path_namespace", string(namespace))
+}
+
+// WithMatchDestination sets destination match option.
+func WithMatchDestination(destination string) MatchOption {
+ return WithMatchOption("destination", destination)
+}
diff --git a/vendor/github.com/godbus/dbus/message.go b/vendor/github.com/godbus/dbus/v5/message.go
index 6a925367e..6a925367e 100644
--- a/vendor/github.com/godbus/dbus/message.go
+++ b/vendor/github.com/godbus/dbus/v5/message.go
diff --git a/vendor/github.com/godbus/dbus/object.go b/vendor/github.com/godbus/dbus/v5/object.go
index 9309b9b40..8acd7fc8b 100644
--- a/vendor/github.com/godbus/dbus/object.go
+++ b/vendor/github.com/godbus/dbus/v5/object.go
@@ -38,41 +38,16 @@ func (o *Object) CallWithContext(ctx context.Context, method string, flags Flags
return <-o.createCall(ctx, method, flags, make(chan *Call, 1), args...).Done
}
-// MatchOption specifies option for dbus routing match rule. Options can be constructed with WithMatch* helpers.
-// For full list of available options consult
-// https://dbus.freedesktop.org/doc/dbus-specification.html#message-bus-routing-match-rules
-type MatchOption struct {
- key string
- value string
-}
-
-// WithMatchOption creates match option with given key and value
-func WithMatchOption(key, value string) MatchOption {
- return MatchOption{key, value}
-}
-
-// WithMatchObjectPath creates match option that filters events based on given path
-func WithMatchObjectPath(path ObjectPath) MatchOption {
- return MatchOption{"path", string(path)}
-}
-
-func formatMatchOptions(options []MatchOption) string {
- items := make([]string, 0, len(options))
- for _, option := range options {
- items = append(items, option.key+"='"+option.value+"'")
- }
-
- return strings.Join(items, ",")
-}
-
// AddMatchSignal subscribes BusObject to signals from specified interface,
// method (member). Additional filter rules can be added via WithMatch* option constructors.
// Note: To filter events by object path you have to specify this path via an option.
+//
+// Deprecated: use (*Conn) AddMatchSignal instead.
func (o *Object) AddMatchSignal(iface, member string, options ...MatchOption) *Call {
base := []MatchOption{
- {"type", "signal"},
- {"interface", iface},
- {"member", member},
+ withMatchType("signal"),
+ WithMatchInterface(iface),
+ WithMatchMember(member),
}
options = append(base, options...)
@@ -85,11 +60,13 @@ func (o *Object) AddMatchSignal(iface, member string, options ...MatchOption) *C
// RemoveMatchSignal unsubscribes BusObject from signals from specified interface,
// method (member). Additional filter rules can be added via WithMatch* option constructors
+//
+// Deprecated: use (*Conn) RemoveMatchSignal instead.
func (o *Object) RemoveMatchSignal(iface, member string, options ...MatchOption) *Call {
base := []MatchOption{
- {"type", "signal"},
- {"interface", iface},
- {"member", member},
+ withMatchType("signal"),
+ WithMatchInterface(iface),
+ WithMatchMember(member),
}
options = append(base, options...)
diff --git a/vendor/github.com/godbus/dbus/server_interfaces.go b/vendor/github.com/godbus/dbus/v5/server_interfaces.go
index 01166f0bd..79d97edf3 100644
--- a/vendor/github.com/godbus/dbus/server_interfaces.go
+++ b/vendor/github.com/godbus/dbus/v5/server_interfaces.go
@@ -77,6 +77,14 @@ type SignalHandler interface {
DeliverSignal(iface, name string, signal *Signal)
}
+// SignalRegistrar manages signal delivery channels.
+//
+// This is an optional set of methods for `SignalHandler`.
+type SignalRegistrar interface {
+ AddSignal(ch chan<- *Signal)
+ RemoveSignal(ch chan<- *Signal)
+}
+
// A DBusError is used to convert a generic object to a D-Bus error.
//
// Any custom error mechanism may implement this interface to provide
diff --git a/vendor/github.com/godbus/dbus/sig.go b/vendor/github.com/godbus/dbus/v5/sig.go
index c1b809202..c1b809202 100644
--- a/vendor/github.com/godbus/dbus/sig.go
+++ b/vendor/github.com/godbus/dbus/v5/sig.go
diff --git a/vendor/github.com/godbus/dbus/transport_darwin.go b/vendor/github.com/godbus/dbus/v5/transport_darwin.go
index 1bba0d6bf..1bba0d6bf 100644
--- a/vendor/github.com/godbus/dbus/transport_darwin.go
+++ b/vendor/github.com/godbus/dbus/v5/transport_darwin.go
diff --git a/vendor/github.com/godbus/dbus/transport_generic.go b/vendor/github.com/godbus/dbus/v5/transport_generic.go
index 718a1ff02..718a1ff02 100644
--- a/vendor/github.com/godbus/dbus/transport_generic.go
+++ b/vendor/github.com/godbus/dbus/v5/transport_generic.go
diff --git a/vendor/github.com/godbus/dbus/transport_nonce_tcp.go b/vendor/github.com/godbus/dbus/v5/transport_nonce_tcp.go
index 697739efa..697739efa 100644
--- a/vendor/github.com/godbus/dbus/transport_nonce_tcp.go
+++ b/vendor/github.com/godbus/dbus/v5/transport_nonce_tcp.go
diff --git a/vendor/github.com/godbus/dbus/transport_tcp.go b/vendor/github.com/godbus/dbus/v5/transport_tcp.go
index f91c9b7d7..f91c9b7d7 100644
--- a/vendor/github.com/godbus/dbus/transport_tcp.go
+++ b/vendor/github.com/godbus/dbus/v5/transport_tcp.go
diff --git a/vendor/github.com/godbus/dbus/transport_unix.go b/vendor/github.com/godbus/dbus/v5/transport_unix.go
index c7cd02f97..c7cd02f97 100644
--- a/vendor/github.com/godbus/dbus/transport_unix.go
+++ b/vendor/github.com/godbus/dbus/v5/transport_unix.go
diff --git a/vendor/github.com/godbus/dbus/transport_unixcred_dragonfly.go b/vendor/github.com/godbus/dbus/v5/transport_unixcred_dragonfly.go
index a8cd39395..a8cd39395 100644
--- a/vendor/github.com/godbus/dbus/transport_unixcred_dragonfly.go
+++ b/vendor/github.com/godbus/dbus/v5/transport_unixcred_dragonfly.go
diff --git a/vendor/github.com/godbus/dbus/transport_unixcred_freebsd.go b/vendor/github.com/godbus/dbus/v5/transport_unixcred_freebsd.go
index 0fc5b9273..0fc5b9273 100644
--- a/vendor/github.com/godbus/dbus/transport_unixcred_freebsd.go
+++ b/vendor/github.com/godbus/dbus/v5/transport_unixcred_freebsd.go
diff --git a/vendor/github.com/godbus/dbus/transport_unixcred_linux.go b/vendor/github.com/godbus/dbus/v5/transport_unixcred_linux.go
index d9dfdf698..d9dfdf698 100644
--- a/vendor/github.com/godbus/dbus/transport_unixcred_linux.go
+++ b/vendor/github.com/godbus/dbus/v5/transport_unixcred_linux.go
diff --git a/vendor/github.com/godbus/dbus/transport_unixcred_openbsd.go b/vendor/github.com/godbus/dbus/v5/transport_unixcred_openbsd.go
index af7bafdf9..af7bafdf9 100644
--- a/vendor/github.com/godbus/dbus/transport_unixcred_openbsd.go
+++ b/vendor/github.com/godbus/dbus/v5/transport_unixcred_openbsd.go
diff --git a/vendor/github.com/godbus/dbus/variant.go b/vendor/github.com/godbus/dbus/v5/variant.go
index 0ca123b01..5b51828c8 100644
--- a/vendor/github.com/godbus/dbus/variant.go
+++ b/vendor/github.com/godbus/dbus/v5/variant.go
@@ -26,7 +26,7 @@ func MakeVariantWithSignature(v interface{}, s Signature) Variant {
}
// ParseVariant parses the given string as a variant as described at
-// https://developer.gnome.org/glib/unstable/gvariant-text.html. If sig is not
+// https://developer.gnome.org/glib/stable/gvariant-text.html. If sig is not
// empty, it is taken to be the expected signature for the variant.
func ParseVariant(s string, sig Signature) (Variant, error) {
tokens := varLex(s)
@@ -129,7 +129,7 @@ func (v Variant) Signature() Signature {
}
// String returns the string representation of the underlying value of v as
-// described at https://developer.gnome.org/glib/unstable/gvariant-text.html.
+// described at https://developer.gnome.org/glib/stable/gvariant-text.html.
func (v Variant) String() string {
s, unamb := v.format()
if !unamb {
diff --git a/vendor/github.com/godbus/dbus/variant_lexer.go b/vendor/github.com/godbus/dbus/v5/variant_lexer.go
index 332007d6f..bf1398c8f 100644
--- a/vendor/github.com/godbus/dbus/variant_lexer.go
+++ b/vendor/github.com/godbus/dbus/v5/variant_lexer.go
@@ -51,7 +51,7 @@ func varLex(s string) []varToken {
}
func (l *varLexer) accept(valid string) bool {
- if strings.IndexRune(valid, l.next()) >= 0 {
+ if strings.ContainsRune(valid, l.next()) {
return true
}
l.backup()
@@ -214,17 +214,17 @@ func varLexNumber(l *varLexer) lexState {
digits = "01234567"
}
}
- for strings.IndexRune(digits, l.next()) >= 0 {
+ for strings.ContainsRune(digits, l.next()) {
}
l.backup()
if l.accept(".") {
- for strings.IndexRune(digits, l.next()) >= 0 {
+ for strings.ContainsRune(digits, l.next()) {
}
l.backup()
}
if l.accept("eE") {
l.accept("+-")
- for strings.IndexRune("0123456789", l.next()) >= 0 {
+ for strings.ContainsRune("0123456789", l.next()) {
}
l.backup()
}
diff --git a/vendor/github.com/godbus/dbus/variant_parser.go b/vendor/github.com/godbus/dbus/v5/variant_parser.go
index d20f5da6d..d20f5da6d 100644
--- a/vendor/github.com/godbus/dbus/variant_parser.go
+++ b/vendor/github.com/godbus/dbus/v5/variant_parser.go
diff --git a/vendor/github.com/gorilla/mux/README.md b/vendor/github.com/gorilla/mux/README.md
index 92e422eed..35eea9f10 100644
--- a/vendor/github.com/gorilla/mux/README.md
+++ b/vendor/github.com/gorilla/mux/README.md
@@ -1,11 +1,10 @@
# gorilla/mux
[![GoDoc](https://godoc.org/github.com/gorilla/mux?status.svg)](https://godoc.org/github.com/gorilla/mux)
-[![Build Status](https://travis-ci.org/gorilla/mux.svg?branch=master)](https://travis-ci.org/gorilla/mux)
[![CircleCI](https://circleci.com/gh/gorilla/mux.svg?style=svg)](https://circleci.com/gh/gorilla/mux)
[![Sourcegraph](https://sourcegraph.com/github.com/gorilla/mux/-/badge.svg)](https://sourcegraph.com/github.com/gorilla/mux?badge)
-![Gorilla Logo](http://www.gorillatoolkit.org/static/images/gorilla-icon-64.png)
+![Gorilla Logo](https://cloud-cdn.questionable.services/gorilla-icon-64.png)
https://www.gorillatoolkit.org/pkg/mux
@@ -26,6 +25,7 @@ The name mux stands for "HTTP request multiplexer". Like the standard `http.Serv
* [Examples](#examples)
* [Matching Routes](#matching-routes)
* [Static Files](#static-files)
+* [Serving Single Page Applications](#serving-single-page-applications) (e.g. React, Vue, Ember.js, etc.)
* [Registered URLs](#registered-urls)
* [Walking Routes](#walking-routes)
* [Graceful Shutdown](#graceful-shutdown)
@@ -212,6 +212,93 @@ func main() {
}
```
+### Serving Single Page Applications
+
+Most of the time it makes sense to serve your SPA on a separate web server from your API,
+but sometimes it's desirable to serve them both from one place. It's possible to write a simple
+handler for serving your SPA (for use with React Router's [BrowserRouter](https://reacttraining.com/react-router/web/api/BrowserRouter) for example), and leverage
+mux's powerful routing for your API endpoints.
+
+```go
+package main
+
+import (
+ "encoding/json"
+ "log"
+ "net/http"
+ "os"
+ "path/filepath"
+ "time"
+
+ "github.com/gorilla/mux"
+)
+
+// spaHandler implements the http.Handler interface, so we can use it
+// to respond to HTTP requests. The path to the static directory and
+// path to the index file within that static directory are used to
+// serve the SPA in the given static directory.
+type spaHandler struct {
+ staticPath string
+ indexPath string
+}
+
+// ServeHTTP inspects the URL path to locate a file within the static dir
+// on the SPA handler. If a file is found, it will be served. If not, the
+// file located at the index path on the SPA handler will be served. This
+// is suitable behavior for serving an SPA (single page application).
+func (h spaHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
+ // get the absolute path to prevent directory traversal
+ path, err := filepath.Abs(r.URL.Path)
+ if err != nil {
+ // if we failed to get the absolute path respond with a 400 bad request
+ // and stop
+ http.Error(w, err.Error(), http.StatusBadRequest)
+ return
+ }
+
+ // prepend the path with the path to the static directory
+ path = filepath.Join(h.staticPath, path)
+
+ // check whether a file exists at the given path
+ _, err = os.Stat(path)
+ if os.IsNotExist(err) {
+ // file does not exist, serve index.html
+ http.ServeFile(w, r, filepath.Join(h.staticPath, h.indexPath))
+ return
+ } else if err != nil {
+ // if we got an error (that wasn't that the file doesn't exist) stating the
+ // file, return a 500 internal server error and stop
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+
+ // otherwise, use http.FileServer to serve the static dir
+ http.FileServer(http.Dir(h.staticPath)).ServeHTTP(w, r)
+}
+
+func main() {
+ router := mux.NewRouter()
+
+ router.HandleFunc("/api/health", func(w http.ResponseWriter, r *http.Request) {
+ // an example API handler
+ json.NewEncoder(w).Encode(map[string]bool{"ok": true})
+ })
+
+ spa := spaHandler{staticPath: "build", indexPath: "index.html"}
+ router.PathPrefix("/").Handler(spa)
+
+ srv := &http.Server{
+ Handler: router,
+ Addr: "127.0.0.1:8000",
+ // Good practice: enforce timeouts for servers you create!
+ WriteTimeout: 15 * time.Second,
+ ReadTimeout: 15 * time.Second,
+ }
+
+ log.Fatal(srv.ListenAndServe())
+}
+```
+
### Registered URLs
Now let's see how to build registered URLs.
diff --git a/vendor/github.com/gorilla/mux/context.go b/vendor/github.com/gorilla/mux/context.go
deleted file mode 100644
index 665940a26..000000000
--- a/vendor/github.com/gorilla/mux/context.go
+++ /dev/null
@@ -1,18 +0,0 @@
-package mux
-
-import (
- "context"
- "net/http"
-)
-
-func contextGet(r *http.Request, key interface{}) interface{} {
- return r.Context().Value(key)
-}
-
-func contextSet(r *http.Request, key, val interface{}) *http.Request {
- if val == nil {
- return r
- }
-
- return r.WithContext(context.WithValue(r.Context(), key, val))
-}
diff --git a/vendor/github.com/gorilla/mux/go.mod b/vendor/github.com/gorilla/mux/go.mod
index cfc8ede58..df170a399 100644
--- a/vendor/github.com/gorilla/mux/go.mod
+++ b/vendor/github.com/gorilla/mux/go.mod
@@ -1 +1,3 @@
module github.com/gorilla/mux
+
+go 1.12
diff --git a/vendor/github.com/gorilla/mux/middleware.go b/vendor/github.com/gorilla/mux/middleware.go
index cf2b26dc0..cb51c565e 100644
--- a/vendor/github.com/gorilla/mux/middleware.go
+++ b/vendor/github.com/gorilla/mux/middleware.go
@@ -58,22 +58,17 @@ func CORSMethodMiddleware(r *Router) MiddlewareFunc {
func getAllMethodsForRoute(r *Router, req *http.Request) ([]string, error) {
var allMethods []string
- err := r.Walk(func(route *Route, _ *Router, _ []*Route) error {
- for _, m := range route.matchers {
- if _, ok := m.(*routeRegexp); ok {
- if m.Match(req, &RouteMatch{}) {
- methods, err := route.GetMethods()
- if err != nil {
- return err
- }
-
- allMethods = append(allMethods, methods...)
- }
- break
+ for _, route := range r.routes {
+ var match RouteMatch
+ if route.Match(req, &match) || match.MatchErr == ErrMethodMismatch {
+ methods, err := route.GetMethods()
+ if err != nil {
+ return nil, err
}
+
+ allMethods = append(allMethods, methods...)
}
- return nil
- })
+ }
- return allMethods, err
+ return allMethods, nil
}
diff --git a/vendor/github.com/gorilla/mux/mux.go b/vendor/github.com/gorilla/mux/mux.go
index a2cd193e4..c9ba64707 100644
--- a/vendor/github.com/gorilla/mux/mux.go
+++ b/vendor/github.com/gorilla/mux/mux.go
@@ -5,6 +5,7 @@
package mux
import (
+ "context"
"errors"
"fmt"
"net/http"
@@ -58,8 +59,7 @@ type Router struct {
// If true, do not clear the request context after handling the request.
//
- // Deprecated: No effect when go1.7+ is used, since the context is stored
- // on the request itself.
+ // Deprecated: No effect, since the context is stored on the request itself.
KeepContext bool
// Slice of middlewares to be called after a match is found
@@ -111,10 +111,8 @@ func copyRouteConf(r routeConf) routeConf {
c.regexp.queries = append(c.regexp.queries, copyRouteRegexp(q))
}
- c.matchers = make([]matcher, 0, len(r.matchers))
- for _, m := range r.matchers {
- c.matchers = append(c.matchers, m)
- }
+ c.matchers = make([]matcher, len(r.matchers))
+ copy(c.matchers, r.matchers)
return c
}
@@ -197,8 +195,8 @@ func (r *Router) ServeHTTP(w http.ResponseWriter, req *http.Request) {
var handler http.Handler
if r.Match(req, &match) {
handler = match.Handler
- req = setVars(req, match.Vars)
- req = setCurrentRoute(req, match.Route)
+ req = requestWithVars(req, match.Vars)
+ req = requestWithRoute(req, match.Route)
}
if handler == nil && match.MatchErr == ErrMethodMismatch {
@@ -428,7 +426,7 @@ const (
// Vars returns the route variables for the current request, if any.
func Vars(r *http.Request) map[string]string {
- if rv := contextGet(r, varsKey); rv != nil {
+ if rv := r.Context().Value(varsKey); rv != nil {
return rv.(map[string]string)
}
return nil
@@ -440,18 +438,20 @@ func Vars(r *http.Request) map[string]string {
// after the handler returns, unless the KeepContext option is set on the
// Router.
func CurrentRoute(r *http.Request) *Route {
- if rv := contextGet(r, routeKey); rv != nil {
+ if rv := r.Context().Value(routeKey); rv != nil {
return rv.(*Route)
}
return nil
}
-func setVars(r *http.Request, val interface{}) *http.Request {
- return contextSet(r, varsKey, val)
+func requestWithVars(r *http.Request, vars map[string]string) *http.Request {
+ ctx := context.WithValue(r.Context(), varsKey, vars)
+ return r.WithContext(ctx)
}
-func setCurrentRoute(r *http.Request, val interface{}) *http.Request {
- return contextSet(r, routeKey, val)
+func requestWithRoute(r *http.Request, route *Route) *http.Request {
+ ctx := context.WithValue(r.Context(), routeKey, route)
+ return r.WithContext(ctx)
}
// ----------------------------------------------------------------------------
diff --git a/vendor/github.com/gorilla/mux/regexp.go b/vendor/github.com/gorilla/mux/regexp.go
index ac1abcd47..96dd94ad1 100644
--- a/vendor/github.com/gorilla/mux/regexp.go
+++ b/vendor/github.com/gorilla/mux/regexp.go
@@ -181,21 +181,21 @@ func (r *routeRegexp) Match(req *http.Request, match *RouteMatch) bool {
}
}
return r.regexp.MatchString(host)
- } else {
- if r.regexpType == regexpTypeQuery {
- return r.matchQueryString(req)
- }
- path := req.URL.Path
- if r.options.useEncodedPath {
- path = req.URL.EscapedPath()
- }
- return r.regexp.MatchString(path)
}
+
+ if r.regexpType == regexpTypeQuery {
+ return r.matchQueryString(req)
+ }
+ path := req.URL.Path
+ if r.options.useEncodedPath {
+ path = req.URL.EscapedPath()
+ }
+ return r.regexp.MatchString(path)
}
// url builds a URL part using the given values.
func (r *routeRegexp) url(values map[string]string) (string, error) {
- urlValues := make([]interface{}, len(r.varsN))
+ urlValues := make([]interface{}, len(r.varsN), len(r.varsN))
for k, v := range r.varsN {
value, ok := values[v]
if !ok {
@@ -230,14 +230,51 @@ func (r *routeRegexp) getURLQuery(req *http.Request) string {
return ""
}
templateKey := strings.SplitN(r.template, "=", 2)[0]
- for key, vals := range req.URL.Query() {
- if key == templateKey && len(vals) > 0 {
- return key + "=" + vals[0]
- }
+ val, ok := findFirstQueryKey(req.URL.RawQuery, templateKey)
+ if ok {
+ return templateKey + "=" + val
}
return ""
}
+// findFirstQueryKey returns the same result as (*url.URL).Query()[key][0].
+// If key was not found, empty string and false is returned.
+func findFirstQueryKey(rawQuery, key string) (value string, ok bool) {
+ query := []byte(rawQuery)
+ for len(query) > 0 {
+ foundKey := query
+ if i := bytes.IndexAny(foundKey, "&;"); i >= 0 {
+ foundKey, query = foundKey[:i], foundKey[i+1:]
+ } else {
+ query = query[:0]
+ }
+ if len(foundKey) == 0 {
+ continue
+ }
+ var value []byte
+ if i := bytes.IndexByte(foundKey, '='); i >= 0 {
+ foundKey, value = foundKey[:i], foundKey[i+1:]
+ }
+ if len(foundKey) < len(key) {
+ // Cannot possibly be key.
+ continue
+ }
+ keyString, err := url.QueryUnescape(string(foundKey))
+ if err != nil {
+ continue
+ }
+ if keyString != key {
+ continue
+ }
+ valueString, err := url.QueryUnescape(string(value))
+ if err != nil {
+ continue
+ }
+ return valueString, true
+ }
+ return "", false
+}
+
func (r *routeRegexp) matchQueryString(req *http.Request) bool {
return r.regexp.MatchString(r.getURLQuery(req))
}
diff --git a/vendor/github.com/gorilla/mux/route.go b/vendor/github.com/gorilla/mux/route.go
index 8479c68c1..750afe570 100644
--- a/vendor/github.com/gorilla/mux/route.go
+++ b/vendor/github.com/gorilla/mux/route.go
@@ -74,7 +74,7 @@ func (r *Route) Match(req *http.Request, match *RouteMatch) bool {
return false
}
- if match.MatchErr == ErrMethodMismatch {
+ if match.MatchErr == ErrMethodMismatch && r.handler != nil {
// We found a route which matches request method, clear MatchErr
match.MatchErr = nil
// Then override the mis-matched handler
@@ -412,11 +412,30 @@ func (r *Route) Queries(pairs ...string) *Route {
type schemeMatcher []string
func (m schemeMatcher) Match(r *http.Request, match *RouteMatch) bool {
- return matchInArray(m, r.URL.Scheme)
+ scheme := r.URL.Scheme
+ // https://golang.org/pkg/net/http/#Request
+ // "For [most] server requests, fields other than Path and RawQuery will be
+ // empty."
+ // Since we're an http muxer, the scheme is either going to be http or https
+ // though, so we can just set it based on the tls termination state.
+ if scheme == "" {
+ if r.TLS == nil {
+ scheme = "http"
+ } else {
+ scheme = "https"
+ }
+ }
+ return matchInArray(m, scheme)
}
// Schemes adds a matcher for URL schemes.
// It accepts a sequence of schemes to be matched, e.g.: "http", "https".
+// If the request's URL has a scheme set, it will be matched against.
+// Generally, the URL scheme will only be set if a previous handler set it,
+// such as the ProxyHeaders handler from gorilla/handlers.
+// If unset, the scheme will be determined based on the request's TLS
+// termination state.
+// The first argument to Schemes will be used when constructing a route URL.
func (r *Route) Schemes(schemes ...string) *Route {
for k, v := range schemes {
schemes[k] = strings.ToLower(v)
@@ -493,8 +512,8 @@ func (r *Route) Subrouter() *Router {
// This also works for host variables:
//
// r := mux.NewRouter()
-// r.Host("{subdomain}.domain.com").
-// HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler).
+// r.HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler).
+// Host("{subdomain}.domain.com").
// Name("article")
//
// // url.String() will be "http://news.domain.com/articles/technology/42"
@@ -502,6 +521,13 @@ func (r *Route) Subrouter() *Router {
// "category", "technology",
// "id", "42")
//
+// The scheme of the resulting url will be the first argument that was passed to Schemes:
+//
+// // url.String() will be "https://example.com"
+// r := mux.NewRouter()
+// url, err := r.Host("example.com")
+// .Schemes("https", "http").URL()
+//
// All variables defined in the route are required, and their values must
// conform to the corresponding patterns.
func (r *Route) URL(pairs ...string) (*url.URL, error) {
@@ -635,7 +661,7 @@ func (r *Route) GetQueriesRegexp() ([]string, error) {
if r.regexp.queries == nil {
return nil, errors.New("mux: route doesn't have queries")
}
- var queries []string
+ queries := make([]string, 0, len(r.regexp.queries))
for _, query := range r.regexp.queries {
queries = append(queries, query.regexp.String())
}
@@ -654,7 +680,7 @@ func (r *Route) GetQueriesTemplates() ([]string, error) {
if r.regexp.queries == nil {
return nil, errors.New("mux: route doesn't have queries")
}
- var queries []string
+ queries := make([]string, 0, len(r.regexp.queries))
for _, query := range r.regexp.queries {
queries = append(queries, query.template)
}
diff --git a/vendor/github.com/gorilla/mux/test_helpers.go b/vendor/github.com/gorilla/mux/test_helpers.go
index 32ecffde4..5f5c496de 100644
--- a/vendor/github.com/gorilla/mux/test_helpers.go
+++ b/vendor/github.com/gorilla/mux/test_helpers.go
@@ -15,5 +15,5 @@ import "net/http"
// can be set by making a route that captures the required variables,
// starting a server and sending the request to that server.
func SetURLVars(r *http.Request, val map[string]string) *http.Request {
- return setVars(r, val)
+ return requestWithVars(r, val)
}
diff --git a/vendor/github.com/ishidawataru/sctp/.travis.yml b/vendor/github.com/ishidawataru/sctp/.travis.yml
index e72c57864..01a76be9a 100644
--- a/vendor/github.com/ishidawataru/sctp/.travis.yml
+++ b/vendor/github.com/ishidawataru/sctp/.travis.yml
@@ -1,10 +1,10 @@
language: go
go:
- - 1.6
- - 1.7
- - 1.8
- - 1.9
- - "1.10"
+ - 1.9.x
+ - 1.10.x
+ - 1.11.x
+ - 1.12.x
+ - 1.13.x
script:
- go test -v -race ./...
diff --git a/vendor/github.com/ishidawataru/sctp/NOTICE b/vendor/github.com/ishidawataru/sctp/NOTICE
new file mode 100644
index 000000000..cfb675fd4
--- /dev/null
+++ b/vendor/github.com/ishidawataru/sctp/NOTICE
@@ -0,0 +1,3 @@
+This source code includes following third party code
+
+- ipsock_linux.go : licensed by the Go authors, see GO_LICENSE file for the license which applies to the code
diff --git a/vendor/github.com/ishidawataru/sctp/go.mod b/vendor/github.com/ishidawataru/sctp/go.mod
new file mode 100644
index 000000000..5adf982b0
--- /dev/null
+++ b/vendor/github.com/ishidawataru/sctp/go.mod
@@ -0,0 +1,3 @@
+module github.com/ishidawataru/sctp
+
+go 1.12
diff --git a/vendor/github.com/ishidawataru/sctp/ipsock_linux.go b/vendor/github.com/ishidawataru/sctp/ipsock_linux.go
index f5632b72d..3df30fa46 100644
--- a/vendor/github.com/ishidawataru/sctp/ipsock_linux.go
+++ b/vendor/github.com/ishidawataru/sctp/ipsock_linux.go
@@ -1,3 +1,7 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the GO_LICENSE file.
+
package sctp
import (
diff --git a/vendor/github.com/ishidawataru/sctp/sctp.go b/vendor/github.com/ishidawataru/sctp/sctp.go
index 30d619640..94842f427 100644
--- a/vendor/github.com/ishidawataru/sctp/sctp.go
+++ b/vendor/github.com/ishidawataru/sctp/sctp.go
@@ -1,3 +1,18 @@
+// Copyright 2019 Wataru Ishida. All rights reserved.
+//
+// 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 sctp
import (
@@ -678,3 +693,37 @@ func (c *SCTPSndRcvInfoWrappedConn) SetReadDeadline(t time.Time) error {
func (c *SCTPSndRcvInfoWrappedConn) SetWriteDeadline(t time.Time) error {
return c.conn.SetWriteDeadline(t)
}
+
+func (c *SCTPSndRcvInfoWrappedConn) SetWriteBuffer(bytes int) error {
+ return c.conn.SetWriteBuffer(bytes)
+}
+
+func (c *SCTPSndRcvInfoWrappedConn) GetWriteBuffer() (int, error) {
+ return c.conn.GetWriteBuffer()
+}
+
+func (c *SCTPSndRcvInfoWrappedConn) SetReadBuffer(bytes int) error {
+ return c.conn.SetReadBuffer(bytes)
+}
+
+func (c *SCTPSndRcvInfoWrappedConn) GetReadBuffer() (int, error) {
+ return c.conn.GetReadBuffer()
+}
+
+// SocketConfig contains options for the SCTP socket.
+type SocketConfig struct {
+ // If Control is not nil it is called after the socket is created but before
+ // it is bound or connected.
+ Control func(network, address string, c syscall.RawConn) error
+
+ // InitMsg is the options to send in the initial SCTP message
+ InitMsg InitMsg
+}
+
+func (cfg *SocketConfig) Listen(net string, laddr *SCTPAddr) (*SCTPListener, error) {
+ return listenSCTPExtConfig(net, laddr, cfg.InitMsg, cfg.Control)
+}
+
+func (cfg *SocketConfig) Dial(net string, laddr, raddr *SCTPAddr) (*SCTPConn, error) {
+ return dialSCTPExtConfig(net, laddr, raddr, cfg.InitMsg, cfg.Control)
+}
diff --git a/vendor/github.com/ishidawataru/sctp/sctp_linux.go b/vendor/github.com/ishidawataru/sctp/sctp_linux.go
index 5a6ad9378..ac340ddfb 100644
--- a/vendor/github.com/ishidawataru/sctp/sctp_linux.go
+++ b/vendor/github.com/ishidawataru/sctp/sctp_linux.go
@@ -1,4 +1,18 @@
// +build linux,!386
+// Copyright 2019 Wataru Ishida. All rights reserved.
+//
+// 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 sctp
@@ -40,6 +54,23 @@ func getsockopt(fd int, optname, optval, optlen uintptr) (uintptr, uintptr, erro
return r0, r1, nil
}
+type rawConn struct {
+ sockfd int
+}
+
+func (r rawConn) Control(f func(fd uintptr)) error {
+ f(uintptr(r.sockfd))
+ return nil
+}
+
+func (r rawConn) Read(f func(fd uintptr) (done bool)) error {
+ panic("not implemented")
+}
+
+func (r rawConn) Write(f func(fd uintptr) (done bool)) error {
+ panic("not implemented")
+}
+
func (c *SCTPConn) SCTPWrite(b []byte, info *SndRcvInfo) (int, error) {
var cbuf []byte
if info != nil {
@@ -114,6 +145,22 @@ func (c *SCTPConn) Close() error {
return syscall.EBADF
}
+func (c *SCTPConn) SetWriteBuffer(bytes int) error {
+ return syscall.SetsockoptInt(c.fd(), syscall.SOL_SOCKET, syscall.SO_SNDBUF, bytes)
+}
+
+func (c *SCTPConn) GetWriteBuffer() (int, error) {
+ return syscall.GetsockoptInt(c.fd(), syscall.SOL_SOCKET, syscall.SO_SNDBUF)
+}
+
+func (c *SCTPConn) SetReadBuffer(bytes int) error {
+ return syscall.SetsockoptInt(c.fd(), syscall.SOL_SOCKET, syscall.SO_RCVBUF, bytes)
+}
+
+func (c *SCTPConn) GetReadBuffer() (int, error) {
+ return syscall.GetsockoptInt(c.fd(), syscall.SOL_SOCKET, syscall.SO_RCVBUF)
+}
+
// ListenSCTP - start listener on specified address/port
func ListenSCTP(net string, laddr *SCTPAddr) (*SCTPListener, error) {
return ListenSCTPExt(net, laddr, InitMsg{NumOstreams: SCTP_MAX_STREAM})
@@ -121,6 +168,11 @@ func ListenSCTP(net string, laddr *SCTPAddr) (*SCTPListener, error) {
// ListenSCTPExt - start listener on specified address/port with given SCTP options
func ListenSCTPExt(network string, laddr *SCTPAddr, options InitMsg) (*SCTPListener, error) {
+ return listenSCTPExtConfig(network, laddr, options, nil)
+}
+
+// listenSCTPExtConfig - start listener on specified address/port with given SCTP options and socket configuration
+func listenSCTPExtConfig(network string, laddr *SCTPAddr, options InitMsg, control func(network, address string, c syscall.RawConn) error) (*SCTPListener, error) {
af, ipv6only := favoriteAddrFamily(network, laddr, nil, "listen")
sock, err := syscall.Socket(
af,
@@ -140,6 +192,12 @@ func ListenSCTPExt(network string, laddr *SCTPAddr, options InitMsg) (*SCTPListe
if err = setDefaultSockopts(sock, af, ipv6only); err != nil {
return nil, err
}
+ if control != nil {
+ rc := rawConn{sockfd: sock}
+ if err = control(network, laddr.String(), rc); err != nil {
+ return nil, err
+ }
+ }
err = setInitOpts(sock, options)
if err != nil {
return nil, err
@@ -191,6 +249,11 @@ func DialSCTP(net string, laddr, raddr *SCTPAddr) (*SCTPConn, error) {
// DialSCTPExt - same as DialSCTP but with given SCTP options
func DialSCTPExt(network string, laddr, raddr *SCTPAddr, options InitMsg) (*SCTPConn, error) {
+ return dialSCTPExtConfig(network, laddr, raddr, options, nil)
+}
+
+// dialSCTPExtConfig - same as DialSCTP but with given SCTP options and socket configuration
+func dialSCTPExtConfig(network string, laddr, raddr *SCTPAddr, options InitMsg, control func(network, address string, c syscall.RawConn) error) (*SCTPConn, error) {
af, ipv6only := favoriteAddrFamily(network, laddr, raddr, "dial")
sock, err := syscall.Socket(
af,
@@ -210,6 +273,12 @@ func DialSCTPExt(network string, laddr, raddr *SCTPAddr, options InitMsg) (*SCTP
if err = setDefaultSockopts(sock, af, ipv6only); err != nil {
return nil, err
}
+ if control != nil {
+ rc := rawConn{sockfd: sock}
+ if err = control(network, laddr.String(), rc); err != nil {
+ return nil, err
+ }
+ }
err = setInitOpts(sock, options)
if err != nil {
return nil, err
diff --git a/vendor/github.com/ishidawataru/sctp/sctp_unsupported.go b/vendor/github.com/ishidawataru/sctp/sctp_unsupported.go
index e5415843d..118fe159e 100644
--- a/vendor/github.com/ishidawataru/sctp/sctp_unsupported.go
+++ b/vendor/github.com/ishidawataru/sctp/sctp_unsupported.go
@@ -1,4 +1,18 @@
// +build !linux linux,386
+// Copyright 2019 Wataru Ishida. All rights reserved.
+//
+// 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 sctp
@@ -6,6 +20,7 @@ import (
"errors"
"net"
"runtime"
+ "syscall"
)
var ErrUnsupported = errors.New("SCTP is unsupported on " + runtime.GOOS + "/" + runtime.GOARCH)
@@ -30,6 +45,22 @@ func (c *SCTPConn) Close() error {
return ErrUnsupported
}
+func (c *SCTPConn) SetWriteBuffer(bytes int) error {
+ return ErrUnsupported
+}
+
+func (c *SCTPConn) GetWriteBuffer() (int, error) {
+ return 0, ErrUnsupported
+}
+
+func (c *SCTPConn) SetReadBuffer(bytes int) error {
+ return ErrUnsupported
+}
+
+func (c *SCTPConn) GetReadBuffer() (int, error) {
+ return 0, ErrUnsupported
+}
+
func ListenSCTP(net string, laddr *SCTPAddr) (*SCTPListener, error) {
return nil, ErrUnsupported
}
@@ -38,6 +69,10 @@ func ListenSCTPExt(net string, laddr *SCTPAddr, options InitMsg) (*SCTPListener,
return nil, ErrUnsupported
}
+func listenSCTPExtConfig(network string, laddr *SCTPAddr, options InitMsg, control func(network, address string, c syscall.RawConn) error) (*SCTPListener, error) {
+ return nil, ErrUnsupported
+}
+
func (ln *SCTPListener) Accept() (net.Conn, error) {
return nil, ErrUnsupported
}
@@ -57,3 +92,7 @@ func DialSCTP(net string, laddr, raddr *SCTPAddr) (*SCTPConn, error) {
func DialSCTPExt(network string, laddr, raddr *SCTPAddr, options InitMsg) (*SCTPConn, error) {
return nil, ErrUnsupported
}
+
+func dialSCTPExtConfig(network string, laddr, raddr *SCTPAddr, options InitMsg, control func(network, address string, c syscall.RawConn) error) (*SCTPConn, error) {
+ return nil, ErrUnsupported
+}
diff --git a/vendor/github.com/klauspost/compress/flate/deflate.go b/vendor/github.com/klauspost/compress/flate/deflate.go
index 20c94f596..2b101d26b 100644
--- a/vendor/github.com/klauspost/compress/flate/deflate.go
+++ b/vendor/github.com/klauspost/compress/flate/deflate.go
@@ -48,6 +48,8 @@ const (
maxHashOffset = 1 << 24
skipNever = math.MaxInt32
+
+ debugDeflate = false
)
type compressionLevel struct {
@@ -59,15 +61,13 @@ type compressionLevel struct {
// See https://blog.klauspost.com/rebalancing-deflate-compression-levels/
var levels = []compressionLevel{
{}, // 0
- // Level 1-4 uses specialized algorithm - values not used
+ // Level 1-6 uses specialized algorithm - values not used
{0, 0, 0, 0, 0, 1},
{0, 0, 0, 0, 0, 2},
{0, 0, 0, 0, 0, 3},
{0, 0, 0, 0, 0, 4},
- // For levels 5-6 we don't bother trying with lazy matches.
- // Lazy matching is at least 30% slower, with 1.5% increase.
- {6, 0, 12, 8, 12, 5},
- {8, 0, 24, 16, 16, 6},
+ {0, 0, 0, 0, 0, 5},
+ {0, 0, 0, 0, 0, 6},
// Levels 7-9 use increasingly more lazy matching
// and increasingly stringent conditions for "good enough".
{8, 8, 24, 16, skipNever, 7},
@@ -203,9 +203,8 @@ func (d *compressor) writeBlockSkip(tok *tokens, index int, eof bool) error {
// This is much faster than doing a full encode.
// Should only be used after a start/reset.
func (d *compressor) fillWindow(b []byte) {
- // Do not fill window if we are in store-only mode,
- // use constant or Snappy compression.
- if d.level == 0 {
+ // Do not fill window if we are in store-only or huffman mode.
+ if d.level <= 0 {
return
}
if d.fast != nil {
@@ -368,7 +367,7 @@ func (d *compressor) deflateLazy() {
// Sanity enables additional runtime tests.
// It's intended to be used during development
// to supplement the currently ad-hoc unit tests.
- const sanity = false
+ const sanity = debugDeflate
if d.windowEnd-s.index < minMatchLength+maxMatchLength && !d.sync {
return
@@ -644,7 +643,7 @@ func (d *compressor) init(w io.Writer, level int) (err error) {
d.fill = (*compressor).fillBlock
d.step = (*compressor).store
case level == ConstantCompression:
- d.w.logReusePenalty = uint(4)
+ d.w.logNewTablePenalty = 4
d.window = make([]byte, maxStoreBlockSize)
d.fill = (*compressor).fillBlock
d.step = (*compressor).storeHuff
@@ -652,13 +651,13 @@ func (d *compressor) init(w io.Writer, level int) (err error) {
level = 5
fallthrough
case level >= 1 && level <= 6:
- d.w.logReusePenalty = uint(level + 1)
+ d.w.logNewTablePenalty = 6
d.fast = newFastEnc(level)
d.window = make([]byte, maxStoreBlockSize)
d.fill = (*compressor).fillBlock
d.step = (*compressor).storeFast
case 7 <= level && level <= 9:
- d.w.logReusePenalty = uint(level)
+ d.w.logNewTablePenalty = 10
d.state = &advancedState{}
d.compressionLevel = levels[level]
d.initDeflate()
@@ -667,6 +666,7 @@ func (d *compressor) init(w io.Writer, level int) (err error) {
default:
return fmt.Errorf("flate: invalid compression level %d: want value in range [-2, 9]", level)
}
+ d.level = level
return nil
}
@@ -720,6 +720,7 @@ func (d *compressor) close() error {
return d.w.err
}
d.w.flush()
+ d.w.reset(nil)
return d.w.err
}
@@ -750,8 +751,7 @@ func NewWriter(w io.Writer, level int) (*Writer, error) {
// can only be decompressed by a Reader initialized with the
// same dictionary.
func NewWriterDict(w io.Writer, level int, dict []byte) (*Writer, error) {
- dw := &dictWriter{w}
- zw, err := NewWriter(dw, level)
+ zw, err := NewWriter(w, level)
if err != nil {
return nil, err
}
@@ -760,14 +760,6 @@ func NewWriterDict(w io.Writer, level int, dict []byte) (*Writer, error) {
return zw, err
}
-type dictWriter struct {
- w io.Writer
-}
-
-func (w *dictWriter) Write(b []byte) (n int, err error) {
- return w.w.Write(b)
-}
-
// A Writer takes data written to it and writes the compressed
// form of that data to an underlying writer (see NewWriter).
type Writer struct {
@@ -805,11 +797,12 @@ func (w *Writer) Close() error {
// the result of NewWriter or NewWriterDict called with dst
// and w's level and dictionary.
func (w *Writer) Reset(dst io.Writer) {
- if dw, ok := w.d.w.writer.(*dictWriter); ok {
+ if len(w.dict) > 0 {
// w was created with NewWriterDict
- dw.w = dst
- w.d.reset(dw)
- w.d.fillWindow(w.dict)
+ w.d.reset(dst)
+ if dst != nil {
+ w.d.fillWindow(w.dict)
+ }
} else {
// w was created with NewWriter
w.d.reset(dst)
diff --git a/vendor/github.com/klauspost/compress/flate/fast_encoder.go b/vendor/github.com/klauspost/compress/flate/fast_encoder.go
index b0a470f92..6d4c1e98b 100644
--- a/vendor/github.com/klauspost/compress/flate/fast_encoder.go
+++ b/vendor/github.com/klauspost/compress/flate/fast_encoder.go
@@ -35,17 +35,17 @@ func newFastEnc(level int) fastEnc {
}
const (
- tableBits = 16 // Bits used in the table
+ tableBits = 15 // Bits used in the table
tableSize = 1 << tableBits // Size of the table
tableShift = 32 - tableBits // Right-shift to get the tableBits most significant bits of a uint32.
baseMatchOffset = 1 // The smallest match offset
baseMatchLength = 3 // The smallest match length per the RFC section 3.2.5
maxMatchOffset = 1 << 15 // The largest match offset
- bTableBits = 18 // Bits used in the big tables
- bTableSize = 1 << bTableBits // Size of the table
- allocHistory = maxMatchOffset * 10 // Size to preallocate for history.
- bufferReset = (1 << 31) - allocHistory - maxStoreBlockSize // Reset the buffer offset when reaching this.
+ bTableBits = 17 // Bits used in the big tables
+ bTableSize = 1 << bTableBits // Size of the table
+ allocHistory = maxStoreBlockSize * 10 // Size to preallocate for history.
+ bufferReset = (1 << 31) - allocHistory - maxStoreBlockSize - 1 // Reset the buffer offset when reaching this.
)
const (
@@ -92,7 +92,6 @@ func hash(u uint32) uint32 {
}
type tableEntry struct {
- val uint32
offset int32
}
@@ -210,16 +209,14 @@ func (e *fastGen) matchlenLong(s, t int32, src []byte) int32 {
// Reset the encoding table.
func (e *fastGen) Reset() {
- if cap(e.hist) < int(maxMatchOffset*8) {
- l := maxMatchOffset * 8
- // Make it at least 1MB.
- if l < 1<<20 {
- l = 1 << 20
- }
- e.hist = make([]byte, 0, l)
+ if cap(e.hist) < allocHistory {
+ e.hist = make([]byte, 0, allocHistory)
+ }
+ // We offset current position so everything will be out of reach.
+ // If we are above the buffer reset it will be cleared anyway since len(hist) == 0.
+ if e.cur <= bufferReset {
+ e.cur += maxMatchOffset + int32(len(e.hist))
}
- // We offset current position so everything will be out of reach
- e.cur += maxMatchOffset + int32(len(e.hist))
e.hist = e.hist[:0]
}
diff --git a/vendor/github.com/klauspost/compress/flate/gen_inflate.go b/vendor/github.com/klauspost/compress/flate/gen_inflate.go
new file mode 100644
index 000000000..c74a95fe7
--- /dev/null
+++ b/vendor/github.com/klauspost/compress/flate/gen_inflate.go
@@ -0,0 +1,274 @@
+// +build generate
+
+//go:generate go run $GOFILE && gofmt -w inflate_gen.go
+
+package main
+
+import (
+ "os"
+ "strings"
+)
+
+func main() {
+ f, err := os.Create("inflate_gen.go")
+ if err != nil {
+ panic(err)
+ }
+ defer f.Close()
+ types := []string{"*bytes.Buffer", "*bytes.Reader", "*bufio.Reader", "*strings.Reader"}
+ names := []string{"BytesBuffer", "BytesReader", "BufioReader", "StringsReader"}
+ imports := []string{"bytes", "bufio", "io", "strings", "math/bits"}
+ f.WriteString(`// Code generated by go generate gen_inflate.go. DO NOT EDIT.
+
+package flate
+
+import (
+`)
+
+ for _, imp := range imports {
+ f.WriteString("\t\"" + imp + "\"\n")
+ }
+ f.WriteString(")\n\n")
+
+ template := `
+
+// Decode a single Huffman block from f.
+// hl and hd are the Huffman states for the lit/length values
+// and the distance values, respectively. If hd == nil, using the
+// fixed distance encoding associated with fixed Huffman blocks.
+func (f *decompressor) $FUNCNAME$() {
+ const (
+ stateInit = iota // Zero value must be stateInit
+ stateDict
+ )
+ fr := f.r.($TYPE$)
+ moreBits := func() error {
+ c, err := fr.ReadByte()
+ if err != nil {
+ return noEOF(err)
+ }
+ f.roffset++
+ f.b |= uint32(c) << f.nb
+ f.nb += 8
+ return nil
+ }
+
+ switch f.stepState {
+ case stateInit:
+ goto readLiteral
+ case stateDict:
+ goto copyHistory
+ }
+
+readLiteral:
+ // Read literal and/or (length, distance) according to RFC section 3.2.3.
+ {
+ var v int
+ {
+ // Inlined v, err := f.huffSym(f.hl)
+ // Since a huffmanDecoder can be empty or be composed of a degenerate tree
+ // with single element, huffSym must error on these two edge cases. In both
+ // cases, the chunks slice will be 0 for the invalid sequence, leading it
+ // satisfy the n == 0 check below.
+ n := uint(f.hl.maxRead)
+ // Optimization. Compiler isn't smart enough to keep f.b,f.nb in registers,
+ // but is smart enough to keep local variables in registers, so use nb and b,
+ // inline call to moreBits and reassign b,nb back to f on return.
+ nb, b := f.nb, f.b
+ for {
+ for nb < n {
+ c, err := fr.ReadByte()
+ if err != nil {
+ f.b = b
+ f.nb = nb
+ f.err = noEOF(err)
+ return
+ }
+ f.roffset++
+ b |= uint32(c) << (nb & 31)
+ nb += 8
+ }
+ chunk := f.hl.chunks[b&(huffmanNumChunks-1)]
+ n = uint(chunk & huffmanCountMask)
+ if n > huffmanChunkBits {
+ chunk = f.hl.links[chunk>>huffmanValueShift][(b>>huffmanChunkBits)&f.hl.linkMask]
+ n = uint(chunk & huffmanCountMask)
+ }
+ if n <= nb {
+ if n == 0 {
+ f.b = b
+ f.nb = nb
+ if debugDecode {
+ fmt.Println("huffsym: n==0")
+ }
+ f.err = CorruptInputError(f.roffset)
+ return
+ }
+ f.b = b >> (n & 31)
+ f.nb = nb - n
+ v = int(chunk >> huffmanValueShift)
+ break
+ }
+ }
+ }
+
+ var n uint // number of bits extra
+ var length int
+ var err error
+ switch {
+ case v < 256:
+ f.dict.writeByte(byte(v))
+ if f.dict.availWrite() == 0 {
+ f.toRead = f.dict.readFlush()
+ f.step = (*decompressor).$FUNCNAME$
+ f.stepState = stateInit
+ return
+ }
+ goto readLiteral
+ case v == 256:
+ f.finishBlock()
+ return
+ // otherwise, reference to older data
+ case v < 265:
+ length = v - (257 - 3)
+ n = 0
+ case v < 269:
+ length = v*2 - (265*2 - 11)
+ n = 1
+ case v < 273:
+ length = v*4 - (269*4 - 19)
+ n = 2
+ case v < 277:
+ length = v*8 - (273*8 - 35)
+ n = 3
+ case v < 281:
+ length = v*16 - (277*16 - 67)
+ n = 4
+ case v < 285:
+ length = v*32 - (281*32 - 131)
+ n = 5
+ case v < maxNumLit:
+ length = 258
+ n = 0
+ default:
+ if debugDecode {
+ fmt.Println(v, ">= maxNumLit")
+ }
+ f.err = CorruptInputError(f.roffset)
+ return
+ }
+ if n > 0 {
+ for f.nb < n {
+ if err = moreBits(); err != nil {
+ if debugDecode {
+ fmt.Println("morebits n>0:", err)
+ }
+ f.err = err
+ return
+ }
+ }
+ length += int(f.b & uint32(1<<n-1))
+ f.b >>= n
+ f.nb -= n
+ }
+
+ var dist int
+ if f.hd == nil {
+ for f.nb < 5 {
+ if err = moreBits(); err != nil {
+ if debugDecode {
+ fmt.Println("morebits f.nb<5:", err)
+ }
+ f.err = err
+ return
+ }
+ }
+ dist = int(bits.Reverse8(uint8(f.b & 0x1F << 3)))
+ f.b >>= 5
+ f.nb -= 5
+ } else {
+ if dist, err = f.huffSym(f.hd); err != nil {
+ if debugDecode {
+ fmt.Println("huffsym:", err)
+ }
+ f.err = err
+ return
+ }
+ }
+
+ switch {
+ case dist < 4:
+ dist++
+ case dist < maxNumDist:
+ nb := uint(dist-2) >> 1
+ // have 1 bit in bottom of dist, need nb more.
+ extra := (dist & 1) << nb
+ for f.nb < nb {
+ if err = moreBits(); err != nil {
+ if debugDecode {
+ fmt.Println("morebits f.nb<nb:", err)
+ }
+ f.err = err
+ return
+ }
+ }
+ extra |= int(f.b & uint32(1<<nb-1))
+ f.b >>= nb
+ f.nb -= nb
+ dist = 1<<(nb+1) + 1 + extra
+ default:
+ if debugDecode {
+ fmt.Println("dist too big:", dist, maxNumDist)
+ }
+ f.err = CorruptInputError(f.roffset)
+ return
+ }
+
+ // No check on length; encoding can be prescient.
+ if dist > f.dict.histSize() {
+ if debugDecode {
+ fmt.Println("dist > f.dict.histSize():", dist, f.dict.histSize())
+ }
+ f.err = CorruptInputError(f.roffset)
+ return
+ }
+
+ f.copyLen, f.copyDist = length, dist
+ goto copyHistory
+ }
+
+copyHistory:
+ // Perform a backwards copy according to RFC section 3.2.3.
+ {
+ cnt := f.dict.tryWriteCopy(f.copyDist, f.copyLen)
+ if cnt == 0 {
+ cnt = f.dict.writeCopy(f.copyDist, f.copyLen)
+ }
+ f.copyLen -= cnt
+
+ if f.dict.availWrite() == 0 || f.copyLen > 0 {
+ f.toRead = f.dict.readFlush()
+ f.step = (*decompressor).$FUNCNAME$ // We need to continue this work
+ f.stepState = stateDict
+ return
+ }
+ goto readLiteral
+ }
+}
+
+`
+ for i, t := range types {
+ s := strings.Replace(template, "$FUNCNAME$", "huffman"+names[i], -1)
+ s = strings.Replace(s, "$TYPE$", t, -1)
+ f.WriteString(s)
+ }
+ f.WriteString("func (f *decompressor) huffmanBlockDecoder() func() {\n")
+ f.WriteString("\tswitch f.r.(type) {\n")
+ for i, t := range types {
+ f.WriteString("\t\tcase " + t + ":\n")
+ f.WriteString("\t\t\treturn f.huffman" + names[i] + "\n")
+ }
+ f.WriteString("\t\tdefault:\n")
+ f.WriteString("\t\t\treturn f.huffmanBlockGeneric")
+ f.WriteString("\t}\n}\n")
+}
diff --git a/vendor/github.com/klauspost/compress/flate/huffman_bit_writer.go b/vendor/github.com/klauspost/compress/flate/huffman_bit_writer.go
index dd74ffb87..53fe1d06e 100644
--- a/vendor/github.com/klauspost/compress/flate/huffman_bit_writer.go
+++ b/vendor/github.com/klauspost/compress/flate/huffman_bit_writer.go
@@ -93,12 +93,12 @@ type huffmanBitWriter struct {
err error
lastHeader int
// Set between 0 (reused block can be up to 2x the size)
- logReusePenalty uint
- lastHuffMan bool
- bytes [256]byte
- literalFreq [lengthCodesStart + 32]uint16
- offsetFreq [32]uint16
- codegenFreq [codegenCodeCount]uint16
+ logNewTablePenalty uint
+ lastHuffMan bool
+ bytes [256]byte
+ literalFreq [lengthCodesStart + 32]uint16
+ offsetFreq [32]uint16
+ codegenFreq [codegenCodeCount]uint16
// codegen must have an extra space for the final symbol.
codegen [literalCount + offsetCodeCount + 1]uint8
@@ -119,7 +119,7 @@ type huffmanBitWriter struct {
// If lastHuffMan is set, a table for outputting literals has been generated and offsets are invalid.
//
// An incoming block estimates the output size of a new table using a 'fresh' by calculating the
-// optimal size and adding a penalty in 'logReusePenalty'.
+// optimal size and adding a penalty in 'logNewTablePenalty'.
// A Huffman table is not optimal, which is why we add a penalty, and generating a new table
// is slower both for compression and decompression.
@@ -177,6 +177,11 @@ func (w *huffmanBitWriter) flush() {
w.nbits = 0
return
}
+ if w.lastHeader > 0 {
+ // We owe an EOB
+ w.writeCode(w.literalEncoding.codes[endBlockMarker])
+ w.lastHeader = 0
+ }
n := w.nbytes
for w.nbits != 0 {
w.bytes[n] = byte(w.bits)
@@ -350,6 +355,13 @@ func (w *huffmanBitWriter) headerSize() (size, numCodegens int) {
}
// dynamicSize returns the size of dynamically encoded data in bits.
+func (w *huffmanBitWriter) dynamicReuseSize(litEnc, offEnc *huffmanEncoder) (size int) {
+ size = litEnc.bitLength(w.literalFreq[:]) +
+ offEnc.bitLength(w.offsetFreq[:])
+ return size
+}
+
+// dynamicSize returns the size of dynamically encoded data in bits.
func (w *huffmanBitWriter) dynamicSize(litEnc, offEnc *huffmanEncoder, extraBits int) (size, numCodegens int) {
header, numCodegens := w.headerSize()
size = header +
@@ -451,12 +463,12 @@ func (w *huffmanBitWriter) writeDynamicHeader(numLiterals int, numOffsets int, n
i := 0
for {
- var codeWord int = int(w.codegen[i])
+ var codeWord = uint32(w.codegen[i])
i++
if codeWord == badCode {
break
}
- w.writeCode(w.codegenEncoding.codes[uint32(codeWord)])
+ w.writeCode(w.codegenEncoding.codes[codeWord])
switch codeWord {
case 16:
@@ -472,6 +484,9 @@ func (w *huffmanBitWriter) writeDynamicHeader(numLiterals int, numOffsets int, n
}
}
+// writeStoredHeader will write a stored header.
+// If the stored block is only used for EOF,
+// it is replaced with a fixed huffman block.
func (w *huffmanBitWriter) writeStoredHeader(length int, isEof bool) {
if w.err != nil {
return
@@ -481,6 +496,16 @@ func (w *huffmanBitWriter) writeStoredHeader(length int, isEof bool) {
w.writeCode(w.literalEncoding.codes[endBlockMarker])
w.lastHeader = 0
}
+
+ // To write EOF, use a fixed encoding block. 10 bits instead of 5 bytes.
+ if length == 0 && isEof {
+ w.writeFixedHeader(isEof)
+ // EOB: 7 bits, value: 0
+ w.writeBits(0, 7)
+ w.flush()
+ return
+ }
+
var flag int32
if isEof {
flag = 1
@@ -587,8 +612,8 @@ func (w *huffmanBitWriter) writeBlockDynamic(tokens *tokens, eof bool, input []b
tokens.AddEOB()
}
- // We cannot reuse pure huffman table.
- if w.lastHuffMan && w.lastHeader > 0 {
+ // We cannot reuse pure huffman table, and must mark as EOF.
+ if (w.lastHuffMan || eof) && w.lastHeader > 0 {
// We will not try to reuse.
w.writeCode(w.literalEncoding.codes[endBlockMarker])
w.lastHeader = 0
@@ -602,14 +627,14 @@ func (w *huffmanBitWriter) writeBlockDynamic(tokens *tokens, eof bool, input []b
var size int
// Check if we should reuse.
if w.lastHeader > 0 {
- // Estimate size for using a new table
+ // Estimate size for using a new table.
+ // Use the previous header size as the best estimate.
newSize := w.lastHeader + tokens.EstimatedBits()
+ newSize += newSize >> w.logNewTablePenalty
// The estimated size is calculated as an optimal table.
// We add a penalty to make it more realistic and re-use a bit more.
- newSize += newSize >> (w.logReusePenalty & 31)
- extra := w.extraBitSize()
- reuseSize, _ := w.dynamicSize(w.literalEncoding, w.offsetEncoding, extra)
+ reuseSize := w.dynamicReuseSize(w.literalEncoding, w.offsetEncoding) + w.extraBitSize()
// Check if a new table is better.
if newSize < reuseSize {
@@ -801,21 +826,30 @@ func (w *huffmanBitWriter) writeBlockHuff(eof bool, input []byte, sync bool) {
}
// Add everything as literals
- estBits := histogramSize(input, w.literalFreq[:], !eof && !sync) + 15
+ // We have to estimate the header size.
+ // Assume header is around 70 bytes:
+ // https://stackoverflow.com/a/25454430
+ const guessHeaderSizeBits = 70 * 8
+ estBits, estExtra := histogramSize(input, w.literalFreq[:], !eof && !sync)
+ estBits += w.lastHeader + 15
+ if w.lastHeader == 0 {
+ estBits += guessHeaderSizeBits
+ }
+ estBits += estBits >> w.logNewTablePenalty
// Store bytes, if we don't get a reasonable improvement.
ssize, storable := w.storedSize(input)
- if storable && ssize < (estBits+estBits>>4) {
+ if storable && ssize < estBits {
w.writeStoredHeader(len(input), eof)
w.writeBytes(input)
return
}
if w.lastHeader > 0 {
- size, _ := w.dynamicSize(w.literalEncoding, huffOffset, w.lastHeader)
- estBits += estBits >> (w.logReusePenalty)
+ reuseSize := w.literalEncoding.bitLength(w.literalFreq[:256])
+ estBits += estExtra
- if estBits < size {
+ if estBits < reuseSize {
// We owe an EOB
w.writeCode(w.literalEncoding.codes[endBlockMarker])
w.lastHeader = 0
diff --git a/vendor/github.com/klauspost/compress/flate/huffman_code.go b/vendor/github.com/klauspost/compress/flate/huffman_code.go
index 1810c6898..4c39a3018 100644
--- a/vendor/github.com/klauspost/compress/flate/huffman_code.go
+++ b/vendor/github.com/klauspost/compress/flate/huffman_code.go
@@ -7,7 +7,6 @@ package flate
import (
"math"
"math/bits"
- "sort"
)
const (
@@ -25,8 +24,6 @@ type huffmanEncoder struct {
codes []hcode
freqcache []literalNode
bitCount [17]int32
- lns byLiteral // stored to avoid repeated allocation in generate
- lfs byFreq // stored to avoid repeated allocation in generate
}
type literalNode struct {
@@ -112,8 +109,8 @@ func generateFixedOffsetEncoding() *huffmanEncoder {
return h
}
-var fixedLiteralEncoding *huffmanEncoder = generateFixedLiteralEncoding()
-var fixedOffsetEncoding *huffmanEncoder = generateFixedOffsetEncoding()
+var fixedLiteralEncoding = generateFixedLiteralEncoding()
+var fixedOffsetEncoding = generateFixedOffsetEncoding()
func (h *huffmanEncoder) bitLength(freq []uint16) int {
var total int
@@ -270,7 +267,7 @@ func (h *huffmanEncoder) assignEncodingAndSize(bitCount []int32, list []literalN
// assigned in literal order (not frequency order).
chunk := list[len(list)-int(bits):]
- h.lns.sort(chunk)
+ sortByLiteral(chunk)
for _, node := range chunk {
h.codes[node.literal] = hcode{code: reverseBits(code, uint8(n)), len: uint16(n)}
code++
@@ -315,7 +312,7 @@ func (h *huffmanEncoder) generate(freq []uint16, maxBits int32) {
}
return
}
- h.lfs.sort(list)
+ sortByFreq(list)
// Get the number of literals for each bit count
bitCount := h.bitCounts(list, maxBits)
@@ -323,59 +320,44 @@ func (h *huffmanEncoder) generate(freq []uint16, maxBits int32) {
h.assignEncodingAndSize(bitCount, list)
}
-type byLiteral []literalNode
-
-func (s *byLiteral) sort(a []literalNode) {
- *s = byLiteral(a)
- sort.Sort(s)
-}
-
-func (s byLiteral) Len() int { return len(s) }
-
-func (s byLiteral) Less(i, j int) bool {
- return s[i].literal < s[j].literal
-}
-
-func (s byLiteral) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
-
-type byFreq []literalNode
-
-func (s *byFreq) sort(a []literalNode) {
- *s = byFreq(a)
- sort.Sort(s)
-}
-
-func (s byFreq) Len() int { return len(s) }
-
-func (s byFreq) Less(i, j int) bool {
- if s[i].freq == s[j].freq {
- return s[i].literal < s[j].literal
+func atLeastOne(v float32) float32 {
+ if v < 1 {
+ return 1
}
- return s[i].freq < s[j].freq
+ return v
}
-func (s byFreq) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
-
// histogramSize accumulates a histogram of b in h.
// An estimated size in bits is returned.
// Unassigned values are assigned '1' in the histogram.
// len(h) must be >= 256, and h's elements must be all zeroes.
-func histogramSize(b []byte, h []uint16, fill bool) int {
+func histogramSize(b []byte, h []uint16, fill bool) (int, int) {
h = h[:256]
for _, t := range b {
h[t]++
}
- invTotal := 1.0 / float64(len(b))
- shannon := 0.0
- single := math.Ceil(-math.Log2(invTotal))
- for i, v := range h[:] {
- if v > 0 {
- n := float64(v)
- shannon += math.Ceil(-math.Log2(n*invTotal) * n)
- } else if fill {
- shannon += single
- h[i] = 1
+ invTotal := 1.0 / float32(len(b))
+ shannon := float32(0.0)
+ var extra float32
+ if fill {
+ oneBits := atLeastOne(-mFastLog2(invTotal))
+ for i, v := range h[:] {
+ if v > 0 {
+ n := float32(v)
+ shannon += atLeastOne(-mFastLog2(n*invTotal)) * n
+ } else {
+ h[i] = 1
+ extra += oneBits
+ }
+ }
+ } else {
+ for _, v := range h[:] {
+ if v > 0 {
+ n := float32(v)
+ shannon += atLeastOne(-mFastLog2(n*invTotal)) * n
+ }
}
}
- return int(shannon + 0.99)
+
+ return int(shannon + 0.99), int(extra + 0.99)
}
diff --git a/vendor/github.com/klauspost/compress/flate/huffman_sortByFreq.go b/vendor/github.com/klauspost/compress/flate/huffman_sortByFreq.go
new file mode 100644
index 000000000..207780299
--- /dev/null
+++ b/vendor/github.com/klauspost/compress/flate/huffman_sortByFreq.go
@@ -0,0 +1,178 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package flate
+
+// Sort sorts data.
+// It makes one call to data.Len to determine n, and O(n*log(n)) calls to
+// data.Less and data.Swap. The sort is not guaranteed to be stable.
+func sortByFreq(data []literalNode) {
+ n := len(data)
+ quickSortByFreq(data, 0, n, maxDepth(n))
+}
+
+func quickSortByFreq(data []literalNode, a, b, maxDepth int) {
+ for b-a > 12 { // Use ShellSort for slices <= 12 elements
+ if maxDepth == 0 {
+ heapSort(data, a, b)
+ return
+ }
+ maxDepth--
+ mlo, mhi := doPivotByFreq(data, a, b)
+ // Avoiding recursion on the larger subproblem guarantees
+ // a stack depth of at most lg(b-a).
+ if mlo-a < b-mhi {
+ quickSortByFreq(data, a, mlo, maxDepth)
+ a = mhi // i.e., quickSortByFreq(data, mhi, b)
+ } else {
+ quickSortByFreq(data, mhi, b, maxDepth)
+ b = mlo // i.e., quickSortByFreq(data, a, mlo)
+ }
+ }
+ if b-a > 1 {
+ // Do ShellSort pass with gap 6
+ // It could be written in this simplified form cause b-a <= 12
+ for i := a + 6; i < b; i++ {
+ if data[i].freq == data[i-6].freq && data[i].literal < data[i-6].literal || data[i].freq < data[i-6].freq {
+ data[i], data[i-6] = data[i-6], data[i]
+ }
+ }
+ insertionSortByFreq(data, a, b)
+ }
+}
+
+// siftDownByFreq implements the heap property on data[lo, hi).
+// first is an offset into the array where the root of the heap lies.
+func siftDownByFreq(data []literalNode, lo, hi, first int) {
+ root := lo
+ for {
+ child := 2*root + 1
+ if child >= hi {
+ break
+ }
+ if child+1 < hi && (data[first+child].freq == data[first+child+1].freq && data[first+child].literal < data[first+child+1].literal || data[first+child].freq < data[first+child+1].freq) {
+ child++
+ }
+ if data[first+root].freq == data[first+child].freq && data[first+root].literal > data[first+child].literal || data[first+root].freq > data[first+child].freq {
+ return
+ }
+ data[first+root], data[first+child] = data[first+child], data[first+root]
+ root = child
+ }
+}
+func doPivotByFreq(data []literalNode, lo, hi int) (midlo, midhi int) {
+ m := int(uint(lo+hi) >> 1) // Written like this to avoid integer overflow.
+ if hi-lo > 40 {
+ // Tukey's ``Ninther,'' median of three medians of three.
+ s := (hi - lo) / 8
+ medianOfThreeSortByFreq(data, lo, lo+s, lo+2*s)
+ medianOfThreeSortByFreq(data, m, m-s, m+s)
+ medianOfThreeSortByFreq(data, hi-1, hi-1-s, hi-1-2*s)
+ }
+ medianOfThreeSortByFreq(data, lo, m, hi-1)
+
+ // Invariants are:
+ // data[lo] = pivot (set up by ChoosePivot)
+ // data[lo < i < a] < pivot
+ // data[a <= i < b] <= pivot
+ // data[b <= i < c] unexamined
+ // data[c <= i < hi-1] > pivot
+ // data[hi-1] >= pivot
+ pivot := lo
+ a, c := lo+1, hi-1
+
+ for ; a < c && (data[a].freq == data[pivot].freq && data[a].literal < data[pivot].literal || data[a].freq < data[pivot].freq); a++ {
+ }
+ b := a
+ for {
+ for ; b < c && (data[pivot].freq == data[b].freq && data[pivot].literal > data[b].literal || data[pivot].freq > data[b].freq); b++ { // data[b] <= pivot
+ }
+ for ; b < c && (data[pivot].freq == data[c-1].freq && data[pivot].literal < data[c-1].literal || data[pivot].freq < data[c-1].freq); c-- { // data[c-1] > pivot
+ }
+ if b >= c {
+ break
+ }
+ // data[b] > pivot; data[c-1] <= pivot
+ data[b], data[c-1] = data[c-1], data[b]
+ b++
+ c--
+ }
+ // If hi-c<3 then there are duplicates (by property of median of nine).
+ // Let's be a bit more conservative, and set border to 5.
+ protect := hi-c < 5
+ if !protect && hi-c < (hi-lo)/4 {
+ // Lets test some points for equality to pivot
+ dups := 0
+ if data[pivot].freq == data[hi-1].freq && data[pivot].literal > data[hi-1].literal || data[pivot].freq > data[hi-1].freq { // data[hi-1] = pivot
+ data[c], data[hi-1] = data[hi-1], data[c]
+ c++
+ dups++
+ }
+ if data[b-1].freq == data[pivot].freq && data[b-1].literal > data[pivot].literal || data[b-1].freq > data[pivot].freq { // data[b-1] = pivot
+ b--
+ dups++
+ }
+ // m-lo = (hi-lo)/2 > 6
+ // b-lo > (hi-lo)*3/4-1 > 8
+ // ==> m < b ==> data[m] <= pivot
+ if data[m].freq == data[pivot].freq && data[m].literal > data[pivot].literal || data[m].freq > data[pivot].freq { // data[m] = pivot
+ data[m], data[b-1] = data[b-1], data[m]
+ b--
+ dups++
+ }
+ // if at least 2 points are equal to pivot, assume skewed distribution
+ protect = dups > 1
+ }
+ if protect {
+ // Protect against a lot of duplicates
+ // Add invariant:
+ // data[a <= i < b] unexamined
+ // data[b <= i < c] = pivot
+ for {
+ for ; a < b && (data[b-1].freq == data[pivot].freq && data[b-1].literal > data[pivot].literal || data[b-1].freq > data[pivot].freq); b-- { // data[b] == pivot
+ }
+ for ; a < b && (data[a].freq == data[pivot].freq && data[a].literal < data[pivot].literal || data[a].freq < data[pivot].freq); a++ { // data[a] < pivot
+ }
+ if a >= b {
+ break
+ }
+ // data[a] == pivot; data[b-1] < pivot
+ data[a], data[b-1] = data[b-1], data[a]
+ a++
+ b--
+ }
+ }
+ // Swap pivot into middle
+ data[pivot], data[b-1] = data[b-1], data[pivot]
+ return b - 1, c
+}
+
+// Insertion sort
+func insertionSortByFreq(data []literalNode, a, b int) {
+ for i := a + 1; i < b; i++ {
+ for j := i; j > a && (data[j].freq == data[j-1].freq && data[j].literal < data[j-1].literal || data[j].freq < data[j-1].freq); j-- {
+ data[j], data[j-1] = data[j-1], data[j]
+ }
+ }
+}
+
+// quickSortByFreq, loosely following Bentley and McIlroy,
+// ``Engineering a Sort Function,'' SP&E November 1993.
+
+// medianOfThreeSortByFreq moves the median of the three values data[m0], data[m1], data[m2] into data[m1].
+func medianOfThreeSortByFreq(data []literalNode, m1, m0, m2 int) {
+ // sort 3 elements
+ if data[m1].freq == data[m0].freq && data[m1].literal < data[m0].literal || data[m1].freq < data[m0].freq {
+ data[m1], data[m0] = data[m0], data[m1]
+ }
+ // data[m0] <= data[m1]
+ if data[m2].freq == data[m1].freq && data[m2].literal < data[m1].literal || data[m2].freq < data[m1].freq {
+ data[m2], data[m1] = data[m1], data[m2]
+ // data[m0] <= data[m2] && data[m1] < data[m2]
+ if data[m1].freq == data[m0].freq && data[m1].literal < data[m0].literal || data[m1].freq < data[m0].freq {
+ data[m1], data[m0] = data[m0], data[m1]
+ }
+ }
+ // now data[m0] <= data[m1] <= data[m2]
+}
diff --git a/vendor/github.com/klauspost/compress/flate/huffman_sortByLiteral.go b/vendor/github.com/klauspost/compress/flate/huffman_sortByLiteral.go
new file mode 100644
index 000000000..93f1aea10
--- /dev/null
+++ b/vendor/github.com/klauspost/compress/flate/huffman_sortByLiteral.go
@@ -0,0 +1,201 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package flate
+
+// Sort sorts data.
+// It makes one call to data.Len to determine n, and O(n*log(n)) calls to
+// data.Less and data.Swap. The sort is not guaranteed to be stable.
+func sortByLiteral(data []literalNode) {
+ n := len(data)
+ quickSort(data, 0, n, maxDepth(n))
+}
+
+func quickSort(data []literalNode, a, b, maxDepth int) {
+ for b-a > 12 { // Use ShellSort for slices <= 12 elements
+ if maxDepth == 0 {
+ heapSort(data, a, b)
+ return
+ }
+ maxDepth--
+ mlo, mhi := doPivot(data, a, b)
+ // Avoiding recursion on the larger subproblem guarantees
+ // a stack depth of at most lg(b-a).
+ if mlo-a < b-mhi {
+ quickSort(data, a, mlo, maxDepth)
+ a = mhi // i.e., quickSort(data, mhi, b)
+ } else {
+ quickSort(data, mhi, b, maxDepth)
+ b = mlo // i.e., quickSort(data, a, mlo)
+ }
+ }
+ if b-a > 1 {
+ // Do ShellSort pass with gap 6
+ // It could be written in this simplified form cause b-a <= 12
+ for i := a + 6; i < b; i++ {
+ if data[i].literal < data[i-6].literal {
+ data[i], data[i-6] = data[i-6], data[i]
+ }
+ }
+ insertionSort(data, a, b)
+ }
+}
+func heapSort(data []literalNode, a, b int) {
+ first := a
+ lo := 0
+ hi := b - a
+
+ // Build heap with greatest element at top.
+ for i := (hi - 1) / 2; i >= 0; i-- {
+ siftDown(data, i, hi, first)
+ }
+
+ // Pop elements, largest first, into end of data.
+ for i := hi - 1; i >= 0; i-- {
+ data[first], data[first+i] = data[first+i], data[first]
+ siftDown(data, lo, i, first)
+ }
+}
+
+// siftDown implements the heap property on data[lo, hi).
+// first is an offset into the array where the root of the heap lies.
+func siftDown(data []literalNode, lo, hi, first int) {
+ root := lo
+ for {
+ child := 2*root + 1
+ if child >= hi {
+ break
+ }
+ if child+1 < hi && data[first+child].literal < data[first+child+1].literal {
+ child++
+ }
+ if data[first+root].literal > data[first+child].literal {
+ return
+ }
+ data[first+root], data[first+child] = data[first+child], data[first+root]
+ root = child
+ }
+}
+func doPivot(data []literalNode, lo, hi int) (midlo, midhi int) {
+ m := int(uint(lo+hi) >> 1) // Written like this to avoid integer overflow.
+ if hi-lo > 40 {
+ // Tukey's ``Ninther,'' median of three medians of three.
+ s := (hi - lo) / 8
+ medianOfThree(data, lo, lo+s, lo+2*s)
+ medianOfThree(data, m, m-s, m+s)
+ medianOfThree(data, hi-1, hi-1-s, hi-1-2*s)
+ }
+ medianOfThree(data, lo, m, hi-1)
+
+ // Invariants are:
+ // data[lo] = pivot (set up by ChoosePivot)
+ // data[lo < i < a] < pivot
+ // data[a <= i < b] <= pivot
+ // data[b <= i < c] unexamined
+ // data[c <= i < hi-1] > pivot
+ // data[hi-1] >= pivot
+ pivot := lo
+ a, c := lo+1, hi-1
+
+ for ; a < c && data[a].literal < data[pivot].literal; a++ {
+ }
+ b := a
+ for {
+ for ; b < c && data[pivot].literal > data[b].literal; b++ { // data[b] <= pivot
+ }
+ for ; b < c && data[pivot].literal < data[c-1].literal; c-- { // data[c-1] > pivot
+ }
+ if b >= c {
+ break
+ }
+ // data[b] > pivot; data[c-1] <= pivot
+ data[b], data[c-1] = data[c-1], data[b]
+ b++
+ c--
+ }
+ // If hi-c<3 then there are duplicates (by property of median of nine).
+ // Let's be a bit more conservative, and set border to 5.
+ protect := hi-c < 5
+ if !protect && hi-c < (hi-lo)/4 {
+ // Lets test some points for equality to pivot
+ dups := 0
+ if data[pivot].literal > data[hi-1].literal { // data[hi-1] = pivot
+ data[c], data[hi-1] = data[hi-1], data[c]
+ c++
+ dups++
+ }
+ if data[b-1].literal > data[pivot].literal { // data[b-1] = pivot
+ b--
+ dups++
+ }
+ // m-lo = (hi-lo)/2 > 6
+ // b-lo > (hi-lo)*3/4-1 > 8
+ // ==> m < b ==> data[m] <= pivot
+ if data[m].literal > data[pivot].literal { // data[m] = pivot
+ data[m], data[b-1] = data[b-1], data[m]
+ b--
+ dups++
+ }
+ // if at least 2 points are equal to pivot, assume skewed distribution
+ protect = dups > 1
+ }
+ if protect {
+ // Protect against a lot of duplicates
+ // Add invariant:
+ // data[a <= i < b] unexamined
+ // data[b <= i < c] = pivot
+ for {
+ for ; a < b && data[b-1].literal > data[pivot].literal; b-- { // data[b] == pivot
+ }
+ for ; a < b && data[a].literal < data[pivot].literal; a++ { // data[a] < pivot
+ }
+ if a >= b {
+ break
+ }
+ // data[a] == pivot; data[b-1] < pivot
+ data[a], data[b-1] = data[b-1], data[a]
+ a++
+ b--
+ }
+ }
+ // Swap pivot into middle
+ data[pivot], data[b-1] = data[b-1], data[pivot]
+ return b - 1, c
+}
+
+// Insertion sort
+func insertionSort(data []literalNode, a, b int) {
+ for i := a + 1; i < b; i++ {
+ for j := i; j > a && data[j].literal < data[j-1].literal; j-- {
+ data[j], data[j-1] = data[j-1], data[j]
+ }
+ }
+}
+
+// maxDepth returns a threshold at which quicksort should switch
+// to heapsort. It returns 2*ceil(lg(n+1)).
+func maxDepth(n int) int {
+ var depth int
+ for i := n; i > 0; i >>= 1 {
+ depth++
+ }
+ return depth * 2
+}
+
+// medianOfThree moves the median of the three values data[m0], data[m1], data[m2] into data[m1].
+func medianOfThree(data []literalNode, m1, m0, m2 int) {
+ // sort 3 elements
+ if data[m1].literal < data[m0].literal {
+ data[m1], data[m0] = data[m0], data[m1]
+ }
+ // data[m0] <= data[m1]
+ if data[m2].literal < data[m1].literal {
+ data[m2], data[m1] = data[m1], data[m2]
+ // data[m0] <= data[m2] && data[m1] < data[m2]
+ if data[m1].literal < data[m0].literal {
+ data[m1], data[m0] = data[m0], data[m1]
+ }
+ }
+ // now data[m0] <= data[m1] <= data[m2]
+}
diff --git a/vendor/github.com/klauspost/compress/flate/inflate.go b/vendor/github.com/klauspost/compress/flate/inflate.go
index 6dc5b5d06..7f175a4ec 100644
--- a/vendor/github.com/klauspost/compress/flate/inflate.go
+++ b/vendor/github.com/klauspost/compress/flate/inflate.go
@@ -106,7 +106,7 @@ const (
)
type huffmanDecoder struct {
- min int // the minimum code length
+ maxRead int // the maximum number of bits we can read and not overread
chunks *[huffmanNumChunks]uint16 // chunks as described above
links [][]uint16 // overflow links
linkMask uint32 // mask the width of the link table
@@ -126,12 +126,12 @@ func (h *huffmanDecoder) init(lengths []int) bool {
if h.chunks == nil {
h.chunks = &[huffmanNumChunks]uint16{}
}
- if h.min != 0 {
+ if h.maxRead != 0 {
*h = huffmanDecoder{chunks: h.chunks, links: h.links}
}
// Count number of codes of each length,
- // compute min and max length.
+ // compute maxRead and max length.
var count [maxCodeLen]int
var min, max int
for _, n := range lengths {
@@ -178,7 +178,7 @@ func (h *huffmanDecoder) init(lengths []int) bool {
return false
}
- h.min = min
+ h.maxRead = min
chunks := h.chunks[:]
for i := range chunks {
chunks[i] = 0
@@ -342,7 +342,7 @@ func (f *decompressor) nextBlock() {
// compressed, fixed Huffman tables
f.hl = &fixedHuffmanDecoder
f.hd = nil
- f.huffmanBlock()
+ f.huffmanBlockDecoder()()
case 2:
// compressed, dynamic Huffman tables
if f.err = f.readHuffman(); f.err != nil {
@@ -350,7 +350,7 @@ func (f *decompressor) nextBlock() {
}
f.hl = &f.h1
f.hd = &f.h2
- f.huffmanBlock()
+ f.huffmanBlockDecoder()()
default:
// 3 is reserved.
if debugDecode {
@@ -543,12 +543,18 @@ func (f *decompressor) readHuffman() error {
return CorruptInputError(f.roffset)
}
- // As an optimization, we can initialize the min bits to read at a time
+ // As an optimization, we can initialize the maxRead bits to read at a time
// for the HLIT tree to the length of the EOB marker since we know that
// every block must terminate with one. This preserves the property that
// we never read any extra bytes after the end of the DEFLATE stream.
- if f.h1.min < f.bits[endBlockMarker] {
- f.h1.min = f.bits[endBlockMarker]
+ if f.h1.maxRead < f.bits[endBlockMarker] {
+ f.h1.maxRead = f.bits[endBlockMarker]
+ }
+ if !f.final {
+ // If not the final block, the smallest block possible is
+ // a predefined table, BTYPE=01, with a single EOB marker.
+ // This will take up 3 + 7 bits.
+ f.h1.maxRead += 10
}
return nil
@@ -558,7 +564,7 @@ func (f *decompressor) readHuffman() error {
// hl and hd are the Huffman states for the lit/length values
// and the distance values, respectively. If hd == nil, using the
// fixed distance encoding associated with fixed Huffman blocks.
-func (f *decompressor) huffmanBlock() {
+func (f *decompressor) huffmanBlockGeneric() {
const (
stateInit = iota // Zero value must be stateInit
stateDict
@@ -574,19 +580,64 @@ func (f *decompressor) huffmanBlock() {
readLiteral:
// Read literal and/or (length, distance) according to RFC section 3.2.3.
{
- v, err := f.huffSym(f.hl)
- if err != nil {
- f.err = err
- return
+ var v int
+ {
+ // Inlined v, err := f.huffSym(f.hl)
+ // Since a huffmanDecoder can be empty or be composed of a degenerate tree
+ // with single element, huffSym must error on these two edge cases. In both
+ // cases, the chunks slice will be 0 for the invalid sequence, leading it
+ // satisfy the n == 0 check below.
+ n := uint(f.hl.maxRead)
+ // Optimization. Compiler isn't smart enough to keep f.b,f.nb in registers,
+ // but is smart enough to keep local variables in registers, so use nb and b,
+ // inline call to moreBits and reassign b,nb back to f on return.
+ nb, b := f.nb, f.b
+ for {
+ for nb < n {
+ c, err := f.r.ReadByte()
+ if err != nil {
+ f.b = b
+ f.nb = nb
+ f.err = noEOF(err)
+ return
+ }
+ f.roffset++
+ b |= uint32(c) << (nb & 31)
+ nb += 8
+ }
+ chunk := f.hl.chunks[b&(huffmanNumChunks-1)]
+ n = uint(chunk & huffmanCountMask)
+ if n > huffmanChunkBits {
+ chunk = f.hl.links[chunk>>huffmanValueShift][(b>>huffmanChunkBits)&f.hl.linkMask]
+ n = uint(chunk & huffmanCountMask)
+ }
+ if n <= nb {
+ if n == 0 {
+ f.b = b
+ f.nb = nb
+ if debugDecode {
+ fmt.Println("huffsym: n==0")
+ }
+ f.err = CorruptInputError(f.roffset)
+ return
+ }
+ f.b = b >> (n & 31)
+ f.nb = nb - n
+ v = int(chunk >> huffmanValueShift)
+ break
+ }
+ }
}
+
var n uint // number of bits extra
var length int
+ var err error
switch {
case v < 256:
f.dict.writeByte(byte(v))
if f.dict.availWrite() == 0 {
f.toRead = f.dict.readFlush()
- f.step = (*decompressor).huffmanBlock
+ f.step = (*decompressor).huffmanBlockGeneric
f.stepState = stateInit
return
}
@@ -714,7 +765,7 @@ copyHistory:
if f.dict.availWrite() == 0 || f.copyLen > 0 {
f.toRead = f.dict.readFlush()
- f.step = (*decompressor).huffmanBlock // We need to continue this work
+ f.step = (*decompressor).huffmanBlockGeneric // We need to continue this work
f.stepState = stateDict
return
}
@@ -726,21 +777,33 @@ copyHistory:
func (f *decompressor) dataBlock() {
// Uncompressed.
// Discard current half-byte.
- f.nb = 0
- f.b = 0
+ left := (f.nb) & 7
+ f.nb -= left
+ f.b >>= left
+
+ offBytes := f.nb >> 3
+ // Unfilled values will be overwritten.
+ f.buf[0] = uint8(f.b)
+ f.buf[1] = uint8(f.b >> 8)
+ f.buf[2] = uint8(f.b >> 16)
+ f.buf[3] = uint8(f.b >> 24)
+
+ f.roffset += int64(offBytes)
+ f.nb, f.b = 0, 0
// Length then ones-complement of length.
- nr, err := io.ReadFull(f.r, f.buf[0:4])
+ nr, err := io.ReadFull(f.r, f.buf[offBytes:4])
f.roffset += int64(nr)
if err != nil {
f.err = noEOF(err)
return
}
- n := int(f.buf[0]) | int(f.buf[1])<<8
- nn := int(f.buf[2]) | int(f.buf[3])<<8
- if uint16(nn) != uint16(^n) {
+ n := uint16(f.buf[0]) | uint16(f.buf[1])<<8
+ nn := uint16(f.buf[2]) | uint16(f.buf[3])<<8
+ if nn != ^n {
if debugDecode {
- fmt.Println("uint16(nn) != uint16(^n)", nn, ^n)
+ ncomp := ^n
+ fmt.Println("uint16(nn) != uint16(^n)", nn, ncomp)
}
f.err = CorruptInputError(f.roffset)
return
@@ -752,7 +815,7 @@ func (f *decompressor) dataBlock() {
return
}
- f.copyLen = n
+ f.copyLen = int(n)
f.copyData()
}
@@ -816,7 +879,7 @@ func (f *decompressor) huffSym(h *huffmanDecoder) (int, error) {
// with single element, huffSym must error on these two edge cases. In both
// cases, the chunks slice will be 0 for the invalid sequence, leading it
// satisfy the n == 0 check below.
- n := uint(h.min)
+ n := uint(h.maxRead)
// Optimization. Compiler isn't smart enough to keep f.b,f.nb in registers,
// but is smart enough to keep local variables in registers, so use nb and b,
// inline call to moreBits and reassign b,nb back to f on return.
diff --git a/vendor/github.com/klauspost/compress/flate/inflate_gen.go b/vendor/github.com/klauspost/compress/flate/inflate_gen.go
new file mode 100644
index 000000000..397dc1b1a
--- /dev/null
+++ b/vendor/github.com/klauspost/compress/flate/inflate_gen.go
@@ -0,0 +1,922 @@
+// Code generated by go generate gen_inflate.go. DO NOT EDIT.
+
+package flate
+
+import (
+ "bufio"
+ "bytes"
+ "fmt"
+ "math/bits"
+ "strings"
+)
+
+// Decode a single Huffman block from f.
+// hl and hd are the Huffman states for the lit/length values
+// and the distance values, respectively. If hd == nil, using the
+// fixed distance encoding associated with fixed Huffman blocks.
+func (f *decompressor) huffmanBytesBuffer() {
+ const (
+ stateInit = iota // Zero value must be stateInit
+ stateDict
+ )
+ fr := f.r.(*bytes.Buffer)
+ moreBits := func() error {
+ c, err := fr.ReadByte()
+ if err != nil {
+ return noEOF(err)
+ }
+ f.roffset++
+ f.b |= uint32(c) << f.nb
+ f.nb += 8
+ return nil
+ }
+
+ switch f.stepState {
+ case stateInit:
+ goto readLiteral
+ case stateDict:
+ goto copyHistory
+ }
+
+readLiteral:
+ // Read literal and/or (length, distance) according to RFC section 3.2.3.
+ {
+ var v int
+ {
+ // Inlined v, err := f.huffSym(f.hl)
+ // Since a huffmanDecoder can be empty or be composed of a degenerate tree
+ // with single element, huffSym must error on these two edge cases. In both
+ // cases, the chunks slice will be 0 for the invalid sequence, leading it
+ // satisfy the n == 0 check below.
+ n := uint(f.hl.maxRead)
+ // Optimization. Compiler isn't smart enough to keep f.b,f.nb in registers,
+ // but is smart enough to keep local variables in registers, so use nb and b,
+ // inline call to moreBits and reassign b,nb back to f on return.
+ nb, b := f.nb, f.b
+ for {
+ for nb < n {
+ c, err := fr.ReadByte()
+ if err != nil {
+ f.b = b
+ f.nb = nb
+ f.err = noEOF(err)
+ return
+ }
+ f.roffset++
+ b |= uint32(c) << (nb & 31)
+ nb += 8
+ }
+ chunk := f.hl.chunks[b&(huffmanNumChunks-1)]
+ n = uint(chunk & huffmanCountMask)
+ if n > huffmanChunkBits {
+ chunk = f.hl.links[chunk>>huffmanValueShift][(b>>huffmanChunkBits)&f.hl.linkMask]
+ n = uint(chunk & huffmanCountMask)
+ }
+ if n <= nb {
+ if n == 0 {
+ f.b = b
+ f.nb = nb
+ if debugDecode {
+ fmt.Println("huffsym: n==0")
+ }
+ f.err = CorruptInputError(f.roffset)
+ return
+ }
+ f.b = b >> (n & 31)
+ f.nb = nb - n
+ v = int(chunk >> huffmanValueShift)
+ break
+ }
+ }
+ }
+
+ var n uint // number of bits extra
+ var length int
+ var err error
+ switch {
+ case v < 256:
+ f.dict.writeByte(byte(v))
+ if f.dict.availWrite() == 0 {
+ f.toRead = f.dict.readFlush()
+ f.step = (*decompressor).huffmanBytesBuffer
+ f.stepState = stateInit
+ return
+ }
+ goto readLiteral
+ case v == 256:
+ f.finishBlock()
+ return
+ // otherwise, reference to older data
+ case v < 265:
+ length = v - (257 - 3)
+ n = 0
+ case v < 269:
+ length = v*2 - (265*2 - 11)
+ n = 1
+ case v < 273:
+ length = v*4 - (269*4 - 19)
+ n = 2
+ case v < 277:
+ length = v*8 - (273*8 - 35)
+ n = 3
+ case v < 281:
+ length = v*16 - (277*16 - 67)
+ n = 4
+ case v < 285:
+ length = v*32 - (281*32 - 131)
+ n = 5
+ case v < maxNumLit:
+ length = 258
+ n = 0
+ default:
+ if debugDecode {
+ fmt.Println(v, ">= maxNumLit")
+ }
+ f.err = CorruptInputError(f.roffset)
+ return
+ }
+ if n > 0 {
+ for f.nb < n {
+ if err = moreBits(); err != nil {
+ if debugDecode {
+ fmt.Println("morebits n>0:", err)
+ }
+ f.err = err
+ return
+ }
+ }
+ length += int(f.b & uint32(1<<n-1))
+ f.b >>= n
+ f.nb -= n
+ }
+
+ var dist int
+ if f.hd == nil {
+ for f.nb < 5 {
+ if err = moreBits(); err != nil {
+ if debugDecode {
+ fmt.Println("morebits f.nb<5:", err)
+ }
+ f.err = err
+ return
+ }
+ }
+ dist = int(bits.Reverse8(uint8(f.b & 0x1F << 3)))
+ f.b >>= 5
+ f.nb -= 5
+ } else {
+ if dist, err = f.huffSym(f.hd); err != nil {
+ if debugDecode {
+ fmt.Println("huffsym:", err)
+ }
+ f.err = err
+ return
+ }
+ }
+
+ switch {
+ case dist < 4:
+ dist++
+ case dist < maxNumDist:
+ nb := uint(dist-2) >> 1
+ // have 1 bit in bottom of dist, need nb more.
+ extra := (dist & 1) << nb
+ for f.nb < nb {
+ if err = moreBits(); err != nil {
+ if debugDecode {
+ fmt.Println("morebits f.nb<nb:", err)
+ }
+ f.err = err
+ return
+ }
+ }
+ extra |= int(f.b & uint32(1<<nb-1))
+ f.b >>= nb
+ f.nb -= nb
+ dist = 1<<(nb+1) + 1 + extra
+ default:
+ if debugDecode {
+ fmt.Println("dist too big:", dist, maxNumDist)
+ }
+ f.err = CorruptInputError(f.roffset)
+ return
+ }
+
+ // No check on length; encoding can be prescient.
+ if dist > f.dict.histSize() {
+ if debugDecode {
+ fmt.Println("dist > f.dict.histSize():", dist, f.dict.histSize())
+ }
+ f.err = CorruptInputError(f.roffset)
+ return
+ }
+
+ f.copyLen, f.copyDist = length, dist
+ goto copyHistory
+ }
+
+copyHistory:
+ // Perform a backwards copy according to RFC section 3.2.3.
+ {
+ cnt := f.dict.tryWriteCopy(f.copyDist, f.copyLen)
+ if cnt == 0 {
+ cnt = f.dict.writeCopy(f.copyDist, f.copyLen)
+ }
+ f.copyLen -= cnt
+
+ if f.dict.availWrite() == 0 || f.copyLen > 0 {
+ f.toRead = f.dict.readFlush()
+ f.step = (*decompressor).huffmanBytesBuffer // We need to continue this work
+ f.stepState = stateDict
+ return
+ }
+ goto readLiteral
+ }
+}
+
+// Decode a single Huffman block from f.
+// hl and hd are the Huffman states for the lit/length values
+// and the distance values, respectively. If hd == nil, using the
+// fixed distance encoding associated with fixed Huffman blocks.
+func (f *decompressor) huffmanBytesReader() {
+ const (
+ stateInit = iota // Zero value must be stateInit
+ stateDict
+ )
+ fr := f.r.(*bytes.Reader)
+ moreBits := func() error {
+ c, err := fr.ReadByte()
+ if err != nil {
+ return noEOF(err)
+ }
+ f.roffset++
+ f.b |= uint32(c) << f.nb
+ f.nb += 8
+ return nil
+ }
+
+ switch f.stepState {
+ case stateInit:
+ goto readLiteral
+ case stateDict:
+ goto copyHistory
+ }
+
+readLiteral:
+ // Read literal and/or (length, distance) according to RFC section 3.2.3.
+ {
+ var v int
+ {
+ // Inlined v, err := f.huffSym(f.hl)
+ // Since a huffmanDecoder can be empty or be composed of a degenerate tree
+ // with single element, huffSym must error on these two edge cases. In both
+ // cases, the chunks slice will be 0 for the invalid sequence, leading it
+ // satisfy the n == 0 check below.
+ n := uint(f.hl.maxRead)
+ // Optimization. Compiler isn't smart enough to keep f.b,f.nb in registers,
+ // but is smart enough to keep local variables in registers, so use nb and b,
+ // inline call to moreBits and reassign b,nb back to f on return.
+ nb, b := f.nb, f.b
+ for {
+ for nb < n {
+ c, err := fr.ReadByte()
+ if err != nil {
+ f.b = b
+ f.nb = nb
+ f.err = noEOF(err)
+ return
+ }
+ f.roffset++
+ b |= uint32(c) << (nb & 31)
+ nb += 8
+ }
+ chunk := f.hl.chunks[b&(huffmanNumChunks-1)]
+ n = uint(chunk & huffmanCountMask)
+ if n > huffmanChunkBits {
+ chunk = f.hl.links[chunk>>huffmanValueShift][(b>>huffmanChunkBits)&f.hl.linkMask]
+ n = uint(chunk & huffmanCountMask)
+ }
+ if n <= nb {
+ if n == 0 {
+ f.b = b
+ f.nb = nb
+ if debugDecode {
+ fmt.Println("huffsym: n==0")
+ }
+ f.err = CorruptInputError(f.roffset)
+ return
+ }
+ f.b = b >> (n & 31)
+ f.nb = nb - n
+ v = int(chunk >> huffmanValueShift)
+ break
+ }
+ }
+ }
+
+ var n uint // number of bits extra
+ var length int
+ var err error
+ switch {
+ case v < 256:
+ f.dict.writeByte(byte(v))
+ if f.dict.availWrite() == 0 {
+ f.toRead = f.dict.readFlush()
+ f.step = (*decompressor).huffmanBytesReader
+ f.stepState = stateInit
+ return
+ }
+ goto readLiteral
+ case v == 256:
+ f.finishBlock()
+ return
+ // otherwise, reference to older data
+ case v < 265:
+ length = v - (257 - 3)
+ n = 0
+ case v < 269:
+ length = v*2 - (265*2 - 11)
+ n = 1
+ case v < 273:
+ length = v*4 - (269*4 - 19)
+ n = 2
+ case v < 277:
+ length = v*8 - (273*8 - 35)
+ n = 3
+ case v < 281:
+ length = v*16 - (277*16 - 67)
+ n = 4
+ case v < 285:
+ length = v*32 - (281*32 - 131)
+ n = 5
+ case v < maxNumLit:
+ length = 258
+ n = 0
+ default:
+ if debugDecode {
+ fmt.Println(v, ">= maxNumLit")
+ }
+ f.err = CorruptInputError(f.roffset)
+ return
+ }
+ if n > 0 {
+ for f.nb < n {
+ if err = moreBits(); err != nil {
+ if debugDecode {
+ fmt.Println("morebits n>0:", err)
+ }
+ f.err = err
+ return
+ }
+ }
+ length += int(f.b & uint32(1<<n-1))
+ f.b >>= n
+ f.nb -= n
+ }
+
+ var dist int
+ if f.hd == nil {
+ for f.nb < 5 {
+ if err = moreBits(); err != nil {
+ if debugDecode {
+ fmt.Println("morebits f.nb<5:", err)
+ }
+ f.err = err
+ return
+ }
+ }
+ dist = int(bits.Reverse8(uint8(f.b & 0x1F << 3)))
+ f.b >>= 5
+ f.nb -= 5
+ } else {
+ if dist, err = f.huffSym(f.hd); err != nil {
+ if debugDecode {
+ fmt.Println("huffsym:", err)
+ }
+ f.err = err
+ return
+ }
+ }
+
+ switch {
+ case dist < 4:
+ dist++
+ case dist < maxNumDist:
+ nb := uint(dist-2) >> 1
+ // have 1 bit in bottom of dist, need nb more.
+ extra := (dist & 1) << nb
+ for f.nb < nb {
+ if err = moreBits(); err != nil {
+ if debugDecode {
+ fmt.Println("morebits f.nb<nb:", err)
+ }
+ f.err = err
+ return
+ }
+ }
+ extra |= int(f.b & uint32(1<<nb-1))
+ f.b >>= nb
+ f.nb -= nb
+ dist = 1<<(nb+1) + 1 + extra
+ default:
+ if debugDecode {
+ fmt.Println("dist too big:", dist, maxNumDist)
+ }
+ f.err = CorruptInputError(f.roffset)
+ return
+ }
+
+ // No check on length; encoding can be prescient.
+ if dist > f.dict.histSize() {
+ if debugDecode {
+ fmt.Println("dist > f.dict.histSize():", dist, f.dict.histSize())
+ }
+ f.err = CorruptInputError(f.roffset)
+ return
+ }
+
+ f.copyLen, f.copyDist = length, dist
+ goto copyHistory
+ }
+
+copyHistory:
+ // Perform a backwards copy according to RFC section 3.2.3.
+ {
+ cnt := f.dict.tryWriteCopy(f.copyDist, f.copyLen)
+ if cnt == 0 {
+ cnt = f.dict.writeCopy(f.copyDist, f.copyLen)
+ }
+ f.copyLen -= cnt
+
+ if f.dict.availWrite() == 0 || f.copyLen > 0 {
+ f.toRead = f.dict.readFlush()
+ f.step = (*decompressor).huffmanBytesReader // We need to continue this work
+ f.stepState = stateDict
+ return
+ }
+ goto readLiteral
+ }
+}
+
+// Decode a single Huffman block from f.
+// hl and hd are the Huffman states for the lit/length values
+// and the distance values, respectively. If hd == nil, using the
+// fixed distance encoding associated with fixed Huffman blocks.
+func (f *decompressor) huffmanBufioReader() {
+ const (
+ stateInit = iota // Zero value must be stateInit
+ stateDict
+ )
+ fr := f.r.(*bufio.Reader)
+ moreBits := func() error {
+ c, err := fr.ReadByte()
+ if err != nil {
+ return noEOF(err)
+ }
+ f.roffset++
+ f.b |= uint32(c) << f.nb
+ f.nb += 8
+ return nil
+ }
+
+ switch f.stepState {
+ case stateInit:
+ goto readLiteral
+ case stateDict:
+ goto copyHistory
+ }
+
+readLiteral:
+ // Read literal and/or (length, distance) according to RFC section 3.2.3.
+ {
+ var v int
+ {
+ // Inlined v, err := f.huffSym(f.hl)
+ // Since a huffmanDecoder can be empty or be composed of a degenerate tree
+ // with single element, huffSym must error on these two edge cases. In both
+ // cases, the chunks slice will be 0 for the invalid sequence, leading it
+ // satisfy the n == 0 check below.
+ n := uint(f.hl.maxRead)
+ // Optimization. Compiler isn't smart enough to keep f.b,f.nb in registers,
+ // but is smart enough to keep local variables in registers, so use nb and b,
+ // inline call to moreBits and reassign b,nb back to f on return.
+ nb, b := f.nb, f.b
+ for {
+ for nb < n {
+ c, err := fr.ReadByte()
+ if err != nil {
+ f.b = b
+ f.nb = nb
+ f.err = noEOF(err)
+ return
+ }
+ f.roffset++
+ b |= uint32(c) << (nb & 31)
+ nb += 8
+ }
+ chunk := f.hl.chunks[b&(huffmanNumChunks-1)]
+ n = uint(chunk & huffmanCountMask)
+ if n > huffmanChunkBits {
+ chunk = f.hl.links[chunk>>huffmanValueShift][(b>>huffmanChunkBits)&f.hl.linkMask]
+ n = uint(chunk & huffmanCountMask)
+ }
+ if n <= nb {
+ if n == 0 {
+ f.b = b
+ f.nb = nb
+ if debugDecode {
+ fmt.Println("huffsym: n==0")
+ }
+ f.err = CorruptInputError(f.roffset)
+ return
+ }
+ f.b = b >> (n & 31)
+ f.nb = nb - n
+ v = int(chunk >> huffmanValueShift)
+ break
+ }
+ }
+ }
+
+ var n uint // number of bits extra
+ var length int
+ var err error
+ switch {
+ case v < 256:
+ f.dict.writeByte(byte(v))
+ if f.dict.availWrite() == 0 {
+ f.toRead = f.dict.readFlush()
+ f.step = (*decompressor).huffmanBufioReader
+ f.stepState = stateInit
+ return
+ }
+ goto readLiteral
+ case v == 256:
+ f.finishBlock()
+ return
+ // otherwise, reference to older data
+ case v < 265:
+ length = v - (257 - 3)
+ n = 0
+ case v < 269:
+ length = v*2 - (265*2 - 11)
+ n = 1
+ case v < 273:
+ length = v*4 - (269*4 - 19)
+ n = 2
+ case v < 277:
+ length = v*8 - (273*8 - 35)
+ n = 3
+ case v < 281:
+ length = v*16 - (277*16 - 67)
+ n = 4
+ case v < 285:
+ length = v*32 - (281*32 - 131)
+ n = 5
+ case v < maxNumLit:
+ length = 258
+ n = 0
+ default:
+ if debugDecode {
+ fmt.Println(v, ">= maxNumLit")
+ }
+ f.err = CorruptInputError(f.roffset)
+ return
+ }
+ if n > 0 {
+ for f.nb < n {
+ if err = moreBits(); err != nil {
+ if debugDecode {
+ fmt.Println("morebits n>0:", err)
+ }
+ f.err = err
+ return
+ }
+ }
+ length += int(f.b & uint32(1<<n-1))
+ f.b >>= n
+ f.nb -= n
+ }
+
+ var dist int
+ if f.hd == nil {
+ for f.nb < 5 {
+ if err = moreBits(); err != nil {
+ if debugDecode {
+ fmt.Println("morebits f.nb<5:", err)
+ }
+ f.err = err
+ return
+ }
+ }
+ dist = int(bits.Reverse8(uint8(f.b & 0x1F << 3)))
+ f.b >>= 5
+ f.nb -= 5
+ } else {
+ if dist, err = f.huffSym(f.hd); err != nil {
+ if debugDecode {
+ fmt.Println("huffsym:", err)
+ }
+ f.err = err
+ return
+ }
+ }
+
+ switch {
+ case dist < 4:
+ dist++
+ case dist < maxNumDist:
+ nb := uint(dist-2) >> 1
+ // have 1 bit in bottom of dist, need nb more.
+ extra := (dist & 1) << nb
+ for f.nb < nb {
+ if err = moreBits(); err != nil {
+ if debugDecode {
+ fmt.Println("morebits f.nb<nb:", err)
+ }
+ f.err = err
+ return
+ }
+ }
+ extra |= int(f.b & uint32(1<<nb-1))
+ f.b >>= nb
+ f.nb -= nb
+ dist = 1<<(nb+1) + 1 + extra
+ default:
+ if debugDecode {
+ fmt.Println("dist too big:", dist, maxNumDist)
+ }
+ f.err = CorruptInputError(f.roffset)
+ return
+ }
+
+ // No check on length; encoding can be prescient.
+ if dist > f.dict.histSize() {
+ if debugDecode {
+ fmt.Println("dist > f.dict.histSize():", dist, f.dict.histSize())
+ }
+ f.err = CorruptInputError(f.roffset)
+ return
+ }
+
+ f.copyLen, f.copyDist = length, dist
+ goto copyHistory
+ }
+
+copyHistory:
+ // Perform a backwards copy according to RFC section 3.2.3.
+ {
+ cnt := f.dict.tryWriteCopy(f.copyDist, f.copyLen)
+ if cnt == 0 {
+ cnt = f.dict.writeCopy(f.copyDist, f.copyLen)
+ }
+ f.copyLen -= cnt
+
+ if f.dict.availWrite() == 0 || f.copyLen > 0 {
+ f.toRead = f.dict.readFlush()
+ f.step = (*decompressor).huffmanBufioReader // We need to continue this work
+ f.stepState = stateDict
+ return
+ }
+ goto readLiteral
+ }
+}
+
+// Decode a single Huffman block from f.
+// hl and hd are the Huffman states for the lit/length values
+// and the distance values, respectively. If hd == nil, using the
+// fixed distance encoding associated with fixed Huffman blocks.
+func (f *decompressor) huffmanStringsReader() {
+ const (
+ stateInit = iota // Zero value must be stateInit
+ stateDict
+ )
+ fr := f.r.(*strings.Reader)
+ moreBits := func() error {
+ c, err := fr.ReadByte()
+ if err != nil {
+ return noEOF(err)
+ }
+ f.roffset++
+ f.b |= uint32(c) << f.nb
+ f.nb += 8
+ return nil
+ }
+
+ switch f.stepState {
+ case stateInit:
+ goto readLiteral
+ case stateDict:
+ goto copyHistory
+ }
+
+readLiteral:
+ // Read literal and/or (length, distance) according to RFC section 3.2.3.
+ {
+ var v int
+ {
+ // Inlined v, err := f.huffSym(f.hl)
+ // Since a huffmanDecoder can be empty or be composed of a degenerate tree
+ // with single element, huffSym must error on these two edge cases. In both
+ // cases, the chunks slice will be 0 for the invalid sequence, leading it
+ // satisfy the n == 0 check below.
+ n := uint(f.hl.maxRead)
+ // Optimization. Compiler isn't smart enough to keep f.b,f.nb in registers,
+ // but is smart enough to keep local variables in registers, so use nb and b,
+ // inline call to moreBits and reassign b,nb back to f on return.
+ nb, b := f.nb, f.b
+ for {
+ for nb < n {
+ c, err := fr.ReadByte()
+ if err != nil {
+ f.b = b
+ f.nb = nb
+ f.err = noEOF(err)
+ return
+ }
+ f.roffset++
+ b |= uint32(c) << (nb & 31)
+ nb += 8
+ }
+ chunk := f.hl.chunks[b&(huffmanNumChunks-1)]
+ n = uint(chunk & huffmanCountMask)
+ if n > huffmanChunkBits {
+ chunk = f.hl.links[chunk>>huffmanValueShift][(b>>huffmanChunkBits)&f.hl.linkMask]
+ n = uint(chunk & huffmanCountMask)
+ }
+ if n <= nb {
+ if n == 0 {
+ f.b = b
+ f.nb = nb
+ if debugDecode {
+ fmt.Println("huffsym: n==0")
+ }
+ f.err = CorruptInputError(f.roffset)
+ return
+ }
+ f.b = b >> (n & 31)
+ f.nb = nb - n
+ v = int(chunk >> huffmanValueShift)
+ break
+ }
+ }
+ }
+
+ var n uint // number of bits extra
+ var length int
+ var err error
+ switch {
+ case v < 256:
+ f.dict.writeByte(byte(v))
+ if f.dict.availWrite() == 0 {
+ f.toRead = f.dict.readFlush()
+ f.step = (*decompressor).huffmanStringsReader
+ f.stepState = stateInit
+ return
+ }
+ goto readLiteral
+ case v == 256:
+ f.finishBlock()
+ return
+ // otherwise, reference to older data
+ case v < 265:
+ length = v - (257 - 3)
+ n = 0
+ case v < 269:
+ length = v*2 - (265*2 - 11)
+ n = 1
+ case v < 273:
+ length = v*4 - (269*4 - 19)
+ n = 2
+ case v < 277:
+ length = v*8 - (273*8 - 35)
+ n = 3
+ case v < 281:
+ length = v*16 - (277*16 - 67)
+ n = 4
+ case v < 285:
+ length = v*32 - (281*32 - 131)
+ n = 5
+ case v < maxNumLit:
+ length = 258
+ n = 0
+ default:
+ if debugDecode {
+ fmt.Println(v, ">= maxNumLit")
+ }
+ f.err = CorruptInputError(f.roffset)
+ return
+ }
+ if n > 0 {
+ for f.nb < n {
+ if err = moreBits(); err != nil {
+ if debugDecode {
+ fmt.Println("morebits n>0:", err)
+ }
+ f.err = err
+ return
+ }
+ }
+ length += int(f.b & uint32(1<<n-1))
+ f.b >>= n
+ f.nb -= n
+ }
+
+ var dist int
+ if f.hd == nil {
+ for f.nb < 5 {
+ if err = moreBits(); err != nil {
+ if debugDecode {
+ fmt.Println("morebits f.nb<5:", err)
+ }
+ f.err = err
+ return
+ }
+ }
+ dist = int(bits.Reverse8(uint8(f.b & 0x1F << 3)))
+ f.b >>= 5
+ f.nb -= 5
+ } else {
+ if dist, err = f.huffSym(f.hd); err != nil {
+ if debugDecode {
+ fmt.Println("huffsym:", err)
+ }
+ f.err = err
+ return
+ }
+ }
+
+ switch {
+ case dist < 4:
+ dist++
+ case dist < maxNumDist:
+ nb := uint(dist-2) >> 1
+ // have 1 bit in bottom of dist, need nb more.
+ extra := (dist & 1) << nb
+ for f.nb < nb {
+ if err = moreBits(); err != nil {
+ if debugDecode {
+ fmt.Println("morebits f.nb<nb:", err)
+ }
+ f.err = err
+ return
+ }
+ }
+ extra |= int(f.b & uint32(1<<nb-1))
+ f.b >>= nb
+ f.nb -= nb
+ dist = 1<<(nb+1) + 1 + extra
+ default:
+ if debugDecode {
+ fmt.Println("dist too big:", dist, maxNumDist)
+ }
+ f.err = CorruptInputError(f.roffset)
+ return
+ }
+
+ // No check on length; encoding can be prescient.
+ if dist > f.dict.histSize() {
+ if debugDecode {
+ fmt.Println("dist > f.dict.histSize():", dist, f.dict.histSize())
+ }
+ f.err = CorruptInputError(f.roffset)
+ return
+ }
+
+ f.copyLen, f.copyDist = length, dist
+ goto copyHistory
+ }
+
+copyHistory:
+ // Perform a backwards copy according to RFC section 3.2.3.
+ {
+ cnt := f.dict.tryWriteCopy(f.copyDist, f.copyLen)
+ if cnt == 0 {
+ cnt = f.dict.writeCopy(f.copyDist, f.copyLen)
+ }
+ f.copyLen -= cnt
+
+ if f.dict.availWrite() == 0 || f.copyLen > 0 {
+ f.toRead = f.dict.readFlush()
+ f.step = (*decompressor).huffmanStringsReader // We need to continue this work
+ f.stepState = stateDict
+ return
+ }
+ goto readLiteral
+ }
+}
+
+func (f *decompressor) huffmanBlockDecoder() func() {
+ switch f.r.(type) {
+ case *bytes.Buffer:
+ return f.huffmanBytesBuffer
+ case *bytes.Reader:
+ return f.huffmanBytesReader
+ case *bufio.Reader:
+ return f.huffmanBufioReader
+ case *strings.Reader:
+ return f.huffmanStringsReader
+ default:
+ return f.huffmanBlockGeneric
+ }
+}
diff --git a/vendor/github.com/klauspost/compress/flate/level1.go b/vendor/github.com/klauspost/compress/flate/level1.go
index 20de8f11f..1e5eea396 100644
--- a/vendor/github.com/klauspost/compress/flate/level1.go
+++ b/vendor/github.com/klauspost/compress/flate/level1.go
@@ -1,5 +1,7 @@
package flate
+import "fmt"
+
// fastGen maintains the table for matches,
// and the previous byte block for level 2.
// This is the generic implementation.
@@ -14,6 +16,9 @@ func (e *fastEncL1) Encode(dst *tokens, src []byte) {
inputMargin = 12 - 1
minNonLiteralBlockSize = 1 + 1 + inputMargin
)
+ if debugDeflate && e.cur < 0 {
+ panic(fmt.Sprint("e.cur < 0: ", e.cur))
+ }
// Protect against e.cur wraparound.
for e.cur >= bufferReset {
@@ -76,12 +81,12 @@ func (e *fastEncL1) Encode(dst *tokens, src []byte) {
}
now := load6432(src, nextS)
- e.table[nextHash] = tableEntry{offset: s + e.cur, val: cv}
+ e.table[nextHash] = tableEntry{offset: s + e.cur}
nextHash = hash(uint32(now))
offset := s - (candidate.offset - e.cur)
- if offset < maxMatchOffset && cv == candidate.val {
- e.table[nextHash] = tableEntry{offset: nextS + e.cur, val: uint32(now)}
+ if offset < maxMatchOffset && cv == load3232(src, candidate.offset-e.cur) {
+ e.table[nextHash] = tableEntry{offset: nextS + e.cur}
break
}
@@ -91,11 +96,11 @@ func (e *fastEncL1) Encode(dst *tokens, src []byte) {
nextS++
candidate = e.table[nextHash]
now >>= 8
- e.table[nextHash] = tableEntry{offset: s + e.cur, val: cv}
+ e.table[nextHash] = tableEntry{offset: s + e.cur}
offset = s - (candidate.offset - e.cur)
- if offset < maxMatchOffset && cv == candidate.val {
- e.table[nextHash] = tableEntry{offset: nextS + e.cur, val: uint32(now)}
+ if offset < maxMatchOffset && cv == load3232(src, candidate.offset-e.cur) {
+ e.table[nextHash] = tableEntry{offset: nextS + e.cur}
break
}
cv = uint32(now)
@@ -134,7 +139,7 @@ func (e *fastEncL1) Encode(dst *tokens, src []byte) {
// Index first pair after match end.
if int(s+l+4) < len(src) {
cv := load3232(src, s)
- e.table[hash(cv)] = tableEntry{offset: s + e.cur, val: cv}
+ e.table[hash(cv)] = tableEntry{offset: s + e.cur}
}
goto emitRemainder
}
@@ -148,14 +153,14 @@ func (e *fastEncL1) Encode(dst *tokens, src []byte) {
x := load6432(src, s-2)
o := e.cur + s - 2
prevHash := hash(uint32(x))
- e.table[prevHash] = tableEntry{offset: o, val: uint32(x)}
+ e.table[prevHash] = tableEntry{offset: o}
x >>= 16
currHash := hash(uint32(x))
candidate = e.table[currHash]
- e.table[currHash] = tableEntry{offset: o + 2, val: uint32(x)}
+ e.table[currHash] = tableEntry{offset: o + 2}
offset := s - (candidate.offset - e.cur)
- if offset > maxMatchOffset || uint32(x) != candidate.val {
+ if offset > maxMatchOffset || uint32(x) != load3232(src, candidate.offset-e.cur) {
cv = uint32(x >> 8)
s++
break
diff --git a/vendor/github.com/klauspost/compress/flate/level2.go b/vendor/github.com/klauspost/compress/flate/level2.go
index 7c824431e..5b986a194 100644
--- a/vendor/github.com/klauspost/compress/flate/level2.go
+++ b/vendor/github.com/klauspost/compress/flate/level2.go
@@ -1,5 +1,7 @@
package flate
+import "fmt"
+
// fastGen maintains the table for matches,
// and the previous byte block for level 2.
// This is the generic implementation.
@@ -16,6 +18,10 @@ func (e *fastEncL2) Encode(dst *tokens, src []byte) {
minNonLiteralBlockSize = 1 + 1 + inputMargin
)
+ if debugDeflate && e.cur < 0 {
+ panic(fmt.Sprint("e.cur < 0: ", e.cur))
+ }
+
// Protect against e.cur wraparound.
for e.cur >= bufferReset {
if len(e.hist) == 0 {
@@ -77,12 +83,12 @@ func (e *fastEncL2) Encode(dst *tokens, src []byte) {
}
candidate = e.table[nextHash]
now := load6432(src, nextS)
- e.table[nextHash] = tableEntry{offset: s + e.cur, val: cv}
+ e.table[nextHash] = tableEntry{offset: s + e.cur}
nextHash = hash4u(uint32(now), bTableBits)
offset := s - (candidate.offset - e.cur)
- if offset < maxMatchOffset && cv == candidate.val {
- e.table[nextHash] = tableEntry{offset: nextS + e.cur, val: uint32(now)}
+ if offset < maxMatchOffset && cv == load3232(src, candidate.offset-e.cur) {
+ e.table[nextHash] = tableEntry{offset: nextS + e.cur}
break
}
@@ -92,10 +98,10 @@ func (e *fastEncL2) Encode(dst *tokens, src []byte) {
nextS++
candidate = e.table[nextHash]
now >>= 8
- e.table[nextHash] = tableEntry{offset: s + e.cur, val: cv}
+ e.table[nextHash] = tableEntry{offset: s + e.cur}
offset = s - (candidate.offset - e.cur)
- if offset < maxMatchOffset && cv == candidate.val {
+ if offset < maxMatchOffset && cv == load3232(src, candidate.offset-e.cur) {
break
}
cv = uint32(now)
@@ -142,7 +148,7 @@ func (e *fastEncL2) Encode(dst *tokens, src []byte) {
// Index first pair after match end.
if int(s+l+4) < len(src) {
cv := load3232(src, s)
- e.table[hash4u(cv, bTableBits)] = tableEntry{offset: s + e.cur, val: cv}
+ e.table[hash4u(cv, bTableBits)] = tableEntry{offset: s + e.cur}
}
goto emitRemainder
}
@@ -151,15 +157,15 @@ func (e *fastEncL2) Encode(dst *tokens, src []byte) {
for i := s - l + 2; i < s-5; i += 7 {
x := load6432(src, int32(i))
nextHash := hash4u(uint32(x), bTableBits)
- e.table[nextHash] = tableEntry{offset: e.cur + i, val: uint32(x)}
+ e.table[nextHash] = tableEntry{offset: e.cur + i}
// Skip one
x >>= 16
nextHash = hash4u(uint32(x), bTableBits)
- e.table[nextHash] = tableEntry{offset: e.cur + i + 2, val: uint32(x)}
+ e.table[nextHash] = tableEntry{offset: e.cur + i + 2}
// Skip one
x >>= 16
nextHash = hash4u(uint32(x), bTableBits)
- e.table[nextHash] = tableEntry{offset: e.cur + i + 4, val: uint32(x)}
+ e.table[nextHash] = tableEntry{offset: e.cur + i + 4}
}
// We could immediately start working at s now, but to improve
@@ -172,14 +178,14 @@ func (e *fastEncL2) Encode(dst *tokens, src []byte) {
o := e.cur + s - 2
prevHash := hash4u(uint32(x), bTableBits)
prevHash2 := hash4u(uint32(x>>8), bTableBits)
- e.table[prevHash] = tableEntry{offset: o, val: uint32(x)}
- e.table[prevHash2] = tableEntry{offset: o + 1, val: uint32(x >> 8)}
+ e.table[prevHash] = tableEntry{offset: o}
+ e.table[prevHash2] = tableEntry{offset: o + 1}
currHash := hash4u(uint32(x>>16), bTableBits)
candidate = e.table[currHash]
- e.table[currHash] = tableEntry{offset: o + 2, val: uint32(x >> 16)}
+ e.table[currHash] = tableEntry{offset: o + 2}
offset := s - (candidate.offset - e.cur)
- if offset > maxMatchOffset || uint32(x>>16) != candidate.val {
+ if offset > maxMatchOffset || uint32(x>>16) != load3232(src, candidate.offset-e.cur) {
cv = uint32(x >> 24)
s++
break
diff --git a/vendor/github.com/klauspost/compress/flate/level3.go b/vendor/github.com/klauspost/compress/flate/level3.go
index 4153d24c9..c22b4244a 100644
--- a/vendor/github.com/klauspost/compress/flate/level3.go
+++ b/vendor/github.com/klauspost/compress/flate/level3.go
@@ -1,5 +1,7 @@
package flate
+import "fmt"
+
// fastEncL3
type fastEncL3 struct {
fastGen
@@ -13,6 +15,10 @@ func (e *fastEncL3) Encode(dst *tokens, src []byte) {
minNonLiteralBlockSize = 1 + 1 + inputMargin
)
+ if debugDeflate && e.cur < 0 {
+ panic(fmt.Sprint("e.cur < 0: ", e.cur))
+ }
+
// Protect against e.cur wraparound.
for e.cur >= bufferReset {
if len(e.hist) == 0 {
@@ -75,22 +81,26 @@ func (e *fastEncL3) Encode(dst *tokens, src []byte) {
}
candidates := e.table[nextHash]
now := load3232(src, nextS)
- e.table[nextHash] = tableEntryPrev{Prev: candidates.Cur, Cur: tableEntry{offset: s + e.cur, val: cv}}
+
+ // Safe offset distance until s + 4...
+ minOffset := e.cur + s - (maxMatchOffset - 4)
+ e.table[nextHash] = tableEntryPrev{Prev: candidates.Cur, Cur: tableEntry{offset: s + e.cur}}
// Check both candidates
candidate = candidates.Cur
- offset := s - (candidate.offset - e.cur)
- if cv == candidate.val {
- if offset > maxMatchOffset {
- cv = now
- // Previous will also be invalid, we have nothing.
- continue
- }
- o2 := s - (candidates.Prev.offset - e.cur)
- if cv != candidates.Prev.val || o2 > maxMatchOffset {
+ if candidate.offset < minOffset {
+ cv = now
+ // Previous will also be invalid, we have nothing.
+ continue
+ }
+
+ if cv == load3232(src, candidate.offset-e.cur) {
+ if candidates.Prev.offset < minOffset || cv != load3232(src, candidates.Prev.offset-e.cur) {
break
}
// Both match and are valid, pick longest.
+ offset := s - (candidate.offset - e.cur)
+ o2 := s - (candidates.Prev.offset - e.cur)
l1, l2 := matchLen(src[s+4:], src[s-offset+4:]), matchLen(src[s+4:], src[s-o2+4:])
if l2 > l1 {
candidate = candidates.Prev
@@ -100,11 +110,8 @@ func (e *fastEncL3) Encode(dst *tokens, src []byte) {
// We only check if value mismatches.
// Offset will always be invalid in other cases.
candidate = candidates.Prev
- if cv == candidate.val {
- offset := s - (candidate.offset - e.cur)
- if offset <= maxMatchOffset {
- break
- }
+ if candidate.offset > minOffset && cv == load3232(src, candidate.offset-e.cur) {
+ break
}
}
cv = now
@@ -152,7 +159,7 @@ func (e *fastEncL3) Encode(dst *tokens, src []byte) {
nextHash := hash(cv)
e.table[nextHash] = tableEntryPrev{
Prev: e.table[nextHash].Cur,
- Cur: tableEntry{offset: e.cur + t, val: cv},
+ Cur: tableEntry{offset: e.cur + t},
}
}
goto emitRemainder
@@ -164,21 +171,21 @@ func (e *fastEncL3) Encode(dst *tokens, src []byte) {
prevHash := hash(uint32(x))
e.table[prevHash] = tableEntryPrev{
Prev: e.table[prevHash].Cur,
- Cur: tableEntry{offset: e.cur + s - 3, val: uint32(x)},
+ Cur: tableEntry{offset: e.cur + s - 3},
}
x >>= 8
prevHash = hash(uint32(x))
e.table[prevHash] = tableEntryPrev{
Prev: e.table[prevHash].Cur,
- Cur: tableEntry{offset: e.cur + s - 2, val: uint32(x)},
+ Cur: tableEntry{offset: e.cur + s - 2},
}
x >>= 8
prevHash = hash(uint32(x))
e.table[prevHash] = tableEntryPrev{
Prev: e.table[prevHash].Cur,
- Cur: tableEntry{offset: e.cur + s - 1, val: uint32(x)},
+ Cur: tableEntry{offset: e.cur + s - 1},
}
x >>= 8
currHash := hash(uint32(x))
@@ -186,21 +193,18 @@ func (e *fastEncL3) Encode(dst *tokens, src []byte) {
cv = uint32(x)
e.table[currHash] = tableEntryPrev{
Prev: candidates.Cur,
- Cur: tableEntry{offset: s + e.cur, val: cv},
+ Cur: tableEntry{offset: s + e.cur},
}
// Check both candidates
candidate = candidates.Cur
- if cv == candidate.val {
- offset := s - (candidate.offset - e.cur)
- if offset <= maxMatchOffset {
- continue
- }
- } else {
+ minOffset := e.cur + s - (maxMatchOffset - 4)
+
+ if candidate.offset > minOffset && cv != load3232(src, candidate.offset-e.cur) {
// We only check if value mismatches.
// Offset will always be invalid in other cases.
candidate = candidates.Prev
- if cv == candidate.val {
+ if candidate.offset > minOffset && cv == load3232(src, candidate.offset-e.cur) {
offset := s - (candidate.offset - e.cur)
if offset <= maxMatchOffset {
continue
diff --git a/vendor/github.com/klauspost/compress/flate/level4.go b/vendor/github.com/klauspost/compress/flate/level4.go
index c689ac771..e62f0c02b 100644
--- a/vendor/github.com/klauspost/compress/flate/level4.go
+++ b/vendor/github.com/klauspost/compress/flate/level4.go
@@ -13,7 +13,9 @@ func (e *fastEncL4) Encode(dst *tokens, src []byte) {
inputMargin = 12 - 1
minNonLiteralBlockSize = 1 + 1 + inputMargin
)
-
+ if debugDeflate && e.cur < 0 {
+ panic(fmt.Sprint("e.cur < 0: ", e.cur))
+ }
// Protect against e.cur wraparound.
for e.cur >= bufferReset {
if len(e.hist) == 0 {
@@ -90,24 +92,24 @@ func (e *fastEncL4) Encode(dst *tokens, src []byte) {
sCandidate := e.table[nextHashS]
lCandidate := e.bTable[nextHashL]
next := load6432(src, nextS)
- entry := tableEntry{offset: s + e.cur, val: uint32(cv)}
+ entry := tableEntry{offset: s + e.cur}
e.table[nextHashS] = entry
e.bTable[nextHashL] = entry
t = lCandidate.offset - e.cur
- if s-t < maxMatchOffset && uint32(cv) == lCandidate.val {
+ if s-t < maxMatchOffset && uint32(cv) == load3232(src, lCandidate.offset-e.cur) {
// We got a long match. Use that.
break
}
t = sCandidate.offset - e.cur
- if s-t < maxMatchOffset && uint32(cv) == sCandidate.val {
+ if s-t < maxMatchOffset && uint32(cv) == load3232(src, sCandidate.offset-e.cur) {
// Found a 4 match...
lCandidate = e.bTable[hash7(next, tableBits)]
// If the next long is a candidate, check if we should use that instead...
lOff := nextS - (lCandidate.offset - e.cur)
- if lOff < maxMatchOffset && lCandidate.val == uint32(next) {
+ if lOff < maxMatchOffset && load3232(src, lCandidate.offset-e.cur) == uint32(next) {
l1, l2 := matchLen(src[s+4:], src[t+4:]), matchLen(src[nextS+4:], src[nextS-lOff+4:])
if l2 > l1 {
s = nextS
@@ -135,7 +137,7 @@ func (e *fastEncL4) Encode(dst *tokens, src []byte) {
if nextEmit < s {
emitLiteral(dst, src[nextEmit:s])
}
- if false {
+ if debugDeflate {
if t >= s {
panic("s-t")
}
@@ -158,8 +160,8 @@ func (e *fastEncL4) Encode(dst *tokens, src []byte) {
// Index first pair after match end.
if int(s+8) < len(src) {
cv := load6432(src, s)
- e.table[hash4x64(cv, tableBits)] = tableEntry{offset: s + e.cur, val: uint32(cv)}
- e.bTable[hash7(cv, tableBits)] = tableEntry{offset: s + e.cur, val: uint32(cv)}
+ e.table[hash4x64(cv, tableBits)] = tableEntry{offset: s + e.cur}
+ e.bTable[hash7(cv, tableBits)] = tableEntry{offset: s + e.cur}
}
goto emitRemainder
}
@@ -169,20 +171,20 @@ func (e *fastEncL4) Encode(dst *tokens, src []byte) {
i := nextS
if i < s-1 {
cv := load6432(src, i)
- t := tableEntry{offset: i + e.cur, val: uint32(cv)}
- t2 := tableEntry{val: uint32(cv >> 8), offset: t.offset + 1}
+ t := tableEntry{offset: i + e.cur}
+ t2 := tableEntry{offset: t.offset + 1}
e.bTable[hash7(cv, tableBits)] = t
e.bTable[hash7(cv>>8, tableBits)] = t2
- e.table[hash4u(t2.val, tableBits)] = t2
+ e.table[hash4u(uint32(cv>>8), tableBits)] = t2
i += 3
for ; i < s-1; i += 3 {
cv := load6432(src, i)
- t := tableEntry{offset: i + e.cur, val: uint32(cv)}
- t2 := tableEntry{val: uint32(cv >> 8), offset: t.offset + 1}
+ t := tableEntry{offset: i + e.cur}
+ t2 := tableEntry{offset: t.offset + 1}
e.bTable[hash7(cv, tableBits)] = t
e.bTable[hash7(cv>>8, tableBits)] = t2
- e.table[hash4u(t2.val, tableBits)] = t2
+ e.table[hash4u(uint32(cv>>8), tableBits)] = t2
}
}
}
@@ -193,8 +195,8 @@ func (e *fastEncL4) Encode(dst *tokens, src []byte) {
o := e.cur + s - 1
prevHashS := hash4x64(x, tableBits)
prevHashL := hash7(x, tableBits)
- e.table[prevHashS] = tableEntry{offset: o, val: uint32(x)}
- e.bTable[prevHashL] = tableEntry{offset: o, val: uint32(x)}
+ e.table[prevHashS] = tableEntry{offset: o}
+ e.bTable[prevHashL] = tableEntry{offset: o}
cv = x >> 8
}
diff --git a/vendor/github.com/klauspost/compress/flate/level5.go b/vendor/github.com/klauspost/compress/flate/level5.go
index 14a235612..d513f1ffd 100644
--- a/vendor/github.com/klauspost/compress/flate/level5.go
+++ b/vendor/github.com/klauspost/compress/flate/level5.go
@@ -13,6 +13,9 @@ func (e *fastEncL5) Encode(dst *tokens, src []byte) {
inputMargin = 12 - 1
minNonLiteralBlockSize = 1 + 1 + inputMargin
)
+ if debugDeflate && e.cur < 0 {
+ panic(fmt.Sprint("e.cur < 0: ", e.cur))
+ }
// Protect against e.cur wraparound.
for e.cur >= bufferReset {
@@ -97,7 +100,7 @@ func (e *fastEncL5) Encode(dst *tokens, src []byte) {
sCandidate := e.table[nextHashS]
lCandidate := e.bTable[nextHashL]
next := load6432(src, nextS)
- entry := tableEntry{offset: s + e.cur, val: uint32(cv)}
+ entry := tableEntry{offset: s + e.cur}
e.table[nextHashS] = entry
eLong := &e.bTable[nextHashL]
eLong.Cur, eLong.Prev = entry, eLong.Cur
@@ -107,14 +110,14 @@ func (e *fastEncL5) Encode(dst *tokens, src []byte) {
t = lCandidate.Cur.offset - e.cur
if s-t < maxMatchOffset {
- if uint32(cv) == lCandidate.Cur.val {
+ if uint32(cv) == load3232(src, lCandidate.Cur.offset-e.cur) {
// Store the next match
- e.table[nextHashS] = tableEntry{offset: nextS + e.cur, val: uint32(next)}
+ e.table[nextHashS] = tableEntry{offset: nextS + e.cur}
eLong := &e.bTable[nextHashL]
- eLong.Cur, eLong.Prev = tableEntry{offset: nextS + e.cur, val: uint32(next)}, eLong.Cur
+ eLong.Cur, eLong.Prev = tableEntry{offset: nextS + e.cur}, eLong.Cur
t2 := lCandidate.Prev.offset - e.cur
- if s-t2 < maxMatchOffset && uint32(cv) == lCandidate.Prev.val {
+ if s-t2 < maxMatchOffset && uint32(cv) == load3232(src, lCandidate.Prev.offset-e.cur) {
l = e.matchlen(s+4, t+4, src) + 4
ml1 := e.matchlen(s+4, t2+4, src) + 4
if ml1 > l {
@@ -126,30 +129,30 @@ func (e *fastEncL5) Encode(dst *tokens, src []byte) {
break
}
t = lCandidate.Prev.offset - e.cur
- if s-t < maxMatchOffset && uint32(cv) == lCandidate.Prev.val {
+ if s-t < maxMatchOffset && uint32(cv) == load3232(src, lCandidate.Prev.offset-e.cur) {
// Store the next match
- e.table[nextHashS] = tableEntry{offset: nextS + e.cur, val: uint32(next)}
+ e.table[nextHashS] = tableEntry{offset: nextS + e.cur}
eLong := &e.bTable[nextHashL]
- eLong.Cur, eLong.Prev = tableEntry{offset: nextS + e.cur, val: uint32(next)}, eLong.Cur
+ eLong.Cur, eLong.Prev = tableEntry{offset: nextS + e.cur}, eLong.Cur
break
}
}
t = sCandidate.offset - e.cur
- if s-t < maxMatchOffset && uint32(cv) == sCandidate.val {
+ if s-t < maxMatchOffset && uint32(cv) == load3232(src, sCandidate.offset-e.cur) {
// Found a 4 match...
l = e.matchlen(s+4, t+4, src) + 4
lCandidate = e.bTable[nextHashL]
// Store the next match
- e.table[nextHashS] = tableEntry{offset: nextS + e.cur, val: uint32(next)}
+ e.table[nextHashS] = tableEntry{offset: nextS + e.cur}
eLong := &e.bTable[nextHashL]
- eLong.Cur, eLong.Prev = tableEntry{offset: nextS + e.cur, val: uint32(next)}, eLong.Cur
+ eLong.Cur, eLong.Prev = tableEntry{offset: nextS + e.cur}, eLong.Cur
// If the next long is a candidate, use that...
t2 := lCandidate.Cur.offset - e.cur
if nextS-t2 < maxMatchOffset {
- if lCandidate.Cur.val == uint32(next) {
+ if load3232(src, lCandidate.Cur.offset-e.cur) == uint32(next) {
ml := e.matchlen(nextS+4, t2+4, src) + 4
if ml > l {
t = t2
@@ -160,7 +163,7 @@ func (e *fastEncL5) Encode(dst *tokens, src []byte) {
}
// If the previous long is a candidate, use that...
t2 = lCandidate.Prev.offset - e.cur
- if nextS-t2 < maxMatchOffset && lCandidate.Prev.val == uint32(next) {
+ if nextS-t2 < maxMatchOffset && load3232(src, lCandidate.Prev.offset-e.cur) == uint32(next) {
ml := e.matchlen(nextS+4, t2+4, src) + 4
if ml > l {
t = t2
@@ -194,7 +197,7 @@ func (e *fastEncL5) Encode(dst *tokens, src []byte) {
if nextEmit < s {
emitLiteral(dst, src[nextEmit:s])
}
- if false {
+ if debugDeflate {
if t >= s {
panic(fmt.Sprintln("s-t", s, t))
}
@@ -223,31 +226,31 @@ func (e *fastEncL5) Encode(dst *tokens, src []byte) {
i := s - l + 1
if i < s-1 {
cv := load6432(src, i)
- t := tableEntry{offset: i + e.cur, val: uint32(cv)}
+ t := tableEntry{offset: i + e.cur}
e.table[hash4x64(cv, tableBits)] = t
eLong := &e.bTable[hash7(cv, tableBits)]
eLong.Cur, eLong.Prev = t, eLong.Cur
// Do an long at i+1
cv >>= 8
- t = tableEntry{offset: t.offset + 1, val: uint32(cv)}
+ t = tableEntry{offset: t.offset + 1}
eLong = &e.bTable[hash7(cv, tableBits)]
eLong.Cur, eLong.Prev = t, eLong.Cur
// We only have enough bits for a short entry at i+2
cv >>= 8
- t = tableEntry{offset: t.offset + 1, val: uint32(cv)}
+ t = tableEntry{offset: t.offset + 1}
e.table[hash4x64(cv, tableBits)] = t
// Skip one - otherwise we risk hitting 's'
i += 4
for ; i < s-1; i += hashEvery {
cv := load6432(src, i)
- t := tableEntry{offset: i + e.cur, val: uint32(cv)}
- t2 := tableEntry{offset: t.offset + 1, val: uint32(cv >> 8)}
+ t := tableEntry{offset: i + e.cur}
+ t2 := tableEntry{offset: t.offset + 1}
eLong := &e.bTable[hash7(cv, tableBits)]
eLong.Cur, eLong.Prev = t, eLong.Cur
- e.table[hash4u(t2.val, tableBits)] = t2
+ e.table[hash4u(uint32(cv>>8), tableBits)] = t2
}
}
}
@@ -258,9 +261,9 @@ func (e *fastEncL5) Encode(dst *tokens, src []byte) {
o := e.cur + s - 1
prevHashS := hash4x64(x, tableBits)
prevHashL := hash7(x, tableBits)
- e.table[prevHashS] = tableEntry{offset: o, val: uint32(x)}
+ e.table[prevHashS] = tableEntry{offset: o}
eLong := &e.bTable[prevHashL]
- eLong.Cur, eLong.Prev = tableEntry{offset: o, val: uint32(x)}, eLong.Cur
+ eLong.Cur, eLong.Prev = tableEntry{offset: o}, eLong.Cur
cv = x >> 8
}
diff --git a/vendor/github.com/klauspost/compress/flate/level6.go b/vendor/github.com/klauspost/compress/flate/level6.go
index cad0c7df7..a52c80ea4 100644
--- a/vendor/github.com/klauspost/compress/flate/level6.go
+++ b/vendor/github.com/klauspost/compress/flate/level6.go
@@ -13,6 +13,9 @@ func (e *fastEncL6) Encode(dst *tokens, src []byte) {
inputMargin = 12 - 1
minNonLiteralBlockSize = 1 + 1 + inputMargin
)
+ if debugDeflate && e.cur < 0 {
+ panic(fmt.Sprint("e.cur < 0: ", e.cur))
+ }
// Protect against e.cur wraparound.
for e.cur >= bufferReset {
@@ -98,7 +101,7 @@ func (e *fastEncL6) Encode(dst *tokens, src []byte) {
sCandidate := e.table[nextHashS]
lCandidate := e.bTable[nextHashL]
next := load6432(src, nextS)
- entry := tableEntry{offset: s + e.cur, val: uint32(cv)}
+ entry := tableEntry{offset: s + e.cur}
e.table[nextHashS] = entry
eLong := &e.bTable[nextHashL]
eLong.Cur, eLong.Prev = entry, eLong.Cur
@@ -109,17 +112,17 @@ func (e *fastEncL6) Encode(dst *tokens, src []byte) {
t = lCandidate.Cur.offset - e.cur
if s-t < maxMatchOffset {
- if uint32(cv) == lCandidate.Cur.val {
+ if uint32(cv) == load3232(src, lCandidate.Cur.offset-e.cur) {
// Long candidate matches at least 4 bytes.
// Store the next match
- e.table[nextHashS] = tableEntry{offset: nextS + e.cur, val: uint32(next)}
+ e.table[nextHashS] = tableEntry{offset: nextS + e.cur}
eLong := &e.bTable[nextHashL]
- eLong.Cur, eLong.Prev = tableEntry{offset: nextS + e.cur, val: uint32(next)}, eLong.Cur
+ eLong.Cur, eLong.Prev = tableEntry{offset: nextS + e.cur}, eLong.Cur
// Check the previous long candidate as well.
t2 := lCandidate.Prev.offset - e.cur
- if s-t2 < maxMatchOffset && uint32(cv) == lCandidate.Prev.val {
+ if s-t2 < maxMatchOffset && uint32(cv) == load3232(src, lCandidate.Prev.offset-e.cur) {
l = e.matchlen(s+4, t+4, src) + 4
ml1 := e.matchlen(s+4, t2+4, src) + 4
if ml1 > l {
@@ -132,17 +135,17 @@ func (e *fastEncL6) Encode(dst *tokens, src []byte) {
}
// Current value did not match, but check if previous long value does.
t = lCandidate.Prev.offset - e.cur
- if s-t < maxMatchOffset && uint32(cv) == lCandidate.Prev.val {
+ if s-t < maxMatchOffset && uint32(cv) == load3232(src, lCandidate.Prev.offset-e.cur) {
// Store the next match
- e.table[nextHashS] = tableEntry{offset: nextS + e.cur, val: uint32(next)}
+ e.table[nextHashS] = tableEntry{offset: nextS + e.cur}
eLong := &e.bTable[nextHashL]
- eLong.Cur, eLong.Prev = tableEntry{offset: nextS + e.cur, val: uint32(next)}, eLong.Cur
+ eLong.Cur, eLong.Prev = tableEntry{offset: nextS + e.cur}, eLong.Cur
break
}
}
t = sCandidate.offset - e.cur
- if s-t < maxMatchOffset && uint32(cv) == sCandidate.val {
+ if s-t < maxMatchOffset && uint32(cv) == load3232(src, sCandidate.offset-e.cur) {
// Found a 4 match...
l = e.matchlen(s+4, t+4, src) + 4
@@ -150,9 +153,9 @@ func (e *fastEncL6) Encode(dst *tokens, src []byte) {
lCandidate = e.bTable[nextHashL]
// Store the next match
- e.table[nextHashS] = tableEntry{offset: nextS + e.cur, val: uint32(next)}
+ e.table[nextHashS] = tableEntry{offset: nextS + e.cur}
eLong := &e.bTable[nextHashL]
- eLong.Cur, eLong.Prev = tableEntry{offset: nextS + e.cur, val: uint32(next)}, eLong.Cur
+ eLong.Cur, eLong.Prev = tableEntry{offset: nextS + e.cur}, eLong.Cur
// Check repeat at s + repOff
const repOff = 1
@@ -171,7 +174,7 @@ func (e *fastEncL6) Encode(dst *tokens, src []byte) {
// If the next long is a candidate, use that...
t2 = lCandidate.Cur.offset - e.cur
if nextS-t2 < maxMatchOffset {
- if lCandidate.Cur.val == uint32(next) {
+ if load3232(src, lCandidate.Cur.offset-e.cur) == uint32(next) {
ml := e.matchlen(nextS+4, t2+4, src) + 4
if ml > l {
t = t2
@@ -182,7 +185,7 @@ func (e *fastEncL6) Encode(dst *tokens, src []byte) {
}
// If the previous long is a candidate, use that...
t2 = lCandidate.Prev.offset - e.cur
- if nextS-t2 < maxMatchOffset && lCandidate.Prev.val == uint32(next) {
+ if nextS-t2 < maxMatchOffset && load3232(src, lCandidate.Prev.offset-e.cur) == uint32(next) {
ml := e.matchlen(nextS+4, t2+4, src) + 4
if ml > l {
t = t2
@@ -241,9 +244,9 @@ func (e *fastEncL6) Encode(dst *tokens, src []byte) {
// Index after match end.
for i := nextS + 1; i < int32(len(src))-8; i += 2 {
cv := load6432(src, i)
- e.table[hash4x64(cv, tableBits)] = tableEntry{offset: i + e.cur, val: uint32(cv)}
+ e.table[hash4x64(cv, tableBits)] = tableEntry{offset: i + e.cur}
eLong := &e.bTable[hash7(cv, tableBits)]
- eLong.Cur, eLong.Prev = tableEntry{offset: i + e.cur, val: uint32(cv)}, eLong.Cur
+ eLong.Cur, eLong.Prev = tableEntry{offset: i + e.cur}, eLong.Cur
}
goto emitRemainder
}
@@ -252,8 +255,8 @@ func (e *fastEncL6) Encode(dst *tokens, src []byte) {
if true {
for i := nextS + 1; i < s-1; i += 2 {
cv := load6432(src, i)
- t := tableEntry{offset: i + e.cur, val: uint32(cv)}
- t2 := tableEntry{offset: t.offset + 1, val: uint32(cv >> 8)}
+ t := tableEntry{offset: i + e.cur}
+ t2 := tableEntry{offset: t.offset + 1}
eLong := &e.bTable[hash7(cv, tableBits)]
eLong2 := &e.bTable[hash7(cv>>8, tableBits)]
e.table[hash4x64(cv, tableBits)] = t
diff --git a/vendor/github.com/klauspost/compress/flate/stateless.go b/vendor/github.com/klauspost/compress/flate/stateless.go
index a47051197..53e899124 100644
--- a/vendor/github.com/klauspost/compress/flate/stateless.go
+++ b/vendor/github.com/klauspost/compress/flate/stateless.go
@@ -8,6 +8,8 @@ import (
const (
maxStatelessBlock = math.MaxInt16
+ // dictionary will be taken from maxStatelessBlock, so limit it.
+ maxStatelessDict = 8 << 10
slTableBits = 13
slTableSize = 1 << slTableBits
@@ -25,11 +27,11 @@ func (s *statelessWriter) Close() error {
}
s.closed = true
// Emit EOF block
- return StatelessDeflate(s.dst, nil, true)
+ return StatelessDeflate(s.dst, nil, true, nil)
}
func (s *statelessWriter) Write(p []byte) (n int, err error) {
- err = StatelessDeflate(s.dst, p, false)
+ err = StatelessDeflate(s.dst, p, false, nil)
if err != nil {
return 0, err
}
@@ -59,7 +61,10 @@ var bitWriterPool = sync.Pool{
// StatelessDeflate allows to compress directly to a Writer without retaining state.
// When returning everything will be flushed.
-func StatelessDeflate(out io.Writer, in []byte, eof bool) error {
+// Up to 8KB of an optional dictionary can be given which is presumed to presumed to precede the block.
+// Longer dictionaries will be truncated and will still produce valid output.
+// Sending nil dictionary is perfectly fine.
+func StatelessDeflate(out io.Writer, in []byte, eof bool, dict []byte) error {
var dst tokens
bw := bitWriterPool.Get().(*huffmanBitWriter)
bw.reset(out)
@@ -76,35 +81,53 @@ func StatelessDeflate(out io.Writer, in []byte, eof bool) error {
return bw.err
}
+ // Truncate dict
+ if len(dict) > maxStatelessDict {
+ dict = dict[len(dict)-maxStatelessDict:]
+ }
+
for len(in) > 0 {
todo := in
- if len(todo) > maxStatelessBlock {
- todo = todo[:maxStatelessBlock]
+ if len(todo) > maxStatelessBlock-len(dict) {
+ todo = todo[:maxStatelessBlock-len(dict)]
}
in = in[len(todo):]
+ uncompressed := todo
+ if len(dict) > 0 {
+ // combine dict and source
+ bufLen := len(todo) + len(dict)
+ combined := make([]byte, bufLen)
+ copy(combined, dict)
+ copy(combined[len(dict):], todo)
+ todo = combined
+ }
// Compress
- statelessEnc(&dst, todo)
+ statelessEnc(&dst, todo, int16(len(dict)))
isEof := eof && len(in) == 0
if dst.n == 0 {
- bw.writeStoredHeader(len(todo), isEof)
+ bw.writeStoredHeader(len(uncompressed), isEof)
if bw.err != nil {
return bw.err
}
- bw.writeBytes(todo)
- } else if int(dst.n) > len(todo)-len(todo)>>4 {
+ bw.writeBytes(uncompressed)
+ } else if int(dst.n) > len(uncompressed)-len(uncompressed)>>4 {
// If we removed less than 1/16th, huffman compress the block.
- bw.writeBlockHuff(isEof, todo, false)
+ bw.writeBlockHuff(isEof, uncompressed, len(in) == 0)
} else {
- bw.writeBlockDynamic(&dst, isEof, todo, false)
+ bw.writeBlockDynamic(&dst, isEof, uncompressed, len(in) == 0)
+ }
+ if len(in) > 0 {
+ // Retain a dict if we have more
+ dict = todo[len(todo)-maxStatelessDict:]
+ dst.Reset()
}
if bw.err != nil {
return bw.err
}
- dst.Reset()
}
if !eof {
- // Align.
+ // Align, only a stored block can do that.
bw.writeStoredHeader(0, false)
}
bw.flush()
@@ -130,7 +153,7 @@ func load6416(b []byte, i int16) uint64 {
uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56
}
-func statelessEnc(dst *tokens, src []byte) {
+func statelessEnc(dst *tokens, src []byte, startAt int16) {
const (
inputMargin = 12 - 1
minNonLiteralBlockSize = 1 + 1 + inputMargin
@@ -144,15 +167,23 @@ func statelessEnc(dst *tokens, src []byte) {
// This check isn't in the Snappy implementation, but there, the caller
// instead of the callee handles this case.
- if len(src) < minNonLiteralBlockSize {
+ if len(src)-int(startAt) < minNonLiteralBlockSize {
// We do not fill the token table.
// This will be picked up by caller.
- dst.n = uint16(len(src))
+ dst.n = 0
return
}
+ // Index until startAt
+ if startAt > 0 {
+ cv := load3232(src, 0)
+ for i := int16(0); i < startAt; i++ {
+ table[hashSL(cv)] = tableEntry{offset: i}
+ cv = (cv >> 8) | (uint32(src[i+4]) << 24)
+ }
+ }
- s := int16(1)
- nextEmit := int16(0)
+ s := startAt + 1
+ nextEmit := startAt
// sLimit is when to stop looking for offset/length copies. The inputMargin
// lets us use a fast path for emitLiteral in the main loop, while we are
// looking for copies.
diff --git a/vendor/github.com/klauspost/compress/flate/token.go b/vendor/github.com/klauspost/compress/flate/token.go
index b3df0d894..f9abf606d 100644
--- a/vendor/github.com/klauspost/compress/flate/token.go
+++ b/vendor/github.com/klauspost/compress/flate/token.go
@@ -184,9 +184,7 @@ func (t *tokens) indexTokens(in []token) {
t.Reset()
for _, tok := range in {
if tok < matchType {
- t.tokens[t.n] = tok
- t.litHist[tok]++
- t.n++
+ t.AddLiteral(tok.literal())
continue
}
t.AddMatch(uint32(tok.length()), tok.offset())
@@ -211,50 +209,60 @@ func (t *tokens) AddLiteral(lit byte) {
t.nLits++
}
+// from https://stackoverflow.com/a/28730362
+func mFastLog2(val float32) float32 {
+ ux := int32(math.Float32bits(val))
+ log2 := (float32)(((ux >> 23) & 255) - 128)
+ ux &= -0x7f800001
+ ux += 127 << 23
+ uval := math.Float32frombits(uint32(ux))
+ log2 += ((-0.34484843)*uval+2.02466578)*uval - 0.67487759
+ return log2
+}
+
// EstimatedBits will return an minimum size estimated by an *optimal*
// compression of the block.
// The size of the block
func (t *tokens) EstimatedBits() int {
- shannon := float64(0)
+ shannon := float32(0)
bits := int(0)
nMatches := 0
if t.nLits > 0 {
- invTotal := 1.0 / float64(t.nLits)
+ invTotal := 1.0 / float32(t.nLits)
for _, v := range t.litHist[:] {
if v > 0 {
- n := float64(v)
- shannon += math.Ceil(-math.Log2(n*invTotal) * n)
+ n := float32(v)
+ shannon += -mFastLog2(n*invTotal) * n
}
}
// Just add 15 for EOB
shannon += 15
- for _, v := range t.extraHist[1 : literalCount-256] {
+ for i, v := range t.extraHist[1 : literalCount-256] {
if v > 0 {
- n := float64(v)
- shannon += math.Ceil(-math.Log2(n*invTotal) * n)
- bits += int(lengthExtraBits[v&31]) * int(v)
+ n := float32(v)
+ shannon += -mFastLog2(n*invTotal) * n
+ bits += int(lengthExtraBits[i&31]) * int(v)
nMatches += int(v)
}
}
}
if nMatches > 0 {
- invTotal := 1.0 / float64(nMatches)
- for _, v := range t.offHist[:offsetCodeCount] {
+ invTotal := 1.0 / float32(nMatches)
+ for i, v := range t.offHist[:offsetCodeCount] {
if v > 0 {
- n := float64(v)
- shannon += math.Ceil(-math.Log2(n*invTotal) * n)
- bits += int(offsetExtraBits[v&31]) * int(n)
+ n := float32(v)
+ shannon += -mFastLog2(n*invTotal) * n
+ bits += int(offsetExtraBits[i&31]) * int(v)
}
}
}
-
return int(shannon) + bits
}
// AddMatch adds a match to the tokens.
// This function is very sensitive to inlining and right on the border.
func (t *tokens) AddMatch(xlength uint32, xoffset uint32) {
- if debugDecode {
+ if debugDeflate {
if xlength >= maxMatchLength+baseMatchLength {
panic(fmt.Errorf("invalid length: %v", xlength))
}
@@ -273,7 +281,7 @@ func (t *tokens) AddMatch(xlength uint32, xoffset uint32) {
// AddMatchLong adds a match to the tokens, potentially longer than max match length.
// Length should NOT have the base subtracted, only offset should.
func (t *tokens) AddMatchLong(xlength int32, xoffset uint32) {
- if debugDecode {
+ if debugDeflate {
if xoffset >= maxMatchOffset+baseMatchOffset {
panic(fmt.Errorf("invalid offset: %v", xoffset))
}
diff --git a/vendor/github.com/klauspost/compress/zstd/blockenc.go b/vendor/github.com/klauspost/compress/zstd/blockenc.go
index 507757d52..4f0eba22f 100644
--- a/vendor/github.com/klauspost/compress/zstd/blockenc.go
+++ b/vendor/github.com/klauspost/compress/zstd/blockenc.go
@@ -806,7 +806,7 @@ func (b *blockEnc) genCodes() {
mlH[v]++
if v > mlMax {
mlMax = v
- if debug && mlMax > maxMatchLengthSymbol {
+ if debugAsserts && mlMax > maxMatchLengthSymbol {
panic(fmt.Errorf("mlMax > maxMatchLengthSymbol (%d), matchlen: %d", mlMax, seq.matchLen))
}
}
@@ -821,13 +821,13 @@ func (b *blockEnc) genCodes() {
}
return int(max)
}
- if mlMax > maxMatchLengthSymbol {
+ if debugAsserts && mlMax > maxMatchLengthSymbol {
panic(fmt.Errorf("mlMax > maxMatchLengthSymbol (%d)", mlMax))
}
- if ofMax > maxOffsetBits {
+ if debugAsserts && ofMax > maxOffsetBits {
panic(fmt.Errorf("ofMax > maxOffsetBits (%d)", ofMax))
}
- if llMax > maxLiteralLengthSymbol {
+ if debugAsserts && llMax > maxLiteralLengthSymbol {
panic(fmt.Errorf("llMax > maxLiteralLengthSymbol (%d)", llMax))
}
diff --git a/vendor/github.com/klauspost/compress/zstd/bytebuf.go b/vendor/github.com/klauspost/compress/zstd/bytebuf.go
index 07321acb1..658ef7838 100644
--- a/vendor/github.com/klauspost/compress/zstd/bytebuf.go
+++ b/vendor/github.com/klauspost/compress/zstd/bytebuf.go
@@ -30,7 +30,7 @@ type byteBuffer interface {
type byteBuf []byte
func (b *byteBuf) readSmall(n int) []byte {
- if debug && n > 8 {
+ if debugAsserts && n > 8 {
panic(fmt.Errorf("small read > 8 (%d). use readBig", n))
}
bb := *b
@@ -82,7 +82,7 @@ type readerWrapper struct {
}
func (r *readerWrapper) readSmall(n int) []byte {
- if debug && n > 8 {
+ if debugAsserts && n > 8 {
panic(fmt.Errorf("small read > 8 (%d). use readBig", n))
}
n2, err := io.ReadFull(r.r, r.tmp[:n])
diff --git a/vendor/github.com/klauspost/compress/zstd/decoder.go b/vendor/github.com/klauspost/compress/zstd/decoder.go
index 35a3cda91..86553c2c3 100644
--- a/vendor/github.com/klauspost/compress/zstd/decoder.go
+++ b/vendor/github.com/klauspost/compress/zstd/decoder.go
@@ -66,7 +66,7 @@ var (
// A Decoder can be used in two modes:
//
// 1) As a stream, or
-// 2) For stateless decoding using DecodeAll or DecodeBuffer.
+// 2) For stateless decoding using DecodeAll.
//
// Only a single stream can be decoded concurrently, but the same decoder
// can run multiple concurrent stateless decodes. It is even possible to
@@ -315,7 +315,7 @@ func (d *Decoder) DecodeAll(input, dst []byte) ([]byte, error) {
if size > 1<<20 {
size = 1 << 20
}
- dst = make([]byte, 0, frame.WindowSize)
+ dst = make([]byte, 0, size)
}
dst, err = frame.runDecoder(dst, block)
diff --git a/vendor/github.com/klauspost/compress/zstd/enc_better.go b/vendor/github.com/klauspost/compress/zstd/enc_better.go
new file mode 100644
index 000000000..4375e08b4
--- /dev/null
+++ b/vendor/github.com/klauspost/compress/zstd/enc_better.go
@@ -0,0 +1,521 @@
+// Copyright 2019+ Klaus Post. All rights reserved.
+// License information can be found in the LICENSE file.
+// Based on work by Yann Collet, released under BSD License.
+
+package zstd
+
+import "fmt"
+
+const (
+ betterLongTableBits = 19 // Bits used in the long match table
+ betterLongTableSize = 1 << betterLongTableBits // Size of the table
+
+ // Note: Increasing the short table bits or making the hash shorter
+ // can actually lead to compression degradation since it will 'steal' more from the
+ // long match table and match offsets are quite big.
+ // This greatly depends on the type of input.
+ betterShortTableBits = 13 // Bits used in the short match table
+ betterShortTableSize = 1 << betterShortTableBits // Size of the table
+)
+
+type prevEntry struct {
+ offset int32
+ prev int32
+}
+
+// betterFastEncoder uses 2 tables, one for short matches (5 bytes) and one for long matches.
+// The long match table contains the previous entry with the same hash,
+// effectively making it a "chain" of length 2.
+// When we find a long match we choose between the two values and select the longest.
+// When we find a short match, after checking the long, we check if we can find a long at n+1
+// and that it is longer (lazy matching).
+type betterFastEncoder struct {
+ fastBase
+ table [betterShortTableSize]tableEntry
+ longTable [betterLongTableSize]prevEntry
+}
+
+// Encode improves compression...
+func (e *betterFastEncoder) Encode(blk *blockEnc, src []byte) {
+ const (
+ // Input margin is the number of bytes we read (8)
+ // and the maximum we will read ahead (2)
+ inputMargin = 8 + 2
+ minNonLiteralBlockSize = 16
+ )
+
+ // Protect against e.cur wraparound.
+ for e.cur >= bufferReset {
+ if len(e.hist) == 0 {
+ for i := range e.table[:] {
+ e.table[i] = tableEntry{}
+ }
+ for i := range e.longTable[:] {
+ e.longTable[i] = prevEntry{}
+ }
+ e.cur = e.maxMatchOff
+ break
+ }
+ // Shift down everything in the table that isn't already too far away.
+ minOff := e.cur + int32(len(e.hist)) - e.maxMatchOff
+ for i := range e.table[:] {
+ v := e.table[i].offset
+ if v < minOff {
+ v = 0
+ } else {
+ v = v - e.cur + e.maxMatchOff
+ }
+ e.table[i].offset = v
+ }
+ for i := range e.longTable[:] {
+ v := e.longTable[i].offset
+ v2 := e.longTable[i].prev
+ if v < minOff {
+ v = 0
+ v2 = 0
+ } else {
+ v = v - e.cur + e.maxMatchOff
+ if v2 < minOff {
+ v2 = 0
+ } else {
+ v2 = v2 - e.cur + e.maxMatchOff
+ }
+ }
+ e.longTable[i] = prevEntry{
+ offset: v,
+ prev: v2,
+ }
+ }
+ e.cur = e.maxMatchOff
+ break
+ }
+
+ s := e.addBlock(src)
+ blk.size = len(src)
+ if len(src) < minNonLiteralBlockSize {
+ blk.extraLits = len(src)
+ blk.literals = blk.literals[:len(src)]
+ copy(blk.literals, src)
+ return
+ }
+
+ // Override src
+ src = e.hist
+ sLimit := int32(len(src)) - inputMargin
+ // stepSize is the number of bytes to skip on every main loop iteration.
+ // It should be >= 1.
+ stepSize := int32(e.o.targetLength)
+ if stepSize == 0 {
+ stepSize++
+ }
+
+ const kSearchStrength = 9
+
+ // nextEmit is where in src the next emitLiteral should start from.
+ nextEmit := s
+ cv := load6432(src, s)
+
+ // Relative offsets
+ offset1 := int32(blk.recentOffsets[0])
+ offset2 := int32(blk.recentOffsets[1])
+
+ addLiterals := func(s *seq, until int32) {
+ if until == nextEmit {
+ return
+ }
+ blk.literals = append(blk.literals, src[nextEmit:until]...)
+ s.litLen = uint32(until - nextEmit)
+ }
+ if debug {
+ println("recent offsets:", blk.recentOffsets)
+ }
+
+encodeLoop:
+ for {
+ var t int32
+ // We allow the encoder to optionally turn off repeat offsets across blocks
+ canRepeat := len(blk.sequences) > 2
+ var matched int32
+
+ for {
+ if debugAsserts && canRepeat && offset1 == 0 {
+ panic("offset0 was 0")
+ }
+
+ nextHashS := hash5(cv, betterShortTableBits)
+ nextHashL := hash8(cv, betterLongTableBits)
+ candidateL := e.longTable[nextHashL]
+ candidateS := e.table[nextHashS]
+
+ const repOff = 1
+ repIndex := s - offset1 + repOff
+ off := s + e.cur
+ e.longTable[nextHashL] = prevEntry{offset: off, prev: candidateL.offset}
+ e.table[nextHashS] = tableEntry{offset: off, val: uint32(cv)}
+
+ if canRepeat {
+ if repIndex >= 0 && load3232(src, repIndex) == uint32(cv>>(repOff*8)) {
+ // Consider history as well.
+ var seq seq
+ lenght := 4 + e.matchlen(s+4+repOff, repIndex+4, src)
+
+ seq.matchLen = uint32(lenght - zstdMinMatch)
+
+ // We might be able to match backwards.
+ // Extend as long as we can.
+ start := s + repOff
+ // We end the search early, so we don't risk 0 literals
+ // and have to do special offset treatment.
+ startLimit := nextEmit + 1
+
+ tMin := s - e.maxMatchOff
+ if tMin < 0 {
+ tMin = 0
+ }
+ for repIndex > tMin && start > startLimit && src[repIndex-1] == src[start-1] && seq.matchLen < maxMatchLength-zstdMinMatch-1 {
+ repIndex--
+ start--
+ seq.matchLen++
+ }
+ addLiterals(&seq, start)
+
+ // rep 0
+ seq.offset = 1
+ if debugSequences {
+ println("repeat sequence", seq, "next s:", s)
+ }
+ blk.sequences = append(blk.sequences, seq)
+
+ // Index match start+1 (long) -> s - 1
+ index0 := s + repOff
+ s += lenght + repOff
+
+ nextEmit = s
+ if s >= sLimit {
+ if debug {
+ println("repeat ended", s, lenght)
+
+ }
+ break encodeLoop
+ }
+ // Index skipped...
+ for index0 < s-1 {
+ cv0 := load6432(src, index0)
+ cv1 := cv0 >> 8
+ h0 := hash8(cv0, betterLongTableBits)
+ off := index0 + e.cur
+ e.longTable[h0] = prevEntry{offset: off, prev: e.longTable[h0].offset}
+ e.table[hash5(cv1, betterShortTableBits)] = tableEntry{offset: off + 1, val: uint32(cv1)}
+ index0 += 2
+ }
+ cv = load6432(src, s)
+ continue
+ }
+ const repOff2 = 1
+
+ // We deviate from the reference encoder and also check offset 2.
+ // Still slower and not much better, so disabled.
+ // repIndex = s - offset2 + repOff2
+ if false && repIndex >= 0 && load6432(src, repIndex) == load6432(src, s+repOff) {
+ // Consider history as well.
+ var seq seq
+ lenght := 8 + e.matchlen(s+8+repOff2, repIndex+8, src)
+
+ seq.matchLen = uint32(lenght - zstdMinMatch)
+
+ // We might be able to match backwards.
+ // Extend as long as we can.
+ start := s + repOff2
+ // We end the search early, so we don't risk 0 literals
+ // and have to do special offset treatment.
+ startLimit := nextEmit + 1
+
+ tMin := s - e.maxMatchOff
+ if tMin < 0 {
+ tMin = 0
+ }
+ for repIndex > tMin && start > startLimit && src[repIndex-1] == src[start-1] && seq.matchLen < maxMatchLength-zstdMinMatch-1 {
+ repIndex--
+ start--
+ seq.matchLen++
+ }
+ addLiterals(&seq, start)
+
+ // rep 2
+ seq.offset = 2
+ if debugSequences {
+ println("repeat sequence 2", seq, "next s:", s)
+ }
+ blk.sequences = append(blk.sequences, seq)
+
+ index0 := s + repOff2
+ s += lenght + repOff2
+ nextEmit = s
+ if s >= sLimit {
+ if debug {
+ println("repeat ended", s, lenght)
+
+ }
+ break encodeLoop
+ }
+
+ // Index skipped...
+ for index0 < s-1 {
+ cv0 := load6432(src, index0)
+ cv1 := cv0 >> 8
+ h0 := hash8(cv0, betterLongTableBits)
+ off := index0 + e.cur
+ e.longTable[h0] = prevEntry{offset: off, prev: e.longTable[h0].offset}
+ e.table[hash5(cv1, betterShortTableBits)] = tableEntry{offset: off + 1, val: uint32(cv1)}
+ index0 += 2
+ }
+ cv = load6432(src, s)
+ // Swap offsets
+ offset1, offset2 = offset2, offset1
+ continue
+ }
+ }
+ // Find the offsets of our two matches.
+ coffsetL := candidateL.offset - e.cur
+ coffsetLP := candidateL.prev - e.cur
+
+ // Check if we have a long match.
+ if s-coffsetL < e.maxMatchOff && cv == load6432(src, coffsetL) {
+ // Found a long match, at least 8 bytes.
+ matched = e.matchlen(s+8, coffsetL+8, src) + 8
+ t = coffsetL
+ if debugAsserts && s <= t {
+ panic(fmt.Sprintf("s (%d) <= t (%d)", s, t))
+ }
+ if debugAsserts && s-t > e.maxMatchOff {
+ panic("s - t >e.maxMatchOff")
+ }
+ if debugMatches {
+ println("long match")
+ }
+
+ if s-coffsetLP < e.maxMatchOff && cv == load6432(src, coffsetLP) {
+ // Found a long match, at least 8 bytes.
+ prevMatch := e.matchlen(s+8, coffsetLP+8, src) + 8
+ if prevMatch > matched {
+ matched = prevMatch
+ t = coffsetLP
+ }
+ if debugAsserts && s <= t {
+ panic(fmt.Sprintf("s (%d) <= t (%d)", s, t))
+ }
+ if debugAsserts && s-t > e.maxMatchOff {
+ panic("s - t >e.maxMatchOff")
+ }
+ if debugMatches {
+ println("long match")
+ }
+ }
+ break
+ }
+
+ // Check if we have a long match on prev.
+ if s-coffsetLP < e.maxMatchOff && cv == load6432(src, coffsetLP) {
+ // Found a long match, at least 8 bytes.
+ matched = e.matchlen(s+8, coffsetLP+8, src) + 8
+ t = coffsetLP
+ if debugAsserts && s <= t {
+ panic(fmt.Sprintf("s (%d) <= t (%d)", s, t))
+ }
+ if debugAsserts && s-t > e.maxMatchOff {
+ panic("s - t >e.maxMatchOff")
+ }
+ if debugMatches {
+ println("long match")
+ }
+ break
+ }
+
+ coffsetS := candidateS.offset - e.cur
+
+ // Check if we have a short match.
+ if s-coffsetS < e.maxMatchOff && uint32(cv) == candidateS.val {
+ // found a regular match
+ matched = e.matchlen(s+4, coffsetS+4, src) + 4
+
+ // See if we can find a long match at s+1
+ const checkAt = 1
+ cv := load6432(src, s+checkAt)
+ nextHashL = hash8(cv, betterLongTableBits)
+ candidateL = e.longTable[nextHashL]
+ coffsetL = candidateL.offset - e.cur
+
+ // We can store it, since we have at least a 4 byte match.
+ e.longTable[nextHashL] = prevEntry{offset: s + checkAt + e.cur, prev: candidateL.offset}
+ if s-coffsetL < e.maxMatchOff && cv == load6432(src, coffsetL) {
+ // Found a long match, at least 8 bytes.
+ matchedNext := e.matchlen(s+8+checkAt, coffsetL+8, src) + 8
+ if matchedNext > matched {
+ t = coffsetL
+ s += checkAt
+ matched = matchedNext
+ if debugMatches {
+ println("long match (after short)")
+ }
+ break
+ }
+ }
+
+ // Check prev long...
+ coffsetL = candidateL.prev - e.cur
+ if s-coffsetL < e.maxMatchOff && cv == load6432(src, coffsetL) {
+ // Found a long match, at least 8 bytes.
+ matchedNext := e.matchlen(s+8+checkAt, coffsetL+8, src) + 8
+ if matchedNext > matched {
+ t = coffsetL
+ s += checkAt
+ matched = matchedNext
+ if debugMatches {
+ println("prev long match (after short)")
+ }
+ break
+ }
+ }
+ t = coffsetS
+ if debugAsserts && s <= t {
+ panic(fmt.Sprintf("s (%d) <= t (%d)", s, t))
+ }
+ if debugAsserts && s-t > e.maxMatchOff {
+ panic("s - t >e.maxMatchOff")
+ }
+ if debugAsserts && t < 0 {
+ panic("t<0")
+ }
+ if debugMatches {
+ println("short match")
+ }
+ break
+ }
+
+ // No match found, move forward in input.
+ s += stepSize + ((s - nextEmit) >> (kSearchStrength - 1))
+ if s >= sLimit {
+ break encodeLoop
+ }
+ cv = load6432(src, s)
+ }
+
+ // A 4-byte match has been found. Update recent offsets.
+ // We'll later see if more than 4 bytes.
+ offset2 = offset1
+ offset1 = s - t
+
+ if debugAsserts && s <= t {
+ panic(fmt.Sprintf("s (%d) <= t (%d)", s, t))
+ }
+
+ if debugAsserts && canRepeat && int(offset1) > len(src) {
+ panic("invalid offset")
+ }
+
+ // Extend the n-byte match as long as possible.
+ l := matched
+
+ // Extend backwards
+ tMin := s - e.maxMatchOff
+ if tMin < 0 {
+ tMin = 0
+ }
+ for t > tMin && s > nextEmit && src[t-1] == src[s-1] && l < maxMatchLength {
+ s--
+ t--
+ l++
+ }
+
+ // Write our sequence
+ var seq seq
+ seq.litLen = uint32(s - nextEmit)
+ seq.matchLen = uint32(l - zstdMinMatch)
+ if seq.litLen > 0 {
+ blk.literals = append(blk.literals, src[nextEmit:s]...)
+ }
+ seq.offset = uint32(s-t) + 3
+ s += l
+ if debugSequences {
+ println("sequence", seq, "next s:", s)
+ }
+ blk.sequences = append(blk.sequences, seq)
+ nextEmit = s
+ if s >= sLimit {
+ break encodeLoop
+ }
+
+ // Index match start+1 (long) -> s - 1
+ index0 := s - l + 1
+ for index0 < s-1 {
+ cv0 := load6432(src, index0)
+ cv1 := cv0 >> 8
+ h0 := hash8(cv0, betterLongTableBits)
+ off := index0 + e.cur
+ e.longTable[h0] = prevEntry{offset: off, prev: e.longTable[h0].offset}
+ e.table[hash5(cv1, betterShortTableBits)] = tableEntry{offset: off + 1, val: uint32(cv1)}
+ index0 += 2
+ }
+
+ cv = load6432(src, s)
+ if !canRepeat {
+ continue
+ }
+
+ // Check offset 2
+ for {
+ o2 := s - offset2
+ if load3232(src, o2) != uint32(cv) {
+ // Do regular search
+ break
+ }
+
+ // Store this, since we have it.
+ nextHashS := hash5(cv, betterShortTableBits)
+ nextHashL := hash8(cv, betterLongTableBits)
+
+ // We have at least 4 byte match.
+ // No need to check backwards. We come straight from a match
+ l := 4 + e.matchlen(s+4, o2+4, src)
+
+ e.longTable[nextHashL] = prevEntry{offset: s + e.cur, prev: e.longTable[nextHashL].offset}
+ e.table[nextHashS] = tableEntry{offset: s + e.cur, val: uint32(cv)}
+ seq.matchLen = uint32(l) - zstdMinMatch
+ seq.litLen = 0
+
+ // Since litlen is always 0, this is offset 1.
+ seq.offset = 1
+ s += l
+ nextEmit = s
+ if debugSequences {
+ println("sequence", seq, "next s:", s)
+ }
+ blk.sequences = append(blk.sequences, seq)
+
+ // Swap offset 1 and 2.
+ offset1, offset2 = offset2, offset1
+ if s >= sLimit {
+ // Finished
+ break encodeLoop
+ }
+ cv = load6432(src, s)
+ }
+ }
+
+ if int(nextEmit) < len(src) {
+ blk.literals = append(blk.literals, src[nextEmit:]...)
+ blk.extraLits = len(src) - int(nextEmit)
+ }
+ blk.recentOffsets[0] = uint32(offset1)
+ blk.recentOffsets[1] = uint32(offset2)
+ if debug {
+ println("returning, recent offsets:", blk.recentOffsets, "extra literals:", blk.extraLits)
+ }
+}
+
+// EncodeNoHist will encode a block with no history and no following blocks.
+// Most notable difference is that src will not be copied for history and
+// we do not need to check for max match length.
+func (e *betterFastEncoder) EncodeNoHist(blk *blockEnc, src []byte) {
+ e.Encode(blk, src)
+}
diff --git a/vendor/github.com/klauspost/compress/zstd/enc_dfast.go b/vendor/github.com/klauspost/compress/zstd/enc_dfast.go
index ee3b09b02..d640e6a9f 100644
--- a/vendor/github.com/klauspost/compress/zstd/enc_dfast.go
+++ b/vendor/github.com/klauspost/compress/zstd/enc_dfast.go
@@ -4,6 +4,8 @@
package zstd
+import "fmt"
+
const (
dFastLongTableBits = 17 // Bits used in the long match table
dFastLongTableSize = 1 << dFastLongTableBits // Size of the table
@@ -29,7 +31,7 @@ func (e *doubleFastEncoder) Encode(blk *blockEnc, src []byte) {
)
// Protect against e.cur wraparound.
- for e.cur > (1<<30)+e.maxMatchOff {
+ for e.cur >= bufferReset {
if len(e.hist) == 0 {
for i := range e.table[:] {
e.table[i] = tableEntry{}
@@ -61,6 +63,7 @@ func (e *doubleFastEncoder) Encode(blk *blockEnc, src []byte) {
e.longTable[i].offset = v
}
e.cur = e.maxMatchOff
+ break
}
s := e.addBlock(src)
@@ -110,7 +113,7 @@ encodeLoop:
canRepeat := len(blk.sequences) > 2
for {
- if debug && canRepeat && offset1 == 0 {
+ if debugAsserts && canRepeat && offset1 == 0 {
panic("offset0 was 0")
}
@@ -169,55 +172,6 @@ encodeLoop:
cv = load6432(src, s)
continue
}
- const repOff2 = 1
- // We deviate from the reference encoder and also check offset 2.
- // Slower and not consistently better, so disabled.
- // repIndex = s - offset2 + repOff2
- if false && repIndex >= 0 && load3232(src, repIndex) == uint32(cv>>(repOff2*8)) {
- // Consider history as well.
- var seq seq
- lenght := 4 + e.matchlen(s+4+repOff2, repIndex+4, src)
-
- seq.matchLen = uint32(lenght - zstdMinMatch)
-
- // We might be able to match backwards.
- // Extend as long as we can.
- start := s + repOff2
- // We end the search early, so we don't risk 0 literals
- // and have to do special offset treatment.
- startLimit := nextEmit + 1
-
- tMin := s - e.maxMatchOff
- if tMin < 0 {
- tMin = 0
- }
- for repIndex > tMin && start > startLimit && src[repIndex-1] == src[start-1] && seq.matchLen < maxMatchLength-zstdMinMatch-1 {
- repIndex--
- start--
- seq.matchLen++
- }
- addLiterals(&seq, start)
-
- // rep 2
- seq.offset = 2
- if debugSequences {
- println("repeat sequence 2", seq, "next s:", s)
- }
- blk.sequences = append(blk.sequences, seq)
- s += lenght + repOff2
- nextEmit = s
- if s >= sLimit {
- if debug {
- println("repeat ended", s, lenght)
-
- }
- break encodeLoop
- }
- cv = load6432(src, s)
- // Swap offsets
- offset1, offset2 = offset2, offset1
- continue
- }
}
// Find the offsets of our two matches.
coffsetL := s - (candidateL.offset - e.cur)
@@ -229,10 +183,10 @@ encodeLoop:
// Reference encoder checks all 8 bytes, we only check 4,
// but the likelihood of both the first 4 bytes and the hash matching should be enough.
t = candidateL.offset - e.cur
- if debug && s <= t {
- panic("s <= t")
+ if debugAsserts && s <= t {
+ panic(fmt.Sprintf("s (%d) <= t (%d)", s, t))
}
- if debug && s-t > e.maxMatchOff {
+ if debugAsserts && s-t > e.maxMatchOff {
panic("s - t >e.maxMatchOff")
}
if debugMatches {
@@ -266,13 +220,13 @@ encodeLoop:
}
t = candidateS.offset - e.cur
- if debug && s <= t {
- panic("s <= t")
+ if debugAsserts && s <= t {
+ panic(fmt.Sprintf("s (%d) <= t (%d)", s, t))
}
- if debug && s-t > e.maxMatchOff {
+ if debugAsserts && s-t > e.maxMatchOff {
panic("s - t >e.maxMatchOff")
}
- if debug && t < 0 {
+ if debugAsserts && t < 0 {
panic("t<0")
}
if debugMatches {
@@ -294,11 +248,11 @@ encodeLoop:
offset2 = offset1
offset1 = s - t
- if debug && s <= t {
- panic("s <= t")
+ if debugAsserts && s <= t {
+ panic(fmt.Sprintf("s (%d) <= t (%d)", s, t))
}
- if debug && canRepeat && int(offset1) > len(src) {
+ if debugAsserts && canRepeat && int(offset1) > len(src) {
panic("invalid offset")
}
@@ -369,7 +323,7 @@ encodeLoop:
}
// Store this, since we have it.
- nextHashS := hash5(cv1>>8, dFastShortTableBits)
+ nextHashS := hash5(cv, dFastShortTableBits)
nextHashL := hash8(cv, dFastLongTableBits)
// We have at least 4 byte match.
@@ -424,7 +378,7 @@ func (e *doubleFastEncoder) EncodeNoHist(blk *blockEnc, src []byte) {
)
// Protect against e.cur wraparound.
- if e.cur > (1<<30)+e.maxMatchOff {
+ if e.cur >= bufferReset {
for i := range e.table[:] {
e.table[i] = tableEntry{}
}
@@ -545,10 +499,10 @@ encodeLoop:
// Reference encoder checks all 8 bytes, we only check 4,
// but the likelihood of both the first 4 bytes and the hash matching should be enough.
t = candidateL.offset - e.cur
- if debug && s <= t {
- panic("s <= t")
+ if debugAsserts && s <= t {
+ panic(fmt.Sprintf("s (%d) <= t (%d)", s, t))
}
- if debug && s-t > e.maxMatchOff {
+ if debugAsserts && s-t > e.maxMatchOff {
panic("s - t >e.maxMatchOff")
}
if debugMatches {
@@ -582,13 +536,13 @@ encodeLoop:
}
t = candidateS.offset - e.cur
- if debug && s <= t {
- panic("s <= t")
+ if debugAsserts && s <= t {
+ panic(fmt.Sprintf("s (%d) <= t (%d)", s, t))
}
- if debug && s-t > e.maxMatchOff {
+ if debugAsserts && s-t > e.maxMatchOff {
panic("s - t >e.maxMatchOff")
}
- if debug && t < 0 {
+ if debugAsserts && t < 0 {
panic("t<0")
}
if debugMatches {
@@ -610,8 +564,8 @@ encodeLoop:
offset2 = offset1
offset1 = s - t
- if debug && s <= t {
- panic("s <= t")
+ if debugAsserts && s <= t {
+ panic(fmt.Sprintf("s (%d) <= t (%d)", s, t))
}
// Extend the 4-byte match as long as possible.
diff --git a/vendor/github.com/klauspost/compress/zstd/enc_fast.go b/vendor/github.com/klauspost/compress/zstd/enc_fast.go
index 0bdddac5b..1387b8082 100644
--- a/vendor/github.com/klauspost/compress/zstd/enc_fast.go
+++ b/vendor/github.com/klauspost/compress/zstd/enc_fast.go
@@ -5,6 +5,8 @@
package zstd
import (
+ "fmt"
+ "math"
"math/bits"
"github.com/klauspost/compress/zstd/internal/xxhash"
@@ -22,7 +24,7 @@ type tableEntry struct {
offset int32
}
-type fastEncoder struct {
+type fastBase struct {
o encParams
// cur is the offset at the start of hist
cur int32
@@ -30,18 +32,22 @@ type fastEncoder struct {
maxMatchOff int32
hist []byte
crc *xxhash.Digest
- table [tableSize]tableEntry
tmp [8]byte
blk *blockEnc
}
+type fastEncoder struct {
+ fastBase
+ table [tableSize]tableEntry
+}
+
// CRC returns the underlying CRC writer.
-func (e *fastEncoder) CRC() *xxhash.Digest {
+func (e *fastBase) CRC() *xxhash.Digest {
return e.crc
}
// AppendCRC will append the CRC to the destination slice and return it.
-func (e *fastEncoder) AppendCRC(dst []byte) []byte {
+func (e *fastBase) AppendCRC(dst []byte) []byte {
crc := e.crc.Sum(e.tmp[:0])
dst = append(dst, crc[7], crc[6], crc[5], crc[4])
return dst
@@ -49,7 +55,7 @@ func (e *fastEncoder) AppendCRC(dst []byte) []byte {
// WindowSize returns the window size of the encoder,
// or a window size small enough to contain the input size, if > 0.
-func (e *fastEncoder) WindowSize(size int) int32 {
+func (e *fastBase) WindowSize(size int) int32 {
if size > 0 && size < int(e.maxMatchOff) {
b := int32(1) << uint(bits.Len(uint(size)))
// Keep minimum window.
@@ -62,7 +68,7 @@ func (e *fastEncoder) WindowSize(size int) int32 {
}
// Block returns the current block.
-func (e *fastEncoder) Block() *blockEnc {
+func (e *fastBase) Block() *blockEnc {
return e.blk
}
@@ -74,7 +80,7 @@ func (e *fastEncoder) Encode(blk *blockEnc, src []byte) {
)
// Protect against e.cur wraparound.
- for e.cur > (1<<30)+e.maxMatchOff {
+ for e.cur >= bufferReset {
if len(e.hist) == 0 {
for i := range e.table[:] {
e.table[i] = tableEntry{}
@@ -94,6 +100,7 @@ func (e *fastEncoder) Encode(blk *blockEnc, src []byte) {
e.table[i].offset = v
}
e.cur = e.maxMatchOff
+ break
}
s := e.addBlock(src)
@@ -151,7 +158,7 @@ encodeLoop:
canRepeat := len(blk.sequences) > 2
for {
- if debug && canRepeat && offset1 == 0 {
+ if debugAsserts && canRepeat && offset1 == 0 {
panic("offset0 was 0")
}
@@ -167,9 +174,22 @@ encodeLoop:
if canRepeat && repIndex >= 0 && load3232(src, repIndex) == uint32(cv>>16) {
// Consider history as well.
var seq seq
- lenght := 4 + e.matchlen(s+6, repIndex+4, src)
+ var length int32
+ // length = 4 + e.matchlen(s+6, repIndex+4, src)
+ {
+ a := src[s+6:]
+ b := src[repIndex+4:]
+ endI := len(a) & (math.MaxInt32 - 7)
+ length = int32(endI) + 4
+ for i := 0; i < endI; i += 8 {
+ if diff := load64(a, i) ^ load64(b, i); diff != 0 {
+ length = int32(i+bits.TrailingZeros64(diff)>>3) + 4
+ break
+ }
+ }
+ }
- seq.matchLen = uint32(lenght - zstdMinMatch)
+ seq.matchLen = uint32(length - zstdMinMatch)
// We might be able to match backwards.
// Extend as long as we can.
@@ -195,11 +215,11 @@ encodeLoop:
println("repeat sequence", seq, "next s:", s)
}
blk.sequences = append(blk.sequences, seq)
- s += lenght + 2
+ s += length + 2
nextEmit = s
if s >= sLimit {
if debug {
- println("repeat ended", s, lenght)
+ println("repeat ended", s, length)
}
break encodeLoop
@@ -212,10 +232,10 @@ encodeLoop:
if coffset0 < e.maxMatchOff && uint32(cv) == candidate.val {
// found a regular match
t = candidate.offset - e.cur
- if debug && s <= t {
- panic("s <= t")
+ if debugAsserts && s <= t {
+ panic(fmt.Sprintf("s (%d) <= t (%d)", s, t))
}
- if debug && s-t > e.maxMatchOff {
+ if debugAsserts && s-t > e.maxMatchOff {
panic("s - t >e.maxMatchOff")
}
break
@@ -225,13 +245,13 @@ encodeLoop:
// found a regular match
t = candidate2.offset - e.cur
s++
- if debug && s <= t {
- panic("s <= t")
+ if debugAsserts && s <= t {
+ panic(fmt.Sprintf("s (%d) <= t (%d)", s, t))
}
- if debug && s-t > e.maxMatchOff {
+ if debugAsserts && s-t > e.maxMatchOff {
panic("s - t >e.maxMatchOff")
}
- if debug && t < 0 {
+ if debugAsserts && t < 0 {
panic("t<0")
}
break
@@ -246,16 +266,29 @@ encodeLoop:
offset2 = offset1
offset1 = s - t
- if debug && s <= t {
- panic("s <= t")
+ if debugAsserts && s <= t {
+ panic(fmt.Sprintf("s (%d) <= t (%d)", s, t))
}
- if debug && canRepeat && int(offset1) > len(src) {
+ if debugAsserts && canRepeat && int(offset1) > len(src) {
panic("invalid offset")
}
// Extend the 4-byte match as long as possible.
- l := e.matchlen(s+4, t+4, src) + 4
+ //l := e.matchlen(s+4, t+4, src) + 4
+ var l int32
+ {
+ a := src[s+4:]
+ b := src[t+4:]
+ endI := len(a) & (math.MaxInt32 - 7)
+ l = int32(endI) + 4
+ for i := 0; i < endI; i += 8 {
+ if diff := load64(a, i) ^ load64(b, i); diff != 0 {
+ l = int32(i+bits.TrailingZeros64(diff)>>3) + 4
+ break
+ }
+ }
+ }
// Extend backwards
tMin := s - e.maxMatchOff
@@ -292,7 +325,20 @@ encodeLoop:
if o2 := s - offset2; canRepeat && load3232(src, o2) == uint32(cv) {
// We have at least 4 byte match.
// No need to check backwards. We come straight from a match
- l := 4 + e.matchlen(s+4, o2+4, src)
+ //l := 4 + e.matchlen(s+4, o2+4, src)
+ var l int32
+ {
+ a := src[s+4:]
+ b := src[o2+4:]
+ endI := len(a) & (math.MaxInt32 - 7)
+ l = int32(endI) + 4
+ for i := 0; i < endI; i += 8 {
+ if diff := load64(a, i) ^ load64(b, i); diff != 0 {
+ l = int32(i+bits.TrailingZeros64(diff)>>3) + 4
+ break
+ }
+ }
+ }
// Store this, since we have it.
nextHash := hash6(cv, hashLog)
@@ -343,7 +389,7 @@ func (e *fastEncoder) EncodeNoHist(blk *blockEnc, src []byte) {
}
}
// Protect against e.cur wraparound.
- if e.cur > (1<<30)+e.maxMatchOff {
+ if e.cur >= bufferReset {
for i := range e.table[:] {
e.table[i] = tableEntry{}
}
@@ -410,10 +456,23 @@ encodeLoop:
if len(blk.sequences) > 2 && load3232(src, repIndex) == uint32(cv>>16) {
// Consider history as well.
var seq seq
- // lenght := 4 + e.matchlen(s+6, repIndex+4, src)
- lenght := 4 + int32(matchLen(src[s+6:], src[repIndex+4:]))
+ // length := 4 + e.matchlen(s+6, repIndex+4, src)
+ // length := 4 + int32(matchLen(src[s+6:], src[repIndex+4:]))
+ var length int32
+ {
+ a := src[s+6:]
+ b := src[repIndex+4:]
+ endI := len(a) & (math.MaxInt32 - 7)
+ length = int32(endI) + 4
+ for i := 0; i < endI; i += 8 {
+ if diff := load64(a, i) ^ load64(b, i); diff != 0 {
+ length = int32(i+bits.TrailingZeros64(diff)>>3) + 4
+ break
+ }
+ }
+ }
- seq.matchLen = uint32(lenght - zstdMinMatch)
+ seq.matchLen = uint32(length - zstdMinMatch)
// We might be able to match backwards.
// Extend as long as we can.
@@ -439,11 +498,11 @@ encodeLoop:
println("repeat sequence", seq, "next s:", s)
}
blk.sequences = append(blk.sequences, seq)
- s += lenght + 2
+ s += length + 2
nextEmit = s
if s >= sLimit {
if debug {
- println("repeat ended", s, lenght)
+ println("repeat ended", s, length)
}
break encodeLoop
@@ -456,10 +515,10 @@ encodeLoop:
if coffset0 < e.maxMatchOff && uint32(cv) == candidate.val {
// found a regular match
t = candidate.offset - e.cur
- if debug && s <= t {
- panic("s <= t")
+ if debugAsserts && s <= t {
+ panic(fmt.Sprintf("s (%d) <= t (%d)", s, t))
}
- if debug && s-t > e.maxMatchOff {
+ if debugAsserts && s-t > e.maxMatchOff {
panic("s - t >e.maxMatchOff")
}
break
@@ -469,13 +528,13 @@ encodeLoop:
// found a regular match
t = candidate2.offset - e.cur
s++
- if debug && s <= t {
- panic("s <= t")
+ if debugAsserts && s <= t {
+ panic(fmt.Sprintf("s (%d) <= t (%d)", s, t))
}
- if debug && s-t > e.maxMatchOff {
+ if debugAsserts && s-t > e.maxMatchOff {
panic("s - t >e.maxMatchOff")
}
- if debug && t < 0 {
+ if debugAsserts && t < 0 {
panic("t<0")
}
break
@@ -490,13 +549,26 @@ encodeLoop:
offset2 = offset1
offset1 = s - t
- if debug && s <= t {
- panic("s <= t")
+ if debugAsserts && s <= t {
+ panic(fmt.Sprintf("s (%d) <= t (%d)", s, t))
}
// Extend the 4-byte match as long as possible.
//l := e.matchlenNoHist(s+4, t+4, src) + 4
- l := int32(matchLen(src[s+4:], src[t+4:])) + 4
+ // l := int32(matchLen(src[s+4:], src[t+4:])) + 4
+ var l int32
+ {
+ a := src[s+4:]
+ b := src[t+4:]
+ endI := len(a) & (math.MaxInt32 - 7)
+ l = int32(endI) + 4
+ for i := 0; i < endI; i += 8 {
+ if diff := load64(a, i) ^ load64(b, i); diff != 0 {
+ l = int32(i+bits.TrailingZeros64(diff)>>3) + 4
+ break
+ }
+ }
+ }
// Extend backwards
tMin := s - e.maxMatchOff
@@ -534,7 +606,20 @@ encodeLoop:
// We have at least 4 byte match.
// No need to check backwards. We come straight from a match
//l := 4 + e.matchlenNoHist(s+4, o2+4, src)
- l := 4 + int32(matchLen(src[s+4:], src[o2+4:]))
+ // l := 4 + int32(matchLen(src[s+4:], src[o2+4:]))
+ var l int32
+ {
+ a := src[s+4:]
+ b := src[o2+4:]
+ endI := len(a) & (math.MaxInt32 - 7)
+ l = int32(endI) + 4
+ for i := 0; i < endI; i += 8 {
+ if diff := load64(a, i) ^ load64(b, i); diff != 0 {
+ l = int32(i+bits.TrailingZeros64(diff)>>3) + 4
+ break
+ }
+ }
+ }
// Store this, since we have it.
nextHash := hash6(cv, hashLog)
@@ -569,7 +654,10 @@ encodeLoop:
}
}
-func (e *fastEncoder) addBlock(src []byte) int32 {
+func (e *fastBase) addBlock(src []byte) int32 {
+ if debugAsserts && e.cur > bufferReset {
+ panic(fmt.Sprintf("ecur (%d) > buffer reset (%d)", e.cur, bufferReset))
+ }
// check if we have space already
if len(e.hist)+len(src) > cap(e.hist) {
if cap(e.hist) == 0 {
@@ -597,39 +685,41 @@ func (e *fastEncoder) addBlock(src []byte) int32 {
// useBlock will replace the block with the provided one,
// but transfer recent offsets from the previous.
-func (e *fastEncoder) UseBlock(enc *blockEnc) {
+func (e *fastBase) UseBlock(enc *blockEnc) {
enc.reset(e.blk)
e.blk = enc
}
-func (e *fastEncoder) matchlenNoHist(s, t int32, src []byte) int32 {
+func (e *fastBase) matchlenNoHist(s, t int32, src []byte) int32 {
// Extend the match to be as long as possible.
return int32(matchLen(src[s:], src[t:]))
}
-func (e *fastEncoder) matchlen(s, t int32, src []byte) int32 {
- if debug {
+func (e *fastBase) matchlen(s, t int32, src []byte) int32 {
+ if debugAsserts {
if s < 0 {
- panic("s<0")
+ err := fmt.Sprintf("s (%d) < 0", s)
+ panic(err)
}
if t < 0 {
- panic("t<0")
+ err := fmt.Sprintf("s (%d) < 0", s)
+ panic(err)
}
if s-t > e.maxMatchOff {
- panic(s - t)
+ err := fmt.Sprintf("s (%d) - t (%d) > maxMatchOff (%d)", s, t, e.maxMatchOff)
+ panic(err)
+ }
+ if len(src)-int(s) > maxCompressedBlockSize {
+ panic(fmt.Sprintf("len(src)-s (%d) > maxCompressedBlockSize (%d)", len(src)-int(s), maxCompressedBlockSize))
}
- }
- s1 := int(s) + maxMatchLength - 4
- if s1 > len(src) {
- s1 = len(src)
}
// Extend the match to be as long as possible.
- return int32(matchLen(src[s:s1], src[t:]))
+ return int32(matchLen(src[s:], src[t:]))
}
// Reset the encoding table.
-func (e *fastEncoder) Reset() {
+func (e *fastBase) Reset() {
if e.blk == nil {
e.blk = &blockEnc{}
e.blk.init()
@@ -650,7 +740,10 @@ func (e *fastEncoder) Reset() {
}
e.hist = make([]byte, 0, l)
}
- // We offset current position so everything will be out of reach
- e.cur += e.maxMatchOff + int32(len(e.hist))
+ // We offset current position so everything will be out of reach.
+ // If above reset line, history will be purged.
+ if e.cur < bufferReset {
+ e.cur += e.maxMatchOff + int32(len(e.hist))
+ }
e.hist = e.hist[:0]
}
diff --git a/vendor/github.com/klauspost/compress/zstd/encoder.go b/vendor/github.com/klauspost/compress/zstd/encoder.go
index 366dd66bd..67d45efb9 100644
--- a/vendor/github.com/klauspost/compress/zstd/encoder.go
+++ b/vendor/github.com/klauspost/compress/zstd/encoder.go
@@ -71,15 +71,14 @@ func NewWriter(w io.Writer, opts ...EOption) (*Encoder, error) {
}
if w != nil {
e.Reset(w)
- } else {
- e.init.Do(func() {
- e.initialize()
- })
}
return &e, nil
}
func (e *Encoder) initialize() {
+ if e.o.concurrent == 0 {
+ e.o.setDefault()
+ }
e.encoders = make(chan encoder, e.o.concurrent)
for i := 0; i < e.o.concurrent; i++ {
e.encoders <- e.o.encoder()
@@ -89,9 +88,6 @@ func (e *Encoder) initialize() {
// Reset will re-initialize the writer and new writes will encode to the supplied writer
// as a new, independent stream.
func (e *Encoder) Reset(w io.Writer) {
- e.init.Do(func() {
- e.initialize()
- })
s := &e.state
s.wg.Wait()
s.wWg.Wait()
@@ -156,7 +152,7 @@ func (e *Encoder) Write(p []byte) (n int, err error) {
if err != nil {
return n, err
}
- if debug && len(s.filling) > 0 {
+ if debugAsserts && len(s.filling) > 0 {
panic(len(s.filling))
}
}
@@ -422,10 +418,7 @@ func (e *Encoder) EncodeAll(src, dst []byte) []byte {
}
return dst
}
- e.init.Do(func() {
- e.o.setDefault()
- e.initialize()
- })
+ e.init.Do(e.initialize)
enc := <-e.encoders
defer func() {
// Release encoder reference to last block.
diff --git a/vendor/github.com/klauspost/compress/zstd/encoder_options.go b/vendor/github.com/klauspost/compress/zstd/encoder_options.go
index 40eb45733..0ff970dac 100644
--- a/vendor/github.com/klauspost/compress/zstd/encoder_options.go
+++ b/vendor/github.com/klauspost/compress/zstd/encoder_options.go
@@ -39,9 +39,11 @@ func (o *encoderOptions) setDefault() {
func (o encoderOptions) encoder() encoder {
switch o.level {
case SpeedDefault:
- return &doubleFastEncoder{fastEncoder: fastEncoder{maxMatchOff: int32(o.windowSize)}}
+ return &doubleFastEncoder{fastEncoder: fastEncoder{fastBase: fastBase{maxMatchOff: int32(o.windowSize)}}}
+ case SpeedBetterCompression:
+ return &betterFastEncoder{fastBase: fastBase{maxMatchOff: int32(o.windowSize)}}
case SpeedFastest:
- return &fastEncoder{maxMatchOff: int32(o.windowSize)}
+ return &fastEncoder{fastBase: fastBase{maxMatchOff: int32(o.windowSize)}}
}
panic("unknown compression level")
}
@@ -67,7 +69,7 @@ func WithEncoderConcurrency(n int) EOption {
}
// WithWindowSize will set the maximum allowed back-reference distance.
-// The value must be a power of two between WindowSizeMin and WindowSizeMax.
+// The value must be a power of two between MinWindowSize and MaxWindowSize.
// A larger value will enable better compression but allocate more memory and,
// for above-default values, take considerably longer.
// The default value is determined by the compression level.
@@ -130,18 +132,18 @@ const (
// This is roughly equivalent to the default Zstandard mode (level 3).
SpeedDefault
+ // SpeedBetterCompression will yield better compression than the default.
+ // Currently it is about zstd level 7-8 with ~ 2x-3x the default CPU usage.
+ // By using this, notice that CPU usage may go up in the future.
+ SpeedBetterCompression
+
// speedLast should be kept as the last actual compression option.
// The is not for external usage, but is used to keep track of the valid options.
speedLast
- // SpeedBetterCompression will (in the future) yield better compression than the default,
- // but at approximately 4x the CPU usage of the default.
- // For now this is not implemented.
- SpeedBetterCompression = SpeedDefault
-
// SpeedBestCompression will choose the best available compression option.
// For now this is not implemented.
- SpeedBestCompression = SpeedDefault
+ SpeedBestCompression = SpeedBetterCompression
)
// EncoderLevelFromString will convert a string representation of an encoding level back
@@ -163,8 +165,10 @@ func EncoderLevelFromZstd(level int) EncoderLevel {
switch {
case level < 3:
return SpeedFastest
- case level >= 3:
+ case level >= 3 && level < 6:
return SpeedDefault
+ case level > 5:
+ return SpeedBetterCompression
}
return SpeedDefault
}
@@ -176,6 +180,8 @@ func (e EncoderLevel) String() string {
return "fastest"
case SpeedDefault:
return "default"
+ case SpeedBetterCompression:
+ return "better"
default:
return "invalid"
}
diff --git a/vendor/github.com/klauspost/compress/zstd/framedec.go b/vendor/github.com/klauspost/compress/zstd/framedec.go
index 40790747a..cda590b5f 100644
--- a/vendor/github.com/klauspost/compress/zstd/framedec.go
+++ b/vendor/github.com/klauspost/compress/zstd/framedec.go
@@ -50,7 +50,7 @@ type frameDec struct {
const (
// The minimum Window_Size is 1 KB.
MinWindowSize = 1 << 10
- MaxWindowSize = 1 << 30
+ MaxWindowSize = 1 << 29
)
var (
diff --git a/vendor/github.com/klauspost/compress/zstd/fse_decoder.go b/vendor/github.com/klauspost/compress/zstd/fse_decoder.go
index 9efe34feb..e002be98b 100644
--- a/vendor/github.com/klauspost/compress/zstd/fse_decoder.go
+++ b/vendor/github.com/klauspost/compress/zstd/fse_decoder.go
@@ -118,7 +118,7 @@ func (s *fseDecoder) readNCount(b *byteReader, maxSymbol uint16) error {
if int32(bitStream)&(threshold-1) < max {
count = int32(bitStream) & (threshold - 1)
- if debug && nbBits < 1 {
+ if debugAsserts && nbBits < 1 {
panic("nbBits underflow")
}
bitCount += nbBits - 1
diff --git a/vendor/github.com/klauspost/compress/zstd/fse_encoder.go b/vendor/github.com/klauspost/compress/zstd/fse_encoder.go
index 619836f52..aa9eba88b 100644
--- a/vendor/github.com/klauspost/compress/zstd/fse_encoder.go
+++ b/vendor/github.com/klauspost/compress/zstd/fse_encoder.go
@@ -327,7 +327,7 @@ func (s *fseEncoder) normalizeCount(length int) error {
if err != nil {
return err
}
- if debug {
+ if debugAsserts {
err = s.validateNorm()
if err != nil {
return err
@@ -336,7 +336,7 @@ func (s *fseEncoder) normalizeCount(length int) error {
return s.buildCTable()
}
s.norm[largest] += stillToDistribute
- if debug {
+ if debugAsserts {
err := s.validateNorm()
if err != nil {
return err
@@ -619,7 +619,7 @@ func (s *fseEncoder) writeCount(out []byte) ([]byte, error) {
func (s *fseEncoder) bitCost(symbolValue uint8, accuracyLog uint32) uint32 {
minNbBits := s.ct.symbolTT[symbolValue].deltaNbBits >> 16
threshold := (minNbBits + 1) << 16
- if debug {
+ if debugAsserts {
if !(s.actualTableLog < 16) {
panic("!s.actualTableLog < 16")
}
@@ -633,7 +633,7 @@ func (s *fseEncoder) bitCost(symbolValue uint8, accuracyLog uint32) uint32 {
// linear interpolation (very approximate)
normalizedDeltaFromThreshold := (deltaFromThreshold << accuracyLog) >> s.actualTableLog
bitMultiplier := uint32(1) << accuracyLog
- if debug {
+ if debugAsserts {
if s.ct.symbolTT[symbolValue].deltaNbBits+tableSize > threshold {
panic("s.ct.symbolTT[symbolValue].deltaNbBits+tableSize > threshold")
}
diff --git a/vendor/github.com/klauspost/compress/zstd/internal/xxhash/xxhash_amd64.s b/vendor/github.com/klauspost/compress/zstd/internal/xxhash/xxhash_amd64.s
index d580e32ae..2c9c5357a 100644
--- a/vendor/github.com/klauspost/compress/zstd/internal/xxhash/xxhash_amd64.s
+++ b/vendor/github.com/klauspost/compress/zstd/internal/xxhash/xxhash_amd64.s
@@ -179,13 +179,13 @@ TEXT ·writeBlocks(SB), NOSPLIT, $0-40
MOVQ ·prime2v(SB), R14
// Load slice.
- MOVQ b_base+8(FP), CX
- MOVQ b_len+16(FP), DX
+ MOVQ arg1_base+8(FP), CX
+ MOVQ arg1_len+16(FP), DX
LEAQ (CX)(DX*1), BX
SUBQ $32, BX
// Load vN from d.
- MOVQ d+0(FP), AX
+ MOVQ arg+0(FP), AX
MOVQ 0(AX), R8 // v1
MOVQ 8(AX), R9 // v2
MOVQ 16(AX), R10 // v3
@@ -209,7 +209,7 @@ blockLoop:
MOVQ R11, 24(AX)
// The number of bytes written is CX minus the old base pointer.
- SUBQ b_base+8(FP), CX
+ SUBQ arg1_base+8(FP), CX
MOVQ CX, ret+32(FP)
RET
diff --git a/vendor/github.com/klauspost/compress/zstd/zstd.go b/vendor/github.com/klauspost/compress/zstd/zstd.go
index 57a8a2f5b..0807719c8 100644
--- a/vendor/github.com/klauspost/compress/zstd/zstd.go
+++ b/vendor/github.com/klauspost/compress/zstd/zstd.go
@@ -6,11 +6,20 @@ package zstd
import (
"errors"
"log"
+ "math"
"math/bits"
)
+// enable debug printing
const debug = false
+
+// Enable extra assertions.
+const debugAsserts = debug || false
+
+// print sequence details
const debugSequences = false
+
+// print detailed matching information
const debugMatches = false
// force encoder to use predefined tables.
@@ -19,6 +28,9 @@ const forcePreDef = false
// zstdMinMatch is the minimum zstd match length.
const zstdMinMatch = 3
+// Reset the buffer offset when reaching this.
+const bufferReset = math.MaxInt32 - MaxWindowSize
+
var (
// ErrReservedBlockType is returned when a reserved block type is found.
// Typically this indicates wrong or corrupted input.
@@ -75,6 +87,17 @@ func printf(format string, a ...interface{}) {
}
}
+// matchLenFast does matching, but will not match the last up to 7 bytes.
+func matchLenFast(a, b []byte) int {
+ endI := len(a) & (math.MaxInt32 - 7)
+ for i := 0; i < endI; i += 8 {
+ if diff := load64(a, i) ^ load64(b, i); diff != 0 {
+ return i + bits.TrailingZeros64(diff)>>3
+ }
+ }
+ return endI
+}
+
// matchLen returns the maximum length.
// a must be the shortest of the two.
// The function also returns whether all bytes matched.
@@ -85,33 +108,18 @@ func matchLen(a, b []byte) int {
return i + (bits.TrailingZeros64(diff) >> 3)
}
}
+
checked := (len(a) >> 3) << 3
a = a[checked:]
b = b[checked:]
- // TODO: We could do a 4 check.
for i := range a {
if a[i] != b[i] {
- return int(i) + checked
+ return i + checked
}
}
return len(a) + checked
}
-// matchLen returns a match length in src between index s and t
-func matchLenIn(src []byte, s, t int32) int32 {
- s1 := len(src)
- b := src[t:]
- a := src[s:s1]
- b = b[:len(a)]
- // Extend the match to be as long as possible.
- for i := range a {
- if a[i] != b[i] {
- return int32(i)
- }
- }
- return int32(len(a))
-}
-
func load3232(b []byte, i int32) uint32 {
// Help the compiler eliminate bounds checks on the read so it can be done in a single read.
b = b[i:]
diff --git a/vendor/github.com/klauspost/pgzip/README.md b/vendor/github.com/klauspost/pgzip/README.md
index 81000996c..171b978fd 100644
--- a/vendor/github.com/klauspost/pgzip/README.md
+++ b/vendor/github.com/klauspost/pgzip/README.md
@@ -39,7 +39,6 @@ You might need to get/update the dependencies:
```
go get -u github.com/klauspost/compress
-go get -u github.com/klauspost/crc32
```
Usage
@@ -65,7 +64,7 @@ Changes in [github.com/klauspost/compress](https://github.com/klauspost/compress
## Compression
The simplest way to use this is to simply do the same as you would when using [compress/gzip](http://golang.org/pkg/compress/gzip).
-To change the block size, use the added (*pgzip.Writer).SetConcurrency(blockSize, blocks int) function. With this you can control the approximate size of your blocks, as well as how many you want to be processing in parallel. Default values for this is SetConcurrency(250000, 16), meaning blocks are split at 250000 bytes and up to 16 blocks can be processing at once before the writer blocks.
+To change the block size, use the added (*pgzip.Writer).SetConcurrency(blockSize, blocks int) function. With this you can control the approximate size of your blocks, as well as how many you want to be processing in parallel. Default values for this is SetConcurrency(1MB, runtime.GOMAXPROCS(0)), meaning blocks are split at 1 MB and up to the number of CPU threads blocks can be processing at once before the writer blocks.
Example:
@@ -99,19 +98,19 @@ See my blog post in [Benchmarks of Golang Gzip](https://blog.klauspost.com/go-gz
Compression cost is usually about 0.2% with default settings with a block size of 250k.
-Example with GOMAXPROC set to 8 (quad core with 8 hyperthreads)
+Example with GOMAXPROC set to 32 (16 core CPU)
Content is [Matt Mahoneys 10GB corpus](http://mattmahoney.net/dc/10gb.html). Compression level 6.
Compressor | MB/sec | speedup | size | size overhead (lower=better)
------------|----------|---------|------|---------
-[gzip](http://golang.org/pkg/compress/gzip) (golang) | 7.21MB/s | 1.0x | 4786608902 | 0%
-[gzip](http://github.com/klauspost/compress/gzip) (klauspost) | 10.98MB/s | 1.52x | 4781331645 | -0.11%
-[pgzip](https://github.com/klauspost/pgzip) (klauspost) | 50.76MB/s|7.04x | 4784121440 | -0.052%
-[bgzf](https://godoc.org/github.com/biogo/hts/bgzf) (biogo) | 38.65MB/s | 5.36x | 4924899484 | 2.889%
-[pargzip](https://godoc.org/github.com/golang/build/pargzip) (builder) | 32.00MB/s | 4.44x | 4791226567 | 0.096%
+[gzip](http://golang.org/pkg/compress/gzip) (golang) | 15.44MB/s (1 thread) | 1.0x | 4781329307 | 0%
+[gzip](http://github.com/klauspost/compress/gzip) (klauspost) | 135.04MB/s (1 thread) | 8.74x | 4894858258 | +2.37%
+[pgzip](https://github.com/klauspost/pgzip) (klauspost) | 1573.23MB/s| 101.9x | 4902285651 | +2.53%
+[bgzf](https://godoc.org/github.com/biogo/hts/bgzf) (biogo) | 361.40MB/s | 23.4x | 4869686090 | +1.85%
+[pargzip](https://godoc.org/github.com/golang/build/pargzip) (builder) | 306.01MB/s | 19.8x | 4786890417 | +0.12%
-pgzip also contains a [linear time compression](https://github.com/klauspost/compress#linear-time-compression) mode, that will allow compression at ~150MB per core per second, independent of the content.
+pgzip also contains a [linear time compression](https://github.com/klauspost/compress#linear-time-compression-huffman-only) mode, that will allow compression at ~250MB per core per second, independent of the content.
See the [complete sheet](https://docs.google.com/spreadsheets/d/1nuNE2nPfuINCZJRMt6wFWhKpToF95I47XjSsc-1rbPQ/edit?usp=sharing) for different content types and compression settings.
diff --git a/vendor/github.com/klauspost/pgzip/gzip.go b/vendor/github.com/klauspost/pgzip/gzip.go
index 85d14e9cb..cb3dc0896 100644
--- a/vendor/github.com/klauspost/pgzip/gzip.go
+++ b/vendor/github.com/klauspost/pgzip/gzip.go
@@ -11,6 +11,7 @@ import (
"hash"
"hash/crc32"
"io"
+ "runtime"
"sync"
"time"
@@ -18,9 +19,9 @@ import (
)
const (
- defaultBlockSize = 256 << 10
+ defaultBlockSize = 1 << 20
tailSize = 16384
- defaultBlocks = 16
+ defaultBlocks = 4
)
// These constants are copied from the flate package, so that code that imports
@@ -68,8 +69,8 @@ type result struct {
// With this you can control the approximate size of your blocks,
// as well as how many you want to be processing in parallel.
//
-// Default values for this is SetConcurrency(250000, 16),
-// meaning blocks are split at 250000 bytes and up to 16 blocks
+// Default values for this is SetConcurrency(defaultBlockSize, runtime.GOMAXPROCS(0)),
+// meaning blocks are split at 1 MB and up to the number of CPU threads
// can be processing at once before the writer blocks.
func (z *Writer) SetConcurrency(blockSize, blocks int) error {
if blockSize <= tailSize {
@@ -84,7 +85,7 @@ func (z *Writer) SetConcurrency(blockSize, blocks int) error {
z.blockSize = blockSize
z.results = make(chan result, blocks)
z.blocks = blocks
- z.dstPool = sync.Pool{New: func() interface{} { return make([]byte, 0, blockSize+(blockSize)>>4) }}
+ z.dstPool.New = func() interface{} { return make([]byte, 0, blockSize+(blockSize)>>4) }
return nil
}
@@ -115,7 +116,7 @@ func NewWriterLevel(w io.Writer, level int) (*Writer, error) {
return nil, fmt.Errorf("gzip: invalid compression level: %d", level)
}
z := new(Writer)
- z.SetConcurrency(defaultBlockSize, defaultBlocks)
+ z.SetConcurrency(defaultBlockSize, runtime.GOMAXPROCS(0))
z.init(w, level)
return z, nil
}
@@ -174,7 +175,7 @@ func (z *Writer) Reset(w io.Writer) {
if z.results != nil && !z.closed {
close(z.results)
}
- z.SetConcurrency(defaultBlockSize, defaultBlocks)
+ z.SetConcurrency(defaultBlockSize, runtime.GOMAXPROCS(0))
z.init(w, z.level)
}
@@ -239,36 +240,36 @@ func (z *Writer) writeString(s string) (err error) {
// compressCurrent will compress the data currently buffered
// This should only be called from the main writer/flush/closer
func (z *Writer) compressCurrent(flush bool) {
+ c := z.currentBuffer
+ if len(c) > z.blockSize {
+ // This can never happen through the public interface.
+ panic("len(z.currentBuffer) > z.blockSize (most likely due to concurrent Write race)")
+ }
+
r := result{}
r.result = make(chan []byte, 1)
r.notifyWritten = make(chan struct{}, 0)
+ // Reserve a result slot
select {
case z.results <- r:
case <-z.pushedErr:
return
}
- // If block given is more than twice the block size, split it.
- c := z.currentBuffer
- if len(c) > z.blockSize*2 {
- c = c[:z.blockSize]
- z.wg.Add(1)
- go z.compressBlock(c, z.prevTail, r, false)
- z.prevTail = c[len(c)-tailSize:]
- z.currentBuffer = z.currentBuffer[z.blockSize:]
- z.compressCurrent(flush)
- // Last one flushes if needed
- return
- }
-
z.wg.Add(1)
- go z.compressBlock(c, z.prevTail, r, z.closed)
+ tail := z.prevTail
if len(c) > tailSize {
- z.prevTail = c[len(c)-tailSize:]
+ buf := z.dstPool.Get().([]byte) // Put in .compressBlock
+ // Copy tail from current buffer before handing the buffer over to the
+ // compressBlock goroutine.
+ buf = append(buf[:0], c[len(c)-tailSize:]...)
+ z.prevTail = buf
} else {
z.prevTail = nil
}
- z.currentBuffer = z.dstPool.Get().([]byte)
+ go z.compressBlock(c, tail, r, z.closed)
+
+ z.currentBuffer = z.dstPool.Get().([]byte) // Put in .compressBlock
z.currentBuffer = z.currentBuffer[:0]
// Wait if flushing
@@ -358,29 +359,37 @@ func (z *Writer) Write(p []byte) (int, error) {
// Start receiving data from compressors
go func() {
listen := z.results
+ var failed bool
for {
r, ok := <-listen
// If closed, we are finished.
if !ok {
return
}
+ if failed {
+ close(r.notifyWritten)
+ continue
+ }
buf := <-r.result
n, err := z.w.Write(buf)
if err != nil {
z.pushError(err)
close(r.notifyWritten)
- return
+ failed = true
+ continue
}
if n != len(buf) {
z.pushError(fmt.Errorf("gzip: short write %d should be %d", n, len(buf)))
+ failed = true
close(r.notifyWritten)
- return
+ continue
}
z.dstPool.Put(buf)
close(r.notifyWritten)
}
}()
- z.currentBuffer = make([]byte, 0, z.blockSize)
+ z.currentBuffer = z.dstPool.Get().([]byte)
+ z.currentBuffer = z.currentBuffer[:0]
}
q := p
for len(q) > 0 {
@@ -390,7 +399,10 @@ func (z *Writer) Write(p []byte) (int, error) {
}
z.digest.Write(q[:length])
z.currentBuffer = append(z.currentBuffer, q[:length]...)
- if len(z.currentBuffer) >= z.blockSize {
+ if len(z.currentBuffer) > z.blockSize {
+ panic("z.currentBuffer too large (most likely due to concurrent Write race)")
+ }
+ if len(z.currentBuffer) == z.blockSize {
z.compressCurrent(false)
if err := z.checkError(); err != nil {
return len(p) - len(q) - length, err
@@ -410,12 +422,13 @@ func (z *Writer) compressBlock(p, prevTail []byte, r result, closed bool) {
close(r.result)
z.wg.Done()
}()
- buf := z.dstPool.Get().([]byte)
+ buf := z.dstPool.Get().([]byte) // Corresponding Put in .Write's result writer
dest := bytes.NewBuffer(buf[:0])
- compressor := z.dictFlatePool.Get().(*flate.Writer)
+ compressor := z.dictFlatePool.Get().(*flate.Writer) // Put below
compressor.ResetDict(dest, prevTail)
compressor.Write(p)
+ z.dstPool.Put(p) // Corresponding Get in .Write and .compressCurrent
err := compressor.Flush()
if err != nil {
@@ -429,7 +442,12 @@ func (z *Writer) compressBlock(p, prevTail []byte, r result, closed bool) {
return
}
}
- z.dictFlatePool.Put(compressor)
+ z.dictFlatePool.Put(compressor) // Get above
+
+ if prevTail != nil {
+ z.dstPool.Put(prevTail) // Get in .compressCurrent
+ }
+
// Read back buffer
buf = dest.Bytes()
r.result <- buf
diff --git a/vendor/github.com/mattn/go-shellwords/go.mod b/vendor/github.com/mattn/go-shellwords/go.mod
index 8d96dbd5f..927c8c7d6 100644
--- a/vendor/github.com/mattn/go-shellwords/go.mod
+++ b/vendor/github.com/mattn/go-shellwords/go.mod
@@ -1 +1,3 @@
module github.com/mattn/go-shellwords
+
+go 1.13
diff --git a/vendor/github.com/mattn/go-shellwords/shellwords.go b/vendor/github.com/mattn/go-shellwords/shellwords.go
index ff5e73091..ef080861a 100644
--- a/vendor/github.com/mattn/go-shellwords/shellwords.go
+++ b/vendor/github.com/mattn/go-shellwords/shellwords.go
@@ -88,9 +88,17 @@ loop:
backtick += string(r)
} else if got {
if p.ParseEnv {
- buf = replaceEnv(p.Getenv, buf)
+ parser := &Parser{ParseEnv: false, ParseBacktick: false, Position: 0, Dir: p.Dir}
+ strs, err := parser.Parse(replaceEnv(p.Getenv, buf))
+ if err != nil {
+ return nil, err
+ }
+ for _, str := range strs {
+ args = append(args, str)
+ }
+ } else {
+ args = append(args, buf)
}
- args = append(args, buf)
buf = ""
got = false
}
@@ -144,7 +152,7 @@ loop:
}
case '"':
if !singleQuoted && !dollarQuote {
- if doubleQuoted && buf == "" {
+ if doubleQuoted {
got = true
}
doubleQuoted = !doubleQuoted
@@ -152,7 +160,7 @@ loop:
}
case '\'':
if !doubleQuoted && !dollarQuote {
- if singleQuoted && buf == "" {
+ if singleQuoted {
got = true
}
singleQuoted = !singleQuoted
@@ -180,9 +188,17 @@ loop:
if got {
if p.ParseEnv {
- buf = replaceEnv(p.Getenv, buf)
+ parser := &Parser{ParseEnv: false, ParseBacktick: false, Position: 0, Dir: p.Dir}
+ strs, err := parser.Parse(replaceEnv(p.Getenv, buf))
+ if err != nil {
+ return nil, err
+ }
+ for _, str := range strs {
+ args = append(args, str)
+ }
+ } else {
+ args = append(args, buf)
}
- args = append(args, buf)
}
if escaped || singleQuoted || doubleQuoted || backQuote || dollarQuote {
diff --git a/vendor/github.com/mattn/go-shellwords/util_go15.go b/vendor/github.com/mattn/go-shellwords/util_go15.go
deleted file mode 100644
index ddcbf229e..000000000
--- a/vendor/github.com/mattn/go-shellwords/util_go15.go
+++ /dev/null
@@ -1,29 +0,0 @@
-// +build !go1.6
-
-package shellwords
-
-import (
- "os"
- "os/exec"
- "runtime"
- "strings"
-)
-
-func shellRun(line, dir string) (string, error) {
- var b []byte
- var err error
- var cmd *exec.Cmd
- if runtime.GOOS == "windows" {
- cmd = exec.Command(os.Getenv("COMSPEC"), "/c", line)
- } else {
- cmd = exec.Command(os.Getenv("SHELL"), "-c", line)
- }
- if dir != "" {
- cmd.Dir = dir
- }
- b, err = cmd.Output()
- if err != nil {
- return "", err
- }
- return strings.TrimSpace(string(b)), nil
-}
diff --git a/vendor/github.com/mattn/go-shellwords/util_posix.go b/vendor/github.com/mattn/go-shellwords/util_posix.go
index 3aef2c4d7..988fc9ed2 100644
--- a/vendor/github.com/mattn/go-shellwords/util_posix.go
+++ b/vendor/github.com/mattn/go-shellwords/util_posix.go
@@ -1,4 +1,4 @@
-// +build !windows,go1.6
+// +build !windows
package shellwords
@@ -10,7 +10,10 @@ import (
)
func shellRun(line, dir string) (string, error) {
- shell := os.Getenv("SHELL")
+ var shell string
+ if shell = os.Getenv("SHELL"); shell == "" {
+ shell = "/bin/sh"
+ }
cmd := exec.Command(shell, "-c", line)
if dir != "" {
cmd.Dir = dir
diff --git a/vendor/github.com/mattn/go-shellwords/util_windows.go b/vendor/github.com/mattn/go-shellwords/util_windows.go
index cda685091..20546737c 100644
--- a/vendor/github.com/mattn/go-shellwords/util_windows.go
+++ b/vendor/github.com/mattn/go-shellwords/util_windows.go
@@ -1,4 +1,4 @@
-// +build windows,go1.6
+// +build windows
package shellwords
@@ -10,7 +10,10 @@ import (
)
func shellRun(line, dir string) (string, error) {
- shell := os.Getenv("COMSPEC")
+ var shell string
+ if shell = os.Getenv("COMSPEC"); shell == "" {
+ shell = "cmd"
+ }
cmd := exec.Command(shell, "/c", line)
if dir != "" {
cmd.Dir = dir
diff --git a/vendor/github.com/mtrmac/gpgme/.appveyor.yml b/vendor/github.com/mtrmac/gpgme/.appveyor.yml
new file mode 100644
index 000000000..2fdc09ab5
--- /dev/null
+++ b/vendor/github.com/mtrmac/gpgme/.appveyor.yml
@@ -0,0 +1,40 @@
+---
+version: 0.{build}
+platform: x86
+branches:
+ only:
+ - master
+
+clone_folder: c:\gopath\src\github.com\proglottis\gpgme
+
+environment:
+ GOPATH: c:\gopath
+ GOROOT: C:\go-x86
+ CGO_LDFLAGS: -LC:\gpg\lib
+ CGO_CFLAGS: -IC:\gpg\include
+ GPG_DIR: C:\gpg
+
+install:
+ - nuget install 7ZipCLI -ExcludeVersion
+ - set PATH=%appveyor_build_folder%\7ZipCLI\tools;%PATH%
+ - appveyor DownloadFile https://www.gnupg.org/ftp/gcrypt/binary/gnupg-w32-2.1.20_20170403.exe -FileName gnupg-w32-2.1.20_20170403.exe
+ - 7z x -o%GPG_DIR% gnupg-w32-2.1.20_20170403.exe
+ - copy "%GPG_DIR%\lib\libgpg-error.imp" "%GPG_DIR%\lib\libgpg-error.a"
+ - copy "%GPG_DIR%\lib\libassuan.imp" "%GPG_DIR%\lib\libassuan.a"
+ - copy "%GPG_DIR%\lib\libgpgme.imp" "%GPG_DIR%\lib\libgpgme.a"
+ - set PATH=%GOPATH%\bin;%GOROOT%\bin;%GPG_DIR%\bin;C:\MinGW\bin;%PATH%
+ - C:\cygwin\bin\sed -i 's/"GPG_AGENT_INFO"/"GPG_AGENT_INFO="/;s/C.unsetenv(v)/C.putenv(v)/' %APPVEYOR_BUILD_FOLDER%\gpgme.go
+
+test_script:
+ - go test -v github.com/proglottis/gpgme
+
+
+build_script:
+ - go build -o example_decrypt.exe -i %APPVEYOR_BUILD_FOLDER%\examples\decrypt.go
+ - go build -o example_encrypt.exe -i %APPVEYOR_BUILD_FOLDER%\examples\encrypt.go
+
+artifacts:
+ - path: example_decrypt.exe
+ name: decrypt example binary
+ - path: example_encrypt.exe
+ name: encrypt example binary \ No newline at end of file
diff --git a/vendor/github.com/mtrmac/gpgme/.travis.yml b/vendor/github.com/mtrmac/gpgme/.travis.yml
new file mode 100644
index 000000000..619e33721
--- /dev/null
+++ b/vendor/github.com/mtrmac/gpgme/.travis.yml
@@ -0,0 +1,32 @@
+---
+language: go
+os:
+ - linux
+ - osx
+ - windows
+dist: xenial
+sudo: false
+
+go:
+ - 1.11
+ - 1.12
+ - 1.13
+
+addons:
+ apt:
+ packages:
+ - libgpgme11-dev
+ homebrew:
+ packages:
+ - gnupg
+ - gnupg@1.4
+ - gpgme
+ update: true
+
+matrix:
+ allow_failures:
+ - os: windows
+
+before_install:
+ - if [[ "$TRAVIS_OS_NAME" == "windows" ]]; then choco install msys2; fi
+ - if [[ "$TRAVIS_OS_NAME" == "windows" ]]; then choco install gpg4win; fi
diff --git a/vendor/github.com/mtrmac/gpgme/data.go b/vendor/github.com/mtrmac/gpgme/data.go
index eebc97263..eee32c032 100644
--- a/vendor/github.com/mtrmac/gpgme/data.go
+++ b/vendor/github.com/mtrmac/gpgme/data.go
@@ -50,25 +50,25 @@ func gogpgme_writefunc(handle, buffer unsafe.Pointer, size C.size_t) C.ssize_t {
}
//export gogpgme_seekfunc
-func gogpgme_seekfunc(handle unsafe.Pointer, offset C.off_t, whence C.int) C.off_t {
+func gogpgme_seekfunc(handle unsafe.Pointer, offset C.gpgme_off_t, whence C.int) C.gpgme_off_t {
d := callbackLookup(uintptr(handle)).(*Data)
n, err := d.s.Seek(int64(offset), int(whence))
if err != nil {
C.gpgme_err_set_errno(C.EIO)
return -1
}
- return C.off_t(n)
+ return C.gpgme_off_t(n)
}
// The Data buffer used to communicate with GPGME
type Data struct {
- dh C.gpgme_data_t
+ dh C.gpgme_data_t // WARNING: Call runtime.KeepAlive(d) after ANY passing of d.dh to C
buf []byte
cbs C.struct_gpgme_data_cbs
r io.Reader
w io.Writer
s io.Seeker
- cbc uintptr
+ cbc uintptr // WARNING: Call runtime.KeepAlive(d) after ANY use of d.cbc in C (typically via d.dh)
}
func newData() *Data {
@@ -154,12 +154,14 @@ func (d *Data) Close() error {
callbackDelete(d.cbc)
}
_, err := C.gpgme_data_release(d.dh)
+ runtime.KeepAlive(d)
d.dh = nil
return err
}
func (d *Data) Write(p []byte) (int, error) {
n, err := C.gpgme_data_write(d.dh, unsafe.Pointer(&p[0]), C.size_t(len(p)))
+ runtime.KeepAlive(d)
if err != nil {
return 0, err
}
@@ -171,6 +173,7 @@ func (d *Data) Write(p []byte) (int, error) {
func (d *Data) Read(p []byte) (int, error) {
n, err := C.gpgme_data_read(d.dh, unsafe.Pointer(&p[0]), C.size_t(len(p)))
+ runtime.KeepAlive(d)
if err != nil {
return 0, err
}
@@ -181,11 +184,14 @@ func (d *Data) Read(p []byte) (int, error) {
}
func (d *Data) Seek(offset int64, whence int) (int64, error) {
- n, err := C.gpgme_data_seek(d.dh, C.off_t(offset), C.int(whence))
+ n, err := C.gogpgme_data_seek(d.dh, C.gpgme_off_t(offset), C.int(whence))
+ runtime.KeepAlive(d)
return int64(n), err
}
// Name returns the associated filename if any
func (d *Data) Name() string {
- return C.GoString(C.gpgme_data_get_file_name(d.dh))
+ res := C.GoString(C.gpgme_data_get_file_name(d.dh))
+ runtime.KeepAlive(d)
+ return res
}
diff --git a/vendor/github.com/mtrmac/gpgme/go.mod b/vendor/github.com/mtrmac/gpgme/go.mod
new file mode 100644
index 000000000..3dd09c9fb
--- /dev/null
+++ b/vendor/github.com/mtrmac/gpgme/go.mod
@@ -0,0 +1,3 @@
+module github.com/mtrmac/gpgme
+
+go 1.11
diff --git a/vendor/github.com/mtrmac/gpgme/go_gpgme.c b/vendor/github.com/mtrmac/gpgme/go_gpgme.c
index b887574e0..00da3ab30 100644
--- a/vendor/github.com/mtrmac/gpgme/go_gpgme.c
+++ b/vendor/github.com/mtrmac/gpgme/go_gpgme.c
@@ -8,6 +8,28 @@ void gogpgme_set_passphrase_cb(gpgme_ctx_t ctx, gpgme_passphrase_cb_t cb, uintpt
gpgme_set_passphrase_cb(ctx, cb, (void *)handle);
}
+gpgme_off_t gogpgme_data_seek(gpgme_data_t dh, gpgme_off_t offset, int whence) {
+ return gpgme_data_seek(dh, offset, whence);
+}
+
+gpgme_error_t gogpgme_op_assuan_transact_ext(
+ gpgme_ctx_t ctx,
+ char* cmd,
+ uintptr_t data_h,
+ uintptr_t inquiry_h,
+ uintptr_t status_h,
+ gpgme_error_t *operr
+ ){
+ return gpgme_op_assuan_transact_ext(
+ ctx,
+ cmd,
+ (gpgme_assuan_data_cb_t) gogpgme_assuan_data_callback, (void *)data_h,
+ (gpgme_assuan_inquire_cb_t) gogpgme_assuan_inquiry_callback, (void *)inquiry_h,
+ (gpgme_assuan_status_cb_t) gogpgme_assuan_status_callback, (void *)status_h,
+ operr
+ );
+}
+
unsigned int key_revoked(gpgme_key_t k) {
return k->revoked;
}
diff --git a/vendor/github.com/mtrmac/gpgme/go_gpgme.h b/vendor/github.com/mtrmac/gpgme/go_gpgme.h
index a3678b127..d4826ab36 100644
--- a/vendor/github.com/mtrmac/gpgme/go_gpgme.h
+++ b/vendor/github.com/mtrmac/gpgme/go_gpgme.h
@@ -6,12 +6,24 @@
#include <gpgme.h>
+/* GPGME_VERSION_NUMBER was introduced in 1.4.0 */
+#if !defined(GPGME_VERSION_NUMBER) || GPGME_VERSION_NUMBER < 0x010402
+typedef off_t gpgme_off_t; /* Introduced in 1.4.2 */
+#endif
+
extern ssize_t gogpgme_readfunc(void *handle, void *buffer, size_t size);
extern ssize_t gogpgme_writefunc(void *handle, void *buffer, size_t size);
extern off_t gogpgme_seekfunc(void *handle, off_t offset, int whence);
extern gpgme_error_t gogpgme_passfunc(void *hook, char *uid_hint, char *passphrase_info, int prev_was_bad, int fd);
extern gpgme_error_t gogpgme_data_new_from_cbs(gpgme_data_t *dh, gpgme_data_cbs_t cbs, uintptr_t handle);
extern void gogpgme_set_passphrase_cb(gpgme_ctx_t ctx, gpgme_passphrase_cb_t cb, uintptr_t handle);
+extern gpgme_off_t gogpgme_data_seek(gpgme_data_t dh, gpgme_off_t offset, int whence);
+
+extern gpgme_error_t gogpgme_op_assuan_transact_ext(gpgme_ctx_t ctx, char *cmd, uintptr_t data_h, uintptr_t inquiry_h , uintptr_t status_h, gpgme_error_t *operr);
+
+extern gpgme_error_t gogpgme_assuan_data_callback(void *opaque, void* data, size_t datalen );
+extern gpgme_error_t gogpgme_assuan_inquiry_callback(void *opaque, char* name, char* args);
+extern gpgme_error_t gogpgme_assuan_status_callback(void *opaque, char* status, char* args);
extern unsigned int key_revoked(gpgme_key_t k);
extern unsigned int key_expired(gpgme_key_t k);
diff --git a/vendor/github.com/mtrmac/gpgme/gpgme.go b/vendor/github.com/mtrmac/gpgme/gpgme.go
index 20aad737c..c19b9aebc 100644
--- a/vendor/github.com/mtrmac/gpgme/gpgme.go
+++ b/vendor/github.com/mtrmac/gpgme/gpgme.go
@@ -7,7 +7,6 @@ package gpgme
// #include <gpgme.h>
// #include "go_gpgme.h"
import "C"
-
import (
"fmt"
"io"
@@ -48,9 +47,8 @@ const (
ProtocolAssuan Protocol = C.GPGME_PROTOCOL_ASSUAN
ProtocolG13 Protocol = C.GPGME_PROTOCOL_G13
ProtocolUIServer Protocol = C.GPGME_PROTOCOL_UISERVER
- // ProtocolSpawn Protocol = C.GPGME_PROTOCOL_SPAWN // Unavailable in 1.4.3
- ProtocolDefault Protocol = C.GPGME_PROTOCOL_DEFAULT
- ProtocolUnknown Protocol = C.GPGME_PROTOCOL_UNKNOWN
+ ProtocolDefault Protocol = C.GPGME_PROTOCOL_DEFAULT
+ ProtocolUnknown Protocol = C.GPGME_PROTOCOL_UNKNOWN
)
type PinEntryMode int
@@ -70,7 +68,6 @@ const (
EncryptNoEncryptTo EncryptFlag = C.GPGME_ENCRYPT_NO_ENCRYPT_TO
EncryptPrepare EncryptFlag = C.GPGME_ENCRYPT_PREPARE
EncryptExceptSign EncryptFlag = C.GPGME_ENCRYPT_EXPECT_SIGN
- // EncryptNoCompress EncryptFlag = C.GPGME_ENCRYPT_NO_COMPRESS // Unavailable in 1.4.3
)
type HashAlgo int
@@ -84,7 +81,6 @@ const (
KeyListModeExtern KeyListMode = C.GPGME_KEYLIST_MODE_EXTERN
KeyListModeSigs KeyListMode = C.GPGME_KEYLIST_MODE_SIGS
KeyListModeSigNotations KeyListMode = C.GPGME_KEYLIST_MODE_SIG_NOTATIONS
- // KeyListModeWithSecret KeyListMode = C.GPGME_KEYLIST_MODE_WITH_SECRET // Unavailable in 1.4.3
KeyListModeEphemeral KeyListMode = C.GPGME_KEYLIST_MODE_EPHEMERAL
KeyListModeModeValidate KeyListMode = C.GPGME_KEYLIST_MODE_VALIDATE
)
@@ -168,39 +164,60 @@ func EngineCheckVersion(p Protocol) error {
}
type EngineInfo struct {
- info C.gpgme_engine_info_t
+ next *EngineInfo
+ protocol Protocol
+ fileName string
+ homeDir string
+ version string
+ requiredVersion string
}
-func (e *EngineInfo) Next() *EngineInfo {
- if e.info.next == nil {
- return nil
+func copyEngineInfo(info C.gpgme_engine_info_t) *EngineInfo {
+ res := &EngineInfo{
+ next: nil,
+ protocol: Protocol(info.protocol),
+ fileName: C.GoString(info.file_name),
+ homeDir: C.GoString(info.home_dir),
+ version: C.GoString(info.version),
+ requiredVersion: C.GoString(info.req_version),
+ }
+ if info.next != nil {
+ res.next = copyEngineInfo(info.next)
}
- return &EngineInfo{info: e.info.next}
+ return res
+}
+
+func (e *EngineInfo) Next() *EngineInfo {
+ return e.next
}
func (e *EngineInfo) Protocol() Protocol {
- return Protocol(e.info.protocol)
+ return e.protocol
}
func (e *EngineInfo) FileName() string {
- return C.GoString(e.info.file_name)
+ return e.fileName
}
func (e *EngineInfo) Version() string {
- return C.GoString(e.info.version)
+ return e.version
}
func (e *EngineInfo) RequiredVersion() string {
- return C.GoString(e.info.req_version)
+ return e.requiredVersion
}
func (e *EngineInfo) HomeDir() string {
- return C.GoString(e.info.home_dir)
+ return e.homeDir
}
func GetEngineInfo() (*EngineInfo, error) {
- info := &EngineInfo{}
- return info, handleError(C.gpgme_get_engine_info(&info.info))
+ var cInfo C.gpgme_engine_info_t
+ err := handleError(C.gpgme_get_engine_info(&cInfo))
+ if err != nil {
+ return nil, err
+ }
+ return copyEngineInfo(cInfo), nil // It is up to the caller not to invalidate cInfo concurrently until this is done.
}
func SetEngineInfo(proto Protocol, fileName, homeDir string) error {
@@ -261,9 +278,9 @@ type Context struct {
KeyError error
callback Callback
- cbc uintptr
+ cbc uintptr // WARNING: Call runtime.KeepAlive(c) after ANY use of c.cbc in C (typically via c.ctx)
- ctx C.gpgme_ctx_t
+ ctx C.gpgme_ctx_t // WARNING: Call runtime.KeepAlive(c) after ANY passing of c.ctx to C
}
func New() (*Context, error) {
@@ -281,49 +298,68 @@ func (c *Context) Release() {
callbackDelete(c.cbc)
}
C.gpgme_release(c.ctx)
+ runtime.KeepAlive(c)
c.ctx = nil
}
func (c *Context) SetArmor(yes bool) {
C.gpgme_set_armor(c.ctx, cbool(yes))
+ runtime.KeepAlive(c)
}
func (c *Context) Armor() bool {
- return C.gpgme_get_armor(c.ctx) != 0
+ res := C.gpgme_get_armor(c.ctx) != 0
+ runtime.KeepAlive(c)
+ return res
}
func (c *Context) SetTextMode(yes bool) {
C.gpgme_set_textmode(c.ctx, cbool(yes))
+ runtime.KeepAlive(c)
}
func (c *Context) TextMode() bool {
- return C.gpgme_get_textmode(c.ctx) != 0
+ res := C.gpgme_get_textmode(c.ctx) != 0
+ runtime.KeepAlive(c)
+ return res
}
func (c *Context) SetProtocol(p Protocol) error {
- return handleError(C.gpgme_set_protocol(c.ctx, C.gpgme_protocol_t(p)))
+ err := handleError(C.gpgme_set_protocol(c.ctx, C.gpgme_protocol_t(p)))
+ runtime.KeepAlive(c)
+ return err
}
func (c *Context) Protocol() Protocol {
- return Protocol(C.gpgme_get_protocol(c.ctx))
+ res := Protocol(C.gpgme_get_protocol(c.ctx))
+ runtime.KeepAlive(c)
+ return res
}
func (c *Context) SetKeyListMode(m KeyListMode) error {
- return handleError(C.gpgme_set_keylist_mode(c.ctx, C.gpgme_keylist_mode_t(m)))
+ err := handleError(C.gpgme_set_keylist_mode(c.ctx, C.gpgme_keylist_mode_t(m)))
+ runtime.KeepAlive(c)
+ return err
}
func (c *Context) KeyListMode() KeyListMode {
- return KeyListMode(C.gpgme_get_keylist_mode(c.ctx))
+ res := KeyListMode(C.gpgme_get_keylist_mode(c.ctx))
+ runtime.KeepAlive(c)
+ return res
}
// Unavailable in 1.3.2:
// func (c *Context) SetPinEntryMode(m PinEntryMode) error {
-// return handleError(C.gpgme_set_pinentry_mode(c.ctx, C.gpgme_pinentry_mode_t(m)))
+// err := handleError(C.gpgme_set_pinentry_mode(c.ctx, C.gpgme_pinentry_mode_t(m)))
+// runtime.KeepAlive(c)
+// return err
// }
// Unavailable in 1.3.2:
// func (c *Context) PinEntryMode() PinEntryMode {
-// return PinEntryMode(C.gpgme_get_pinentry_mode(c.ctx))
+// res := PinEntryMode(C.gpgme_get_pinentry_mode(c.ctx))
+// runtime.KeepAlive(c)
+// return res
// }
func (c *Context) SetCallback(callback Callback) error {
@@ -340,11 +376,17 @@ func (c *Context) SetCallback(callback Callback) error {
c.cbc = 0
_, err = C.gogpgme_set_passphrase_cb(c.ctx, nil, 0)
}
+ runtime.KeepAlive(c)
return err
}
func (c *Context) EngineInfo() *EngineInfo {
- return &EngineInfo{info: C.gpgme_ctx_get_engine_info(c.ctx)}
+ cInfo := C.gpgme_ctx_get_engine_info(c.ctx)
+ runtime.KeepAlive(c)
+ // NOTE: c must be live as long as we are accessing cInfo.
+ res := copyEngineInfo(cInfo)
+ runtime.KeepAlive(c) // for accesses to cInfo
+ return res
}
func (c *Context) SetEngineInfo(proto Protocol, fileName, homeDir string) error {
@@ -357,19 +399,23 @@ func (c *Context) SetEngineInfo(proto Protocol, fileName, homeDir string) error
chome = C.CString(homeDir)
defer C.free(unsafe.Pointer(chome))
}
- return handleError(C.gpgme_ctx_set_engine_info(c.ctx, C.gpgme_protocol_t(proto), cfn, chome))
+ err := handleError(C.gpgme_ctx_set_engine_info(c.ctx, C.gpgme_protocol_t(proto), cfn, chome))
+ runtime.KeepAlive(c)
+ return err
}
func (c *Context) KeyListStart(pattern string, secretOnly bool) error {
cpattern := C.CString(pattern)
defer C.free(unsafe.Pointer(cpattern))
- err := C.gpgme_op_keylist_start(c.ctx, cpattern, cbool(secretOnly))
- return handleError(err)
+ err := handleError(C.gpgme_op_keylist_start(c.ctx, cpattern, cbool(secretOnly)))
+ runtime.KeepAlive(c)
+ return err
}
func (c *Context) KeyListNext() bool {
c.Key = newKey()
err := handleError(C.gpgme_op_keylist_next(c.ctx, &c.Key.k))
+ runtime.KeepAlive(c) // implies runtime.KeepAlive(c.Key)
if err != nil {
if e, ok := err.(Error); ok && e.Code() == ErrorEOF {
c.KeyError = nil
@@ -383,7 +429,9 @@ func (c *Context) KeyListNext() bool {
}
func (c *Context) KeyListEnd() error {
- return handleError(C.gpgme_op_keylist_end(c.ctx))
+ err := handleError(C.gpgme_op_keylist_end(c.ctx))
+ runtime.KeepAlive(c)
+ return err
}
func (c *Context) GetKey(fingerprint string, secret bool) (*Key, error) {
@@ -391,7 +439,11 @@ func (c *Context) GetKey(fingerprint string, secret bool) (*Key, error) {
cfpr := C.CString(fingerprint)
defer C.free(unsafe.Pointer(cfpr))
err := handleError(C.gpgme_get_key(c.ctx, cfpr, &key.k, cbool(secret)))
- if e, ok := err.(Error); key.k == nil && ok && e.Code() == ErrorEOF {
+ runtime.KeepAlive(c)
+ runtime.KeepAlive(key)
+ keyKIsNil := key.k == nil
+ runtime.KeepAlive(key)
+ if e, ok := err.(Error); keyKIsNil && ok && e.Code() == ErrorEOF {
return nil, fmt.Errorf("key %q not found", fingerprint)
}
if err != nil {
@@ -401,11 +453,19 @@ func (c *Context) GetKey(fingerprint string, secret bool) (*Key, error) {
}
func (c *Context) Decrypt(ciphertext, plaintext *Data) error {
- return handleError(C.gpgme_op_decrypt(c.ctx, ciphertext.dh, plaintext.dh))
+ err := handleError(C.gpgme_op_decrypt(c.ctx, ciphertext.dh, plaintext.dh))
+ runtime.KeepAlive(c)
+ runtime.KeepAlive(ciphertext)
+ runtime.KeepAlive(plaintext)
+ return err
}
func (c *Context) DecryptVerify(ciphertext, plaintext *Data) error {
- return handleError(C.gpgme_op_decrypt_verify(c.ctx, ciphertext.dh, plaintext.dh))
+ err := handleError(C.gpgme_op_decrypt_verify(c.ctx, ciphertext.dh, plaintext.dh))
+ runtime.KeepAlive(c)
+ runtime.KeepAlive(ciphertext)
+ runtime.KeepAlive(plaintext)
+ return err
}
type Signature struct {
@@ -432,10 +492,20 @@ func (c *Context) Verify(sig, signedText, plain *Data) (string, []Signature, err
plainPtr = plain.dh
}
err := handleError(C.gpgme_op_verify(c.ctx, sig.dh, signedTextPtr, plainPtr))
+ runtime.KeepAlive(c)
+ runtime.KeepAlive(sig)
+ if signedText != nil {
+ runtime.KeepAlive(signedText)
+ }
+ if plain != nil {
+ runtime.KeepAlive(plain)
+ }
if err != nil {
return "", nil, err
}
res := C.gpgme_op_verify_result(c.ctx)
+ runtime.KeepAlive(c)
+ // NOTE: c must be live as long as we are accessing res.
sigs := []Signature{}
for s := res.signatures; s != nil; s = s.next {
sig := Signature{
@@ -455,7 +525,9 @@ func (c *Context) Verify(sig, signedText, plain *Data) (string, []Signature, err
}
sigs = append(sigs, sig)
}
- return C.GoString(res.file_name), sigs, nil
+ fileName := C.GoString(res.file_name)
+ runtime.KeepAlive(c) // for all accesses to res above
+ return fileName, sigs, nil
}
func (c *Context) Encrypt(recipients []*Key, flags EncryptFlag, plaintext, ciphertext *Data) error {
@@ -467,18 +539,116 @@ func (c *Context) Encrypt(recipients []*Key, flags EncryptFlag, plaintext, ciphe
*ptr = recipients[i].k
}
err := C.gpgme_op_encrypt(c.ctx, (*C.gpgme_key_t)(recp), C.gpgme_encrypt_flags_t(flags), plaintext.dh, ciphertext.dh)
+ runtime.KeepAlive(c)
+ runtime.KeepAlive(recipients)
+ runtime.KeepAlive(plaintext)
+ runtime.KeepAlive(ciphertext)
return handleError(err)
}
func (c *Context) Sign(signers []*Key, plain, sig *Data, mode SigMode) error {
C.gpgme_signers_clear(c.ctx)
+ runtime.KeepAlive(c)
for _, k := range signers {
- if err := handleError(C.gpgme_signers_add(c.ctx, k.k)); err != nil {
+ err := handleError(C.gpgme_signers_add(c.ctx, k.k))
+ runtime.KeepAlive(c)
+ runtime.KeepAlive(k)
+ if err != nil {
C.gpgme_signers_clear(c.ctx)
+ runtime.KeepAlive(c)
return err
}
}
- return handleError(C.gpgme_op_sign(c.ctx, plain.dh, sig.dh, C.gpgme_sig_mode_t(mode)))
+ err := handleError(C.gpgme_op_sign(c.ctx, plain.dh, sig.dh, C.gpgme_sig_mode_t(mode)))
+ runtime.KeepAlive(c)
+ runtime.KeepAlive(plain)
+ runtime.KeepAlive(sig)
+ return err
+}
+
+type AssuanDataCallback func(data []byte) error
+type AssuanInquireCallback func(name, args string) error
+type AssuanStatusCallback func(status, args string) error
+
+// AssuanSend sends a raw Assuan command to gpg-agent
+func (c *Context) AssuanSend(
+ cmd string,
+ data AssuanDataCallback,
+ inquiry AssuanInquireCallback,
+ status AssuanStatusCallback,
+) error {
+ var operr C.gpgme_error_t
+
+ dataPtr := callbackAdd(&data)
+ inquiryPtr := callbackAdd(&inquiry)
+ statusPtr := callbackAdd(&status)
+ cmdCStr := C.CString(cmd)
+ defer C.free(unsafe.Pointer(cmdCStr))
+ err := C.gogpgme_op_assuan_transact_ext(
+ c.ctx,
+ cmdCStr,
+ C.uintptr_t(dataPtr),
+ C.uintptr_t(inquiryPtr),
+ C.uintptr_t(statusPtr),
+ &operr,
+ )
+ runtime.KeepAlive(c)
+
+ if handleError(operr) != nil {
+ return handleError(operr)
+ }
+ return handleError(err)
+}
+
+//export gogpgme_assuan_data_callback
+func gogpgme_assuan_data_callback(handle unsafe.Pointer, data unsafe.Pointer, datalen C.size_t) C.gpgme_error_t {
+ c := callbackLookup(uintptr(handle)).(*AssuanDataCallback)
+ if *c == nil {
+ return 0
+ }
+ (*c)(C.GoBytes(data, C.int(datalen)))
+ return 0
+}
+
+//export gogpgme_assuan_inquiry_callback
+func gogpgme_assuan_inquiry_callback(handle unsafe.Pointer, cName *C.char, cArgs *C.char) C.gpgme_error_t {
+ name := C.GoString(cName)
+ args := C.GoString(cArgs)
+ c := callbackLookup(uintptr(handle)).(*AssuanInquireCallback)
+ if *c == nil {
+ return 0
+ }
+ (*c)(name, args)
+ return 0
+}
+
+//export gogpgme_assuan_status_callback
+func gogpgme_assuan_status_callback(handle unsafe.Pointer, cStatus *C.char, cArgs *C.char) C.gpgme_error_t {
+ status := C.GoString(cStatus)
+ args := C.GoString(cArgs)
+ c := callbackLookup(uintptr(handle)).(*AssuanStatusCallback)
+ if *c == nil {
+ return 0
+ }
+ (*c)(status, args)
+ return 0
+}
+
+// ExportModeFlags defines how keys are exported from Export
+type ExportModeFlags uint
+
+const (
+ ExportModeExtern ExportModeFlags = C.GPGME_EXPORT_MODE_EXTERN
+ ExportModeMinimal ExportModeFlags = C.GPGME_EXPORT_MODE_MINIMAL
+)
+
+func (c *Context) Export(pattern string, mode ExportModeFlags, data *Data) error {
+ pat := C.CString(pattern)
+ defer C.free(unsafe.Pointer(pat))
+ err := handleError(C.gpgme_op_export(c.ctx, pat, C.gpgme_export_mode_t(mode), data.dh))
+ runtime.KeepAlive(c)
+ runtime.KeepAlive(data)
+ return err
}
// ImportStatusFlags describes the type of ImportStatus.Status. The C API in gpgme.h simply uses "unsigned".
@@ -517,10 +687,14 @@ type ImportResult struct {
func (c *Context) Import(keyData *Data) (*ImportResult, error) {
err := handleError(C.gpgme_op_import(c.ctx, keyData.dh))
+ runtime.KeepAlive(c)
+ runtime.KeepAlive(keyData)
if err != nil {
return nil, err
}
res := C.gpgme_op_import_result(c.ctx)
+ runtime.KeepAlive(c)
+ // NOTE: c must be live as long as we are accessing res.
imports := []ImportStatus{}
for s := res.imports; s != nil; s = s.next {
imports = append(imports, ImportStatus{
@@ -529,7 +703,7 @@ func (c *Context) Import(keyData *Data) (*ImportResult, error) {
Status: ImportStatusFlags(s.status),
})
}
- return &ImportResult{
+ importResult := &ImportResult{
Considered: int(res.considered),
NoUserID: int(res.no_user_id),
Imported: int(res.imported),
@@ -544,11 +718,13 @@ func (c *Context) Import(keyData *Data) (*ImportResult, error) {
SecretUnchanged: int(res.secret_unchanged),
NotImported: int(res.not_imported),
Imports: imports,
- }, nil
+ }
+ runtime.KeepAlive(c) // for all accesses to res above
+ return importResult, nil
}
type Key struct {
- k C.gpgme_key_t
+ k C.gpgme_key_t // WARNING: Call Runtime.KeepAlive(k) after ANY passing of k.k to C
}
func newKey() *Key {
@@ -559,85 +735,122 @@ func newKey() *Key {
func (k *Key) Release() {
C.gpgme_key_release(k.k)
+ runtime.KeepAlive(k)
k.k = nil
}
func (k *Key) Revoked() bool {
- return C.key_revoked(k.k) != 0
+ res := C.key_revoked(k.k) != 0
+ runtime.KeepAlive(k)
+ return res
}
func (k *Key) Expired() bool {
- return C.key_expired(k.k) != 0
+ res := C.key_expired(k.k) != 0
+ runtime.KeepAlive(k)
+ return res
}
func (k *Key) Disabled() bool {
- return C.key_disabled(k.k) != 0
+ res := C.key_disabled(k.k) != 0
+ runtime.KeepAlive(k)
+ return res
}
func (k *Key) Invalid() bool {
- return C.key_invalid(k.k) != 0
+ res := C.key_invalid(k.k) != 0
+ runtime.KeepAlive(k)
+ return res
}
func (k *Key) CanEncrypt() bool {
- return C.key_can_encrypt(k.k) != 0
+ res := C.key_can_encrypt(k.k) != 0
+ runtime.KeepAlive(k)
+ return res
}
func (k *Key) CanSign() bool {
- return C.key_can_sign(k.k) != 0
+ res := C.key_can_sign(k.k) != 0
+ runtime.KeepAlive(k)
+ return res
}
func (k *Key) CanCertify() bool {
- return C.key_can_certify(k.k) != 0
+ res := C.key_can_certify(k.k) != 0
+ runtime.KeepAlive(k)
+ return res
}
func (k *Key) Secret() bool {
- return C.key_secret(k.k) != 0
+ res := C.key_secret(k.k) != 0
+ runtime.KeepAlive(k)
+ return res
}
func (k *Key) CanAuthenticate() bool {
- return C.key_can_authenticate(k.k) != 0
+ res := C.key_can_authenticate(k.k) != 0
+ runtime.KeepAlive(k)
+ return res
}
func (k *Key) IsQualified() bool {
- return C.key_is_qualified(k.k) != 0
+ res := C.key_is_qualified(k.k) != 0
+ runtime.KeepAlive(k)
+ return res
}
func (k *Key) Protocol() Protocol {
- return Protocol(k.k.protocol)
+ res := Protocol(k.k.protocol)
+ runtime.KeepAlive(k)
+ return res
}
func (k *Key) IssuerSerial() string {
- return C.GoString(k.k.issuer_serial)
+ res := C.GoString(k.k.issuer_serial)
+ runtime.KeepAlive(k)
+ return res
}
func (k *Key) IssuerName() string {
- return C.GoString(k.k.issuer_name)
+ res := C.GoString(k.k.issuer_name)
+ runtime.KeepAlive(k)
+ return res
}
func (k *Key) ChainID() string {
- return C.GoString(k.k.chain_id)
+ res := C.GoString(k.k.chain_id)
+ runtime.KeepAlive(k)
+ return res
}
func (k *Key) OwnerTrust() Validity {
- return Validity(k.k.owner_trust)
+ res := Validity(k.k.owner_trust)
+ runtime.KeepAlive(k)
+ return res
}
func (k *Key) SubKeys() *SubKey {
- if k.k.subkeys == nil {
+ subKeys := k.k.subkeys
+ runtime.KeepAlive(k)
+ if subKeys == nil {
return nil
}
- return &SubKey{k: k.k.subkeys, parent: k}
+ return &SubKey{k: subKeys, parent: k} // The parent: k reference ensures subKeys remains valid
}
func (k *Key) UserIDs() *UserID {
- if k.k.uids == nil {
+ uids := k.k.uids
+ runtime.KeepAlive(k)
+ if uids == nil {
return nil
}
- return &UserID{u: k.k.uids, parent: k}
+ return &UserID{u: uids, parent: k} // The parent: k reference ensures uids remains valid
}
func (k *Key) KeyListMode() KeyListMode {
- return KeyListMode(k.k.keylist_mode)
+ res := KeyListMode(k.k.keylist_mode)
+ runtime.KeepAlive(k)
+ return res
}
type SubKey struct {
@@ -737,12 +950,3 @@ func (u *UserID) Comment() string {
func (u *UserID) Email() string {
return C.GoString(u.u.email)
}
-
-// This is somewhat of a horrible hack. We need to unset GPG_AGENT_INFO so that gpgme does not pass --use-agent to GPG.
-// os.Unsetenv should be enough, but that only calls the underlying C library (which gpgme uses) if cgo is involved
-// - and cgo can't be used in tests. So, provide this helper for test initialization.
-func unsetenvGPGAgentInfo() {
- v := C.CString("GPG_AGENT_INFO")
- defer C.free(unsafe.Pointer(v))
- C.unsetenv(v)
-}
diff --git a/vendor/github.com/mtrmac/gpgme/unset_agent_info.go b/vendor/github.com/mtrmac/gpgme/unset_agent_info.go
new file mode 100644
index 000000000..986aca59f
--- /dev/null
+++ b/vendor/github.com/mtrmac/gpgme/unset_agent_info.go
@@ -0,0 +1,18 @@
+// +build !windows
+
+package gpgme
+
+// #include <stdlib.h>
+import "C"
+import (
+ "unsafe"
+)
+
+// This is somewhat of a horrible hack. We need to unset GPG_AGENT_INFO so that gpgme does not pass --use-agent to GPG.
+// os.Unsetenv should be enough, but that only calls the underlying C library (which gpgme uses) if cgo is involved
+// - and cgo can't be used in tests. So, provide this helper for test initialization.
+func unsetenvGPGAgentInfo() {
+ v := C.CString("GPG_AGENT_INFO")
+ defer C.free(unsafe.Pointer(v))
+ C.unsetenv(v)
+}
diff --git a/vendor/github.com/mtrmac/gpgme/unset_agent_info_windows.go b/vendor/github.com/mtrmac/gpgme/unset_agent_info_windows.go
new file mode 100644
index 000000000..431ec86d3
--- /dev/null
+++ b/vendor/github.com/mtrmac/gpgme/unset_agent_info_windows.go
@@ -0,0 +1,14 @@
+package gpgme
+
+// #include <stdlib.h>
+import "C"
+import (
+ "unsafe"
+)
+
+// unsetenv is not available in mingw
+func unsetenvGPGAgentInfo() {
+ v := C.CString("GPG_AGENT_INFO=")
+ defer C.free(unsafe.Pointer(v))
+ C.putenv(v)
+}
diff --git a/vendor/github.com/onsi/ginkgo/.travis.yml b/vendor/github.com/onsi/ginkgo/.travis.yml
index b454d643c..65dc3002b 100644
--- a/vendor/github.com/onsi/ginkgo/.travis.yml
+++ b/vendor/github.com/onsi/ginkgo/.travis.yml
@@ -4,14 +4,22 @@ go:
- 1.13.x
- tip
+cache:
+ directories:
+ - $GOPATH/pkg/mod
+
# allow internal package imports, necessary for forked repositories
go_import_path: github.com/onsi/ginkgo
install:
- - go get -v -t ./...
- - go get golang.org/x/tools/cmd/cover
- - go get github.com/onsi/gomega
- - go install github.com/onsi/ginkgo/ginkgo
+ - GO111MODULE="off" go get -v -t ./...
+ - GO111MODULE="off" go get golang.org/x/tools/cmd/cover
+ - GO111MODULE="off" go get github.com/onsi/gomega
+ - GO111MODULE="off" go install github.com/onsi/ginkgo/ginkgo
- export PATH=$PATH:$HOME/gopath/bin
-script: $HOME/gopath/bin/ginkgo -r --randomizeAllSpecs --randomizeSuites --race --trace && go vet
+script:
+ - GO111MODULE="on" go mod tidy
+ - diff -u <(echo -n) <(git diff go.mod)
+ - diff -u <(echo -n) <(git diff go.sum)
+ - $HOME/gopath/bin/ginkgo -r --randomizeAllSpecs --randomizeSuites --race --trace && go vet
diff --git a/vendor/github.com/onsi/ginkgo/CHANGELOG.md b/vendor/github.com/onsi/ginkgo/CHANGELOG.md
index 96f03ad7c..84b479404 100644
--- a/vendor/github.com/onsi/ginkgo/CHANGELOG.md
+++ b/vendor/github.com/onsi/ginkgo/CHANGELOG.md
@@ -1,3 +1,8 @@
+## 1.12.0
+
+### Features
+- Add module definition (#630) [78916ab]
+
## 1.11.0
### Features
diff --git a/vendor/github.com/onsi/ginkgo/config/config.go b/vendor/github.com/onsi/ginkgo/config/config.go
index 14c82ec3a..949f8130f 100644
--- a/vendor/github.com/onsi/ginkgo/config/config.go
+++ b/vendor/github.com/onsi/ginkgo/config/config.go
@@ -20,7 +20,7 @@ import (
"fmt"
)
-const VERSION = "1.11.0"
+const VERSION = "1.12.0"
type GinkgoConfigType struct {
RandomSeed int64
diff --git a/vendor/github.com/onsi/ginkgo/go.mod b/vendor/github.com/onsi/ginkgo/go.mod
new file mode 100644
index 000000000..15a4ab571
--- /dev/null
+++ b/vendor/github.com/onsi/ginkgo/go.mod
@@ -0,0 +1,9 @@
+module github.com/onsi/ginkgo
+
+require (
+ github.com/hpcloud/tail v1.0.0
+ github.com/onsi/gomega v1.7.1
+ golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e
+)
+
+go 1.12
diff --git a/vendor/github.com/onsi/ginkgo/go.sum b/vendor/github.com/onsi/ginkgo/go.sum
new file mode 100644
index 000000000..29adce41a
--- /dev/null
+++ b/vendor/github.com/onsi/ginkgo/go.sum
@@ -0,0 +1,26 @@
+github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
+github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
+github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
+github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
+github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
+github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
+github.com/onsi/gomega v1.7.1 h1:K0jcRCwNQM3vFGh1ppMtDh/+7ApJrjldlX8fA0jDTLQ=
+github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
+golang.org/x/net v0.0.0-20180906233101-161cd47e91fd h1:nTDtHvHSdCn1m6ITfMRqtOd/9+7a3s8RBNOZ3eYZzJA=
+golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA=
+golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e h1:N7DeIrjYszNmSW409R3frPPwglRwMkXSBzwVbkOjLLA=
+golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
+gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
+gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
+gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
+gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I=
+gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
diff --git a/vendor/github.com/onsi/gomega/CHANGELOG.md b/vendor/github.com/onsi/gomega/CHANGELOG.md
index 59ad384aa..3e9b5961b 100644
--- a/vendor/github.com/onsi/gomega/CHANGELOG.md
+++ b/vendor/github.com/onsi/gomega/CHANGELOG.md
@@ -1,3 +1,10 @@
+## 1.9.0
+
+### Features
+- Add ContainElements matcher (#370) [2f57380]
+- Output missing and extra elements in ConsistOf failure message [a31eda7]
+- Document method LargestMatching [7c5a280]
+
## 1.8.1
### Fixes
diff --git a/vendor/github.com/onsi/gomega/gomega_dsl.go b/vendor/github.com/onsi/gomega/gomega_dsl.go
index 4cb94d22f..0ab35bc7a 100644
--- a/vendor/github.com/onsi/gomega/gomega_dsl.go
+++ b/vendor/github.com/onsi/gomega/gomega_dsl.go
@@ -24,7 +24,7 @@ import (
"github.com/onsi/gomega/types"
)
-const GOMEGA_VERSION = "1.8.1"
+const GOMEGA_VERSION = "1.9.0"
const nilFailHandlerPanic = `You are trying to make an assertion, but Gomega's fail handler is nil.
If you're using Ginkgo then you probably forgot to put your assertion in an It().
diff --git a/vendor/github.com/onsi/gomega/matchers.go b/vendor/github.com/onsi/gomega/matchers.go
index 9ec8893cb..11f5b1070 100644
--- a/vendor/github.com/onsi/gomega/matchers.go
+++ b/vendor/github.com/onsi/gomega/matchers.go
@@ -306,6 +306,20 @@ func ConsistOf(elements ...interface{}) types.GomegaMatcher {
}
}
+//ContainElements succeeds if actual contains the passed in elements. The ordering of the elements does not matter.
+//By default ContainElements() uses Equal() to match the elements, however custom matchers can be passed in instead. Here are some examples:
+//
+// Expect([]string{"Foo", "FooBar"}).Should(ContainElements("FooBar"))
+// Expect([]string{"Foo", "FooBar"}).Should(ContainElements(ContainSubstring("Bar"), "Foo"))
+//
+//Actual must be an array, slice or map.
+//For maps, ContainElements searches through the map's values.
+func ContainElements(elements ...interface{}) types.GomegaMatcher {
+ return &matchers.ContainElementsMatcher{
+ Elements: elements,
+ }
+}
+
//HaveKey succeeds if actual is a map with the passed in key.
//By default HaveKey uses Equal() to perform the match, however a
//matcher can be passed in instead:
diff --git a/vendor/github.com/onsi/gomega/matchers/consist_of.go b/vendor/github.com/onsi/gomega/matchers/consist_of.go
index cbbf61802..e453b22d1 100644
--- a/vendor/github.com/onsi/gomega/matchers/consist_of.go
+++ b/vendor/github.com/onsi/gomega/matchers/consist_of.go
@@ -11,7 +11,9 @@ import (
)
type ConsistOfMatcher struct {
- Elements []interface{}
+ Elements []interface{}
+ missingElements []interface{}
+ extraElements []interface{}
}
func (matcher *ConsistOfMatcher) Match(actual interface{}) (success bool, err error) {
@@ -19,44 +21,63 @@ func (matcher *ConsistOfMatcher) Match(actual interface{}) (success bool, err er
return false, fmt.Errorf("ConsistOf matcher expects an array/slice/map. Got:\n%s", format.Object(actual, 1))
}
- elements := matcher.Elements
- if len(matcher.Elements) == 1 && isArrayOrSlice(matcher.Elements[0]) {
- elements = []interface{}{}
- value := reflect.ValueOf(matcher.Elements[0])
- for i := 0; i < value.Len(); i++ {
- elements = append(elements, value.Index(i).Interface())
- }
+ matchers := matchers(matcher.Elements)
+ values := valuesOf(actual)
+
+ bipartiteGraph, err := bipartitegraph.NewBipartiteGraph(values, matchers, neighbours)
+ if err != nil {
+ return false, err
}
- matchers := []interface{}{}
- for _, element := range elements {
- matcher, isMatcher := element.(omegaMatcher)
- if !isMatcher {
- matcher = &EqualMatcher{Expected: element}
- }
- matchers = append(matchers, matcher)
+ edges := bipartiteGraph.LargestMatching()
+ if len(edges) == len(values) && len(edges) == len(matchers) {
+ return true, nil
}
- values := matcher.valuesOf(actual)
+ var missingMatchers []interface{}
+ matcher.extraElements, missingMatchers = bipartiteGraph.FreeLeftRight(edges)
+ matcher.missingElements = equalMatchersToElements(missingMatchers)
- if len(values) != len(matchers) {
- return false, nil
- }
+ return false, nil
+}
- neighbours := func(v, m interface{}) (bool, error) {
- match, err := m.(omegaMatcher).Match(v)
- return match && err == nil, nil
+func neighbours(value, matcher interface{}) (bool, error) {
+ match, err := matcher.(omegaMatcher).Match(value)
+ return match && err == nil, nil
+}
+
+func equalMatchersToElements(matchers []interface{}) (elements []interface{}) {
+ for _, matcher := range matchers {
+ equalMatcher, ok := matcher.(*EqualMatcher)
+ if ok {
+ matcher = equalMatcher.Expected
+ }
+ elements = append(elements, matcher)
}
+ return
+}
- bipartiteGraph, err := bipartitegraph.NewBipartiteGraph(values, matchers, neighbours)
- if err != nil {
- return false, err
+func matchers(expectedElems []interface{}) (matchers []interface{}) {
+ elems := expectedElems
+ if len(expectedElems) == 1 && isArrayOrSlice(expectedElems[0]) {
+ elems = []interface{}{}
+ value := reflect.ValueOf(expectedElems[0])
+ for i := 0; i < value.Len(); i++ {
+ elems = append(elems, value.Index(i).Interface())
+ }
}
- return len(bipartiteGraph.LargestMatching()) == len(values), nil
+ for _, e := range elems {
+ matcher, isMatcher := e.(omegaMatcher)
+ if !isMatcher {
+ matcher = &EqualMatcher{Expected: e}
+ }
+ matchers = append(matchers, matcher)
+ }
+ return
}
-func (matcher *ConsistOfMatcher) valuesOf(actual interface{}) []interface{} {
+func valuesOf(actual interface{}) []interface{} {
value := reflect.ValueOf(actual)
values := []interface{}{}
if isMap(actual) {
@@ -74,7 +95,21 @@ func (matcher *ConsistOfMatcher) valuesOf(actual interface{}) []interface{} {
}
func (matcher *ConsistOfMatcher) FailureMessage(actual interface{}) (message string) {
- return format.Message(actual, "to consist of", matcher.Elements)
+ message = format.Message(actual, "to consist of", matcher.Elements)
+ message = appendMissingElements(message, matcher.missingElements)
+ if len(matcher.extraElements) > 0 {
+ message = fmt.Sprintf("%s\nthe extra elements were\n%s", message,
+ format.Object(matcher.extraElements, 1))
+ }
+ return
+}
+
+func appendMissingElements(message string, missingElements []interface{}) string {
+ if len(missingElements) == 0 {
+ return message
+ }
+ return fmt.Sprintf("%s\nthe missing elements were\n%s", message,
+ format.Object(missingElements, 1))
}
func (matcher *ConsistOfMatcher) NegatedFailureMessage(actual interface{}) (message string) {
diff --git a/vendor/github.com/onsi/gomega/matchers/contain_elements_matcher.go b/vendor/github.com/onsi/gomega/matchers/contain_elements_matcher.go
new file mode 100644
index 000000000..19a9e78f8
--- /dev/null
+++ b/vendor/github.com/onsi/gomega/matchers/contain_elements_matcher.go
@@ -0,0 +1,44 @@
+package matchers
+
+import (
+ "fmt"
+
+ "github.com/onsi/gomega/format"
+ "github.com/onsi/gomega/matchers/support/goraph/bipartitegraph"
+)
+
+type ContainElementsMatcher struct {
+ Elements []interface{}
+ missingElements []interface{}
+}
+
+func (matcher *ContainElementsMatcher) Match(actual interface{}) (success bool, err error) {
+ if !isArrayOrSlice(actual) && !isMap(actual) {
+ return false, fmt.Errorf("ContainElements matcher expects an array/slice/map. Got:\n%s", format.Object(actual, 1))
+ }
+
+ matchers := matchers(matcher.Elements)
+ bipartiteGraph, err := bipartitegraph.NewBipartiteGraph(valuesOf(actual), matchers, neighbours)
+ if err != nil {
+ return false, err
+ }
+
+ edges := bipartiteGraph.LargestMatching()
+ if len(edges) == len(matchers) {
+ return true, nil
+ }
+
+ _, missingMatchers := bipartiteGraph.FreeLeftRight(edges)
+ matcher.missingElements = equalMatchersToElements(missingMatchers)
+
+ return false, nil
+}
+
+func (matcher *ContainElementsMatcher) FailureMessage(actual interface{}) (message string) {
+ message = format.Message(actual, "to contain elements", matcher.Elements)
+ return appendMissingElements(message, matcher.missingElements)
+}
+
+func (matcher *ContainElementsMatcher) NegatedFailureMessage(actual interface{}) (message string) {
+ return format.Message(actual, "not to contain elements", matcher.Elements)
+}
diff --git a/vendor/github.com/onsi/gomega/matchers/support/goraph/bipartitegraph/bipartitegraph.go b/vendor/github.com/onsi/gomega/matchers/support/goraph/bipartitegraph/bipartitegraph.go
index 108f28586..830e30827 100644
--- a/vendor/github.com/onsi/gomega/matchers/support/goraph/bipartitegraph/bipartitegraph.go
+++ b/vendor/github.com/onsi/gomega/matchers/support/goraph/bipartitegraph/bipartitegraph.go
@@ -13,13 +13,13 @@ type BipartiteGraph struct {
func NewBipartiteGraph(leftValues, rightValues []interface{}, neighbours func(interface{}, interface{}) (bool, error)) (*BipartiteGraph, error) {
left := NodeOrderedSet{}
- for i := range leftValues {
- left = append(left, Node{Id: i})
+ for i, v := range leftValues {
+ left = append(left, Node{ID: i, Value: v})
}
right := NodeOrderedSet{}
- for j := range rightValues {
- right = append(right, Node{Id: j + len(left)})
+ for j, v := range rightValues {
+ right = append(right, Node{ID: j + len(left), Value: v})
}
edges := EdgeSet{}
@@ -31,10 +31,26 @@ func NewBipartiteGraph(leftValues, rightValues []interface{}, neighbours func(in
}
if neighbours {
- edges = append(edges, Edge{Node1: left[i], Node2: right[j]})
+ edges = append(edges, Edge{Node1: left[i].ID, Node2: right[j].ID})
}
}
}
return &BipartiteGraph{left, right, edges}, nil
}
+
+// FreeLeftRight returns left node values and right node values
+// of the BipartiteGraph's nodes which are not part of the given edges.
+func (bg *BipartiteGraph) FreeLeftRight(edges EdgeSet) (leftValues, rightValues []interface{}) {
+ for _, node := range bg.Left {
+ if edges.Free(node) {
+ leftValues = append(leftValues, node.Value)
+ }
+ }
+ for _, node := range bg.Right {
+ if edges.Free(node) {
+ rightValues = append(rightValues, node.Value)
+ }
+ }
+ return
+}
diff --git a/vendor/github.com/onsi/gomega/matchers/support/goraph/bipartitegraph/bipartitegraphmatching.go b/vendor/github.com/onsi/gomega/matchers/support/goraph/bipartitegraph/bipartitegraphmatching.go
index 8181f43a4..1c54edd8f 100644
--- a/vendor/github.com/onsi/gomega/matchers/support/goraph/bipartitegraph/bipartitegraphmatching.go
+++ b/vendor/github.com/onsi/gomega/matchers/support/goraph/bipartitegraph/bipartitegraphmatching.go
@@ -1,9 +1,14 @@
package bipartitegraph
-import . "github.com/onsi/gomega/matchers/support/goraph/node"
-import . "github.com/onsi/gomega/matchers/support/goraph/edge"
-import "github.com/onsi/gomega/matchers/support/goraph/util"
-
+import (
+ . "github.com/onsi/gomega/matchers/support/goraph/edge"
+ . "github.com/onsi/gomega/matchers/support/goraph/node"
+ "github.com/onsi/gomega/matchers/support/goraph/util"
+)
+
+// LargestMatching implements the Hopcroft–Karp algorithm taking as input a bipartite graph
+// and outputting a maximum cardinality matching, i.e. a set of as many edges as possible
+// with the property that no two edges share an endpoint.
func (bg *BipartiteGraph) LargestMatching() (matching EdgeSet) {
paths := bg.maximalDisjointSLAPCollection(matching)
@@ -23,7 +28,7 @@ func (bg *BipartiteGraph) maximalDisjointSLAPCollection(matching EdgeSet) (resul
return
}
- used := make(map[Node]bool)
+ used := make(map[int]bool)
for _, u := range guideLayers[len(guideLayers)-1] {
slap, found := bg.findDisjointSLAP(u, matching, guideLayers, used)
@@ -43,7 +48,7 @@ func (bg *BipartiteGraph) findDisjointSLAP(
start Node,
matching EdgeSet,
guideLayers []NodeOrderedSet,
- used map[Node]bool,
+ used map[int]bool,
) ([]Edge, bool) {
return bg.findDisjointSLAPHelper(start, EdgeSet{}, len(guideLayers)-1, matching, guideLayers, used)
}
@@ -54,16 +59,16 @@ func (bg *BipartiteGraph) findDisjointSLAPHelper(
currentLevel int,
matching EdgeSet,
guideLayers []NodeOrderedSet,
- used map[Node]bool,
+ used map[int]bool,
) (EdgeSet, bool) {
- used[currentNode] = true
+ used[currentNode.ID] = true
if currentLevel == 0 {
return currentSLAP, true
}
for _, nextNode := range guideLayers[currentLevel-1] {
- if used[nextNode] {
+ if used[nextNode.ID] {
continue
}
@@ -84,17 +89,17 @@ func (bg *BipartiteGraph) findDisjointSLAPHelper(
currentSLAP = currentSLAP[:len(currentSLAP)-1]
}
- used[currentNode] = false
+ used[currentNode.ID] = false
return nil, false
}
func (bg *BipartiteGraph) createSLAPGuideLayers(matching EdgeSet) (guideLayers []NodeOrderedSet) {
- used := make(map[Node]bool)
+ used := make(map[int]bool)
currentLayer := NodeOrderedSet{}
for _, node := range bg.Left {
if matching.Free(node) {
- used[node] = true
+ used[node.ID] = true
currentLayer = append(currentLayer, node)
}
}
@@ -113,7 +118,7 @@ func (bg *BipartiteGraph) createSLAPGuideLayers(matching EdgeSet) (guideLayers [
if util.Odd(len(guideLayers)) {
for _, leftNode := range lastLayer {
for _, rightNode := range bg.Right {
- if used[rightNode] {
+ if used[rightNode.ID] {
continue
}
@@ -123,7 +128,7 @@ func (bg *BipartiteGraph) createSLAPGuideLayers(matching EdgeSet) (guideLayers [
}
currentLayer = append(currentLayer, rightNode)
- used[rightNode] = true
+ used[rightNode.ID] = true
if matching.Free(rightNode) {
done = true
@@ -133,7 +138,7 @@ func (bg *BipartiteGraph) createSLAPGuideLayers(matching EdgeSet) (guideLayers [
} else {
for _, rightNode := range lastLayer {
for _, leftNode := range bg.Left {
- if used[leftNode] {
+ if used[leftNode.ID] {
continue
}
@@ -143,7 +148,7 @@ func (bg *BipartiteGraph) createSLAPGuideLayers(matching EdgeSet) (guideLayers [
}
currentLayer = append(currentLayer, leftNode)
- used[leftNode] = true
+ used[leftNode.ID] = true
}
}
diff --git a/vendor/github.com/onsi/gomega/matchers/support/goraph/edge/edge.go b/vendor/github.com/onsi/gomega/matchers/support/goraph/edge/edge.go
index 4fd15cc06..8c38411b2 100644
--- a/vendor/github.com/onsi/gomega/matchers/support/goraph/edge/edge.go
+++ b/vendor/github.com/onsi/gomega/matchers/support/goraph/edge/edge.go
@@ -3,15 +3,15 @@ package edge
import . "github.com/onsi/gomega/matchers/support/goraph/node"
type Edge struct {
- Node1 Node
- Node2 Node
+ Node1 int
+ Node2 int
}
type EdgeSet []Edge
func (ec EdgeSet) Free(node Node) bool {
for _, e := range ec {
- if e.Node1 == node || e.Node2 == node {
+ if e.Node1 == node.ID || e.Node2 == node.ID {
return false
}
}
@@ -31,7 +31,7 @@ func (ec EdgeSet) Contains(edge Edge) bool {
func (ec EdgeSet) FindByNodes(node1, node2 Node) (Edge, bool) {
for _, e := range ec {
- if (e.Node1 == node1 && e.Node2 == node2) || (e.Node1 == node2 && e.Node2 == node1) {
+ if (e.Node1 == node1.ID && e.Node2 == node2.ID) || (e.Node1 == node2.ID && e.Node2 == node1.ID) {
return e, true
}
}
diff --git a/vendor/github.com/onsi/gomega/matchers/support/goraph/node/node.go b/vendor/github.com/onsi/gomega/matchers/support/goraph/node/node.go
index 800c2ea8c..cd597a2f2 100644
--- a/vendor/github.com/onsi/gomega/matchers/support/goraph/node/node.go
+++ b/vendor/github.com/onsi/gomega/matchers/support/goraph/node/node.go
@@ -1,7 +1,8 @@
package node
type Node struct {
- Id int
+ ID int
+ Value interface{}
}
type NodeOrderedSet []Node
diff --git a/vendor/github.com/opencontainers/selinux/go-selinux/label/label.go b/vendor/github.com/opencontainers/selinux/go-selinux/label/label.go
index e178568fd..6e38d3d32 100644
--- a/vendor/github.com/opencontainers/selinux/go-selinux/label/label.go
+++ b/vendor/github.com/opencontainers/selinux/go-selinux/label/label.go
@@ -1,109 +1,77 @@
-// +build !selinux !linux
-
package label
-// InitLabels returns the process label and file labels to be used within
-// the container. A list of options can be passed into this function to alter
-// the labels.
-func InitLabels(options []string) (string, string, error) {
- return "", "", nil
-}
-
-func ROMountLabel() string {
- return ""
-}
-
-func GenLabels(options string) (string, string, error) {
- return "", "", nil
-}
+import (
+ "github.com/opencontainers/selinux/go-selinux"
+)
-func FormatMountLabel(src string, mountLabel string) string {
- return src
-}
+// Deprecated: use selinux.ROFileLabel
+var ROMountLabel = selinux.ROFileLabel
-func SetProcessLabel(processLabel string) error {
- return nil
-}
+// SetProcessLabel takes a process label and tells the kernel to assign the
+// label to the next program executed by the current process.
+// Deprecated: use selinux.SetExecLabel
+var SetProcessLabel = selinux.SetExecLabel
-func ProcessLabel() (string, error) {
- return "", nil
-}
+// ProcessLabel returns the process label that the kernel will assign
+// to the next program executed by the current process. If "" is returned
+// this indicates that the default labeling will happen for the process.
+// Deprecated: use selinux.ExecLabel
+var ProcessLabel = selinux.ExecLabel
-func SetSocketLabel(processLabel string) error {
- return nil
-}
+// SetSocketLabel takes a process label and tells the kernel to assign the
+// label to the next socket that gets created
+// Deprecated: use selinux.SetSocketLabel
+var SetSocketLabel = selinux.SetSocketLabel
-func SocketLabel() (string, error) {
- return "", nil
-}
+// SocketLabel retrieves the current default socket label setting
+// Deprecated: use selinux.SocketLabel
+var SocketLabel = selinux.SocketLabel
-func SetKeyLabel(processLabel string) error {
- return nil
-}
+// SetKeyLabel takes a process label and tells the kernel to assign the
+// label to the next kernel keyring that gets created
+// Deprecated: use selinux.SetKeyLabel
+var SetKeyLabel = selinux.SetKeyLabel
-func KeyLabel() (string, error) {
- return "", nil
-}
+// KeyLabel retrieves the current default kernel keyring label setting
+// Deprecated: use selinux.KeyLabel
+var KeyLabel = selinux.KeyLabel
-func FileLabel(path string) (string, error) {
- return "", nil
-}
+// FileLabel returns the label for specified path
+// Deprecated: use selinux.FileLabel
+var FileLabel = selinux.FileLabel
-func SetFileLabel(path string, fileLabel string) error {
- return nil
-}
-
-func SetFileCreateLabel(fileLabel string) error {
- return nil
-}
-
-func Relabel(path string, fileLabel string, shared bool) error {
- return nil
-}
-
-func PidLabel(pid int) (string, error) {
- return "", nil
-}
+// PidLabel will return the label of the process running with the specified pid
+// Deprecated: use selinux.PidLabel
+var PidLabel = selinux.PidLabel
+// Init initialises the labeling system
func Init() {
+ selinux.GetEnabled()
}
-// ClearLabels clears all reserved labels
-func ClearLabels() {
- return
-}
+// ClearLabels will clear all reserved labels
+// Deprecated: use selinux.ClearLabels
+var ClearLabels = selinux.ClearLabels
+// ReserveLabel will record the fact that the MCS label has already been used.
+// This will prevent InitLabels from using the MCS label in a newly created
+// container
+// Deprecated: use selinux.ReserveLabel
func ReserveLabel(label string) error {
+ selinux.ReserveLabel(label)
return nil
}
+// ReleaseLabel will remove the reservation of the MCS label.
+// This will allow InitLabels to use the MCS label in a newly created
+// containers
+// Deprecated: use selinux.ReleaseLabel
func ReleaseLabel(label string) error {
+ selinux.ReleaseLabel(label)
return nil
}
// DupSecOpt takes a process label and returns security options that
// can be used to set duplicate labels on future container processes
-func DupSecOpt(src string) ([]string, error) {
- return nil, nil
-}
-
-// DisableSecOpt returns a security opt that can disable labeling
-// support for future container processes
-func DisableSecOpt() []string {
- return nil
-}
-
-// Validate checks that the label does not include unexpected options
-func Validate(label string) error {
- return nil
-}
-
-// RelabelNeeded checks whether the user requested a relabel
-func RelabelNeeded(label string) bool {
- return false
-}
-
-// IsShared checks that the label includes a "shared" mark
-func IsShared(label string) bool {
- return false
-}
+// Deprecated: use selinux.DupSecOpt
+var DupSecOpt = selinux.DupSecOpt
diff --git a/vendor/github.com/opencontainers/selinux/go-selinux/label/label_selinux.go b/vendor/github.com/opencontainers/selinux/go-selinux/label/label_selinux.go
index 2730fcf4a..903829958 100644
--- a/vendor/github.com/opencontainers/selinux/go-selinux/label/label_selinux.go
+++ b/vendor/github.com/opencontainers/selinux/go-selinux/label/label_selinux.go
@@ -9,6 +9,7 @@ import (
"strings"
"github.com/opencontainers/selinux/go-selinux"
+ "github.com/pkg/errors"
)
// Valid Label Options
@@ -21,7 +22,7 @@ var validOptions = map[string]bool{
"level": true,
}
-var ErrIncompatibleLabel = fmt.Errorf("Bad SELinux option z and Z can not be used together")
+var ErrIncompatibleLabel = errors.New("Bad SELinux option z and Z can not be used together")
// InitLabels returns the process label and file labels to be used within
// the container. A list of options can be passed into this function to alter
@@ -35,7 +36,7 @@ func InitLabels(options []string) (plabel string, mlabel string, Err error) {
if processLabel != "" {
defer func() {
if Err != nil {
- ReleaseLabel(mountLabel)
+ selinux.ReleaseLabel(mountLabel)
}
}()
pcon, err := selinux.NewContext(processLabel)
@@ -52,11 +53,11 @@ func InitLabels(options []string) (plabel string, mlabel string, Err error) {
return "", mountLabel, nil
}
if i := strings.Index(opt, ":"); i == -1 {
- return "", "", fmt.Errorf("Bad label option %q, valid options 'disable' or \n'user, role, level, type, filetype' followed by ':' and a value", opt)
+ return "", "", errors.Errorf("Bad label option %q, valid options 'disable' or \n'user, role, level, type, filetype' followed by ':' and a value", opt)
}
con := strings.SplitN(opt, ":", 2)
if !validOptions[con[0]] {
- return "", "", fmt.Errorf("Bad label option %q, valid options 'disable, user, role, level, type, filetype'", con[0])
+ return "", "", errors.Errorf("Bad label option %q, valid options 'disable, user, role, level, type, filetype'", con[0])
}
if con[0] == "filetype" {
@@ -67,19 +68,16 @@ func InitLabels(options []string) (plabel string, mlabel string, Err error) {
mcon[con[0]] = con[1]
}
}
- _ = ReleaseLabel(processLabel)
+ selinux.ReleaseLabel(processLabel)
processLabel = pcon.Get()
mountLabel = mcon.Get()
- _ = ReserveLabel(processLabel)
+ selinux.ReserveLabel(processLabel)
}
return processLabel, mountLabel, nil
}
-func ROMountLabel() string {
- return selinux.ROFileLabel()
-}
-
-// DEPRECATED: The GenLabels function is only to be used during the transition to the official API.
+// Deprecated: The GenLabels function is only to be used during the transition
+// to the official API. Use InitLabels(strings.Fields(options)) instead.
func GenLabels(options string) (string, string, error) {
return InitLabels(strings.Fields(options))
}
@@ -102,71 +100,27 @@ func FormatMountLabel(src, mountLabel string) string {
return src
}
-// SetProcessLabel takes a process label and tells the kernel to assign the
-// label to the next program executed by the current process.
-func SetProcessLabel(processLabel string) error {
- return selinux.SetExecLabel(processLabel)
-}
-
-// SetSocketLabel takes a process label and tells the kernel to assign the
-// label to the next socket that gets created
-func SetSocketLabel(processLabel string) error {
- return selinux.SetSocketLabel(processLabel)
-}
-
-// SocketLabel retrieves the current default socket label setting
-func SocketLabel() (string, error) {
- return selinux.SocketLabel()
-}
-
-// SetKeyLabel takes a process label and tells the kernel to assign the
-// label to the next kernel keyring that gets created
-func SetKeyLabel(processLabel string) error {
- return selinux.SetKeyLabel(processLabel)
-}
-
-// KeyLabel retrieves the current default kernel keyring label setting
-func KeyLabel() (string, error) {
- return selinux.KeyLabel()
-}
-
-// ProcessLabel returns the process label that the kernel will assign
-// to the next program executed by the current process. If "" is returned
-// this indicates that the default labeling will happen for the process.
-func ProcessLabel() (string, error) {
- return selinux.ExecLabel()
-}
-
-// FileLabel returns the label for specified path
-func FileLabel(path string) (string, error) {
- return selinux.FileLabel(path)
-}
-
// SetFileLabel modifies the "path" label to the specified file label
func SetFileLabel(path string, fileLabel string) error {
- if selinux.GetEnabled() && fileLabel != "" {
- return selinux.SetFileLabel(path, fileLabel)
+ if !selinux.GetEnabled() || fileLabel == "" {
+ return nil
}
- return nil
+ return selinux.SetFileLabel(path, fileLabel)
}
// SetFileCreateLabel tells the kernel the label for all files to be created
func SetFileCreateLabel(fileLabel string) error {
- if selinux.GetEnabled() {
- return selinux.SetFSCreateLabel(fileLabel)
+ if !selinux.GetEnabled() {
+ return nil
}
- return nil
+ return selinux.SetFSCreateLabel(fileLabel)
}
// Relabel changes the label of path to the filelabel string.
// It changes the MCS label to s0 if shared is true.
// This will allow all containers to share the content.
func Relabel(path string, fileLabel string, shared bool) error {
- if !selinux.GetEnabled() {
- return nil
- }
-
- if fileLabel == "" {
+ if !selinux.GetEnabled() || fileLabel == "" {
return nil
}
@@ -211,7 +165,7 @@ func Relabel(path string, fileLabel string, shared bool) error {
path = strings.TrimSuffix(path, "/")
}
if exclude_paths[path] {
- return fmt.Errorf("SELinux relabeling of %s is not allowed", path)
+ return errors.Errorf("SELinux relabeling of %s is not allowed", path)
}
if shared {
@@ -229,48 +183,10 @@ func Relabel(path string, fileLabel string, shared bool) error {
return nil
}
-// PidLabel will return the label of the process running with the specified pid
-func PidLabel(pid int) (string, error) {
- return selinux.PidLabel(pid)
-}
-
-// Init initialises the labeling system
-func Init() {
- selinux.GetEnabled()
-}
-
-// ClearLabels will clear all reserved labels
-func ClearLabels() {
- selinux.ClearLabels()
-}
-
-// ReserveLabel will record the fact that the MCS label has already been used.
-// This will prevent InitLabels from using the MCS label in a newly created
-// container
-func ReserveLabel(label string) error {
- selinux.ReserveLabel(label)
- return nil
-}
-
-// ReleaseLabel will remove the reservation of the MCS label.
-// This will allow InitLabels to use the MCS label in a newly created
-// containers
-func ReleaseLabel(label string) error {
- selinux.ReleaseLabel(label)
- return nil
-}
-
-// DupSecOpt takes a process label and returns security options that
-// can be used to set duplicate labels on future container processes
-func DupSecOpt(src string) ([]string, error) {
- return selinux.DupSecOpt(src)
-}
-
// DisableSecOpt returns a security opt that can disable labeling
// support for future container processes
-func DisableSecOpt() []string {
- return selinux.DisableSecOpt()
-}
+// Deprecated: use selinux.DisableSecOpt
+var DisableSecOpt = selinux.DisableSecOpt
// Validate checks that the label does not include unexpected options
func Validate(label string) error {
diff --git a/vendor/github.com/opencontainers/selinux/go-selinux/label/label_stub.go b/vendor/github.com/opencontainers/selinux/go-selinux/label/label_stub.go
new file mode 100644
index 000000000..cda59d671
--- /dev/null
+++ b/vendor/github.com/opencontainers/selinux/go-selinux/label/label_stub.go
@@ -0,0 +1,54 @@
+// +build !selinux !linux
+
+package label
+
+// InitLabels returns the process label and file labels to be used within
+// the container. A list of options can be passed into this function to alter
+// the labels.
+func InitLabels(options []string) (string, string, error) {
+ return "", "", nil
+}
+
+// Deprecated: The GenLabels function is only to be used during the transition
+// to the official API. Use InitLabels(strings.Fields(options)) instead.
+func GenLabels(options string) (string, string, error) {
+ return "", "", nil
+}
+
+func FormatMountLabel(src string, mountLabel string) string {
+ return src
+}
+
+func SetFileLabel(path string, fileLabel string) error {
+ return nil
+}
+
+func SetFileCreateLabel(fileLabel string) error {
+ return nil
+}
+
+func Relabel(path string, fileLabel string, shared bool) error {
+ return nil
+}
+
+// DisableSecOpt returns a security opt that can disable labeling
+// support for future container processes
+func DisableSecOpt() []string {
+ // TODO the selinux.DisableSecOpt stub returns []string{"disable"} instead of "nil"
+ return nil
+}
+
+// Validate checks that the label does not include unexpected options
+func Validate(label string) error {
+ return nil
+}
+
+// RelabelNeeded checks whether the user requested a relabel
+func RelabelNeeded(label string) bool {
+ return false
+}
+
+// IsShared checks that the label includes a "shared" mark
+func IsShared(label string) bool {
+ return false
+}
diff --git a/vendor/github.com/opencontainers/selinux/go-selinux/selinux_linux.go b/vendor/github.com/opencontainers/selinux/go-selinux/selinux_linux.go
index 2d4e9f890..599bdb6e2 100644
--- a/vendor/github.com/opencontainers/selinux/go-selinux/selinux_linux.go
+++ b/vendor/github.com/opencontainers/selinux/go-selinux/selinux_linux.go
@@ -7,17 +7,19 @@ import (
"bytes"
"crypto/rand"
"encoding/binary"
- "errors"
"fmt"
"io"
"io/ioutil"
"os"
+ "path"
"path/filepath"
"regexp"
"strconv"
"strings"
"sync"
- "syscall"
+
+ "github.com/opencontainers/selinux/pkg/pwalk"
+ "github.com/pkg/errors"
"golang.org/x/sys/unix"
)
@@ -35,16 +37,14 @@ const (
selinuxTypeTag = "SELINUXTYPE"
selinuxTag = "SELINUX"
xattrNameSelinux = "security.selinux"
- stRdOnly = 0x01
- selinuxfsMagic = 0xf97cff8c
)
type selinuxState struct {
- enabledSet bool
- enabled bool
- selinuxfsSet bool
- selinuxfs string
- mcsList map[string]bool
+ enabledSet bool
+ enabled bool
+ selinuxfsOnce sync.Once
+ selinuxfs string
+ mcsList map[string]bool
sync.Mutex
}
@@ -61,6 +61,10 @@ var (
state = selinuxState{
mcsList: make(map[string]bool),
}
+
+ // for attrPath()
+ attrPathOnce sync.Once
+ haveThreadSelf bool
)
// Context is a representation of the SELinux label broken into 4 parts
@@ -97,30 +101,23 @@ func SetDisabled() {
state.setEnable(false)
}
-func (s *selinuxState) setSELinuxfs(selinuxfs string) string {
- s.Lock()
- defer s.Unlock()
- s.selinuxfsSet = true
- s.selinuxfs = selinuxfs
- return s.selinuxfs
-}
-
func verifySELinuxfsMount(mnt string) bool {
- var buf syscall.Statfs_t
+ var buf unix.Statfs_t
for {
- err := syscall.Statfs(mnt, &buf)
+ err := unix.Statfs(mnt, &buf)
if err == nil {
break
}
- if err == syscall.EAGAIN {
+ if err == unix.EAGAIN {
continue
}
return false
}
- if uint32(buf.Type) != uint32(selinuxfsMagic) {
+
+ if uint32(buf.Type) != uint32(unix.SELINUX_MAGIC) {
return false
}
- if (buf.Flags & stRdOnly) != 0 {
+ if (buf.Flags & unix.ST_RDONLY) != 0 {
return false
}
@@ -165,33 +162,29 @@ func findSELinuxfs() string {
// if there is one, or an empty string in case of EOF or error.
func findSELinuxfsMount(s *bufio.Scanner) string {
for s.Scan() {
- txt := s.Text()
+ txt := s.Bytes()
// The first field after - is fs type.
// Safe as spaces in mountpoints are encoded as \040
- if !strings.Contains(txt, " - selinuxfs ") {
+ if !bytes.Contains(txt, []byte(" - selinuxfs ")) {
continue
}
const mPos = 5 // mount point is 5th field
- fields := strings.SplitN(txt, " ", mPos+1)
+ fields := bytes.SplitN(txt, []byte(" "), mPos+1)
if len(fields) < mPos+1 {
continue
}
- return fields[mPos-1]
+ return string(fields[mPos-1])
}
return ""
}
func (s *selinuxState) getSELinuxfs() string {
- s.Lock()
- selinuxfs := s.selinuxfs
- selinuxfsSet := s.selinuxfsSet
- s.Unlock()
- if selinuxfsSet {
- return selinuxfs
- }
+ s.selinuxfsOnce.Do(func() {
+ s.selinuxfs = findSELinuxfs()
+ })
- return s.setSELinuxfs(findSELinuxfs())
+ return s.selinuxfs
}
// getSelinuxMountPoint returns the path to the mountpoint of an selinuxfs
@@ -253,6 +246,19 @@ func getSELinuxPolicyRoot() string {
return filepath.Join(selinuxDir, readConfig(selinuxTypeTag))
}
+func isProcHandle(fh *os.File) error {
+ var buf unix.Statfs_t
+ err := unix.Fstatfs(int(fh.Fd()), &buf)
+ if err != nil {
+ return errors.Wrapf(err, "statfs(%q) failed", fh.Name())
+ }
+ if buf.Type != unix.PROC_SUPER_MAGIC {
+ return errors.Errorf("file %q is not on procfs", fh.Name())
+ }
+
+ return nil
+}
+
func readCon(fpath string) (string, error) {
if fpath == "" {
return "", ErrEmptyPath
@@ -264,6 +270,10 @@ func readCon(fpath string) (string, error) {
}
defer in.Close()
+ if err := isProcHandle(in); err != nil {
+ return "", err
+ }
+
var retval string
if _, err := fmt.Fscanf(in, "%s", &retval); err != nil {
return "", err
@@ -271,12 +281,32 @@ func readCon(fpath string) (string, error) {
return strings.Trim(retval, "\x00"), nil
}
+// ClassIndex returns the int index for an object class in the loaded policy, or -1 and an error
+func ClassIndex(class string) (int, error) {
+ permpath := fmt.Sprintf("class/%s/index", class)
+ indexpath := filepath.Join(getSelinuxMountPoint(), permpath)
+
+ indexB, err := ioutil.ReadFile(indexpath)
+ if err != nil {
+ return -1, err
+ }
+ index, err := strconv.Atoi(string(indexB))
+ if err != nil {
+ return -1, err
+ }
+
+ return index, nil
+}
+
// SetFileLabel sets the SELinux label for this path or returns an error.
func SetFileLabel(fpath string, label string) error {
if fpath == "" {
return ErrEmptyPath
}
- return lsetxattr(fpath, xattrNameSelinux, []byte(label), 0)
+ if err := unix.Lsetxattr(fpath, xattrNameSelinux, []byte(label), 0); err != nil {
+ return errors.Wrapf(err, "failed to set file label on %s", fpath)
+ }
+ return nil
}
// FileLabel returns the SELinux label for this path or returns an error.
@@ -301,7 +331,7 @@ SetFSCreateLabel tells kernel the label to create all file system objects
created by this task. Setting label="" to return to default.
*/
func SetFSCreateLabel(label string) error {
- return writeCon(fmt.Sprintf("/proc/self/task/%d/attr/fscreate", syscall.Gettid()), label)
+ return writeAttr("fscreate", label)
}
/*
@@ -309,12 +339,12 @@ FSCreateLabel returns the default label the kernel which the kernel is using
for file system objects created by this task. "" indicates default.
*/
func FSCreateLabel() (string, error) {
- return readCon(fmt.Sprintf("/proc/self/task/%d/attr/fscreate", syscall.Gettid()))
+ return readAttr("fscreate")
}
// CurrentLabel returns the SELinux label of the current process thread, or an error.
func CurrentLabel() (string, error) {
- return readCon(fmt.Sprintf("/proc/self/task/%d/attr/current", syscall.Gettid()))
+ return readAttr("current")
}
// PidLabel returns the SELinux label of the given pid, or an error.
@@ -327,10 +357,10 @@ ExecLabel returns the SELinux label that the kernel will use for any programs
that are executed by the current process thread, or an error.
*/
func ExecLabel() (string, error) {
- return readCon(fmt.Sprintf("/proc/self/task/%d/attr/exec", syscall.Gettid()))
+ return readAttr("exec")
}
-func writeCon(fpath string, val string) error {
+func writeCon(fpath, val string) error {
if fpath == "" {
return ErrEmptyPath
}
@@ -346,12 +376,45 @@ func writeCon(fpath string, val string) error {
}
defer out.Close()
+ if err := isProcHandle(out); err != nil {
+ return err
+ }
+
if val != "" {
_, err = out.Write([]byte(val))
} else {
_, err = out.Write(nil)
}
- return err
+ if err != nil {
+ return errors.Wrapf(err, "failed to set %s on procfs", fpath)
+ }
+ return nil
+}
+
+func attrPath(attr string) string {
+ // Linux >= 3.17 provides this
+ const threadSelfPrefix = "/proc/thread-self/attr"
+
+ attrPathOnce.Do(func() {
+ st, err := os.Stat(threadSelfPrefix)
+ if err == nil && st.Mode().IsDir() {
+ haveThreadSelf = true
+ }
+ })
+
+ if haveThreadSelf {
+ return path.Join(threadSelfPrefix, attr)
+ }
+
+ return path.Join("/proc/self/task/", strconv.Itoa(unix.Gettid()), "/attr/", attr)
+}
+
+func readAttr(attr string) (string, error) {
+ return readCon(attrPath(attr))
+}
+
+func writeAttr(attr, val string) error {
+ return writeCon(attrPath(attr), val)
}
/*
@@ -363,6 +426,18 @@ func CanonicalizeContext(val string) (string, error) {
return readWriteCon(filepath.Join(getSelinuxMountPoint(), "context"), val)
}
+/*
+ComputeCreateContext requests the type transition from source to target for class from the kernel.
+*/
+func ComputeCreateContext(source string, target string, class string) (string, error) {
+ classidx, err := ClassIndex(class)
+ if err != nil {
+ return "", err
+ }
+
+ return readWriteCon(filepath.Join(getSelinuxMountPoint(), "create"), fmt.Sprintf("%s %s %d", source, target, classidx))
+}
+
func readWriteCon(fpath string, val string) (string, error) {
if fpath == "" {
return "", ErrEmptyPath
@@ -390,41 +465,41 @@ SetExecLabel sets the SELinux label that the kernel will use for any programs
that are executed by the current process thread, or an error.
*/
func SetExecLabel(label string) error {
- return writeCon(fmt.Sprintf("/proc/self/task/%d/attr/exec", syscall.Gettid()), label)
+ return writeAttr("exec", label)
}
/*
-SetTaskLabel sets the SELinux label for the current thread, or an error.
+SetTaskLabel sets the SELinux label for the current thread, or an error.
This requires the dyntransition permission.
*/
func SetTaskLabel(label string) error {
- return writeCon(fmt.Sprintf("/proc/self/task/%d/attr/current", syscall.Gettid()), label)
+ return writeAttr("current", label)
}
// SetSocketLabel takes a process label and tells the kernel to assign the
// label to the next socket that gets created
func SetSocketLabel(label string) error {
- return writeCon(fmt.Sprintf("/proc/self/task/%d/attr/sockcreate", syscall.Gettid()), label)
+ return writeAttr("sockcreate", label)
}
// SocketLabel retrieves the current socket label setting
func SocketLabel() (string, error) {
- return readCon(fmt.Sprintf("/proc/self/task/%d/attr/sockcreate", syscall.Gettid()))
+ return readAttr("sockcreate")
}
// PeerLabel retrieves the label of the client on the other side of a socket
func PeerLabel(fd uintptr) (string, error) {
- return unix.GetsockoptString(int(fd), syscall.SOL_SOCKET, syscall.SO_PEERSEC)
+ return unix.GetsockoptString(int(fd), unix.SOL_SOCKET, unix.SO_PEERSEC)
}
// SetKeyLabel takes a process label and tells the kernel to assign the
// label to the next kernel keyring that gets created
func SetKeyLabel(label string) error {
err := writeCon("/proc/self/attr/keycreate", label)
- if os.IsNotExist(err) {
+ if os.IsNotExist(errors.Cause(err)) {
return nil
}
- if label == "" && os.IsPermission(err) && !GetEnabled() {
+ if label == "" && os.IsPermission(errors.Cause(err)) {
return nil
}
return err
@@ -480,19 +555,18 @@ func ReserveLabel(label string) {
}
func selinuxEnforcePath() string {
- return fmt.Sprintf("%s/enforce", getSelinuxMountPoint())
+ return path.Join(getSelinuxMountPoint(), "enforce")
}
// EnforceMode returns the current SELinux mode Enforcing, Permissive, Disabled
func EnforceMode() int {
var enforce int
- enforceS, err := readCon(selinuxEnforcePath())
+ enforceB, err := ioutil.ReadFile(selinuxEnforcePath())
if err != nil {
return -1
}
-
- enforce, err = strconv.Atoi(string(enforceS))
+ enforce, err = strconv.Atoi(string(enforceB))
if err != nil {
return -1
}
@@ -504,7 +578,7 @@ SetEnforceMode sets the current SELinux mode Enforcing, Permissive.
Disabled is not valid, since this needs to be set at boot time.
*/
func SetEnforceMode(mode int) error {
- return writeCon(selinuxEnforcePath(), fmt.Sprintf("%d", mode))
+ return ioutil.WriteFile(selinuxEnforcePath(), []byte(strconv.Itoa(mode)), 0644)
}
/*
@@ -686,7 +760,7 @@ exit:
// SecurityCheckContext validates that the SELinux label is understood by the kernel
func SecurityCheckContext(val string) error {
- return writeCon(fmt.Sprintf("%s/context", getSelinuxMountPoint()), val)
+ return ioutil.WriteFile(path.Join(getSelinuxMountPoint(), "context"), []byte(val), 0644)
}
/*
@@ -726,14 +800,14 @@ func badPrefix(fpath string) error {
badPrefixes := []string{"/usr"}
for _, prefix := range badPrefixes {
if strings.HasPrefix(fpath, prefix) {
- return fmt.Errorf("relabeling content in %s is not allowed", prefix)
+ return errors.Errorf("relabeling content in %s is not allowed", prefix)
}
}
return nil
}
-// Chcon changes the `fpath` file object to the SELinux label `label`.
-// If `fpath` is a directory and `recurse`` is true, Chcon will walk the
+// Chcon changes the fpath file object to the SELinux label label.
+// If fpath is a directory and recurse is true, Chcon will walk the
// directory tree setting the label.
func Chcon(fpath string, label string, recurse bool) error {
if fpath == "" {
@@ -745,19 +819,19 @@ func Chcon(fpath string, label string, recurse bool) error {
if err := badPrefix(fpath); err != nil {
return err
}
- callback := func(p string, info os.FileInfo, err error) error {
+
+ if !recurse {
+ return SetFileLabel(fpath, label)
+ }
+
+ return pwalk.Walk(fpath, func(p string, info os.FileInfo, err error) error {
e := SetFileLabel(p, label)
- if os.IsNotExist(e) {
+ // Walk a file tree can race with removal, so ignore ENOENT
+ if os.IsNotExist(errors.Cause(e)) {
return nil
}
return e
- }
-
- if recurse {
- return filepath.Walk(fpath, callback)
- }
-
- return SetFileLabel(fpath, label)
+ })
}
// DupSecOpt takes an SELinux process label and returns security options that
diff --git a/vendor/github.com/opencontainers/selinux/go-selinux/selinux_stub.go b/vendor/github.com/opencontainers/selinux/go-selinux/selinux_stub.go
index 0c2e1cd38..f349513d9 100644
--- a/vendor/github.com/opencontainers/selinux/go-selinux/selinux_stub.go
+++ b/vendor/github.com/opencontainers/selinux/go-selinux/selinux_stub.go
@@ -1,4 +1,4 @@
-// +build !selinux
+// +build !selinux !linux
package selinux
@@ -35,6 +35,11 @@ func GetEnabled() bool {
return false
}
+// ClassIndex returns the int index for an object class in the loaded policy, or -1 and an error
+func ClassIndex(class string) (int, error) {
+ return -1, nil
+}
+
// SetFileLabel sets the SELinux label for this path or returns an error.
func SetFileLabel(fpath string, label string) error {
return nil
@@ -89,6 +94,13 @@ func CanonicalizeContext(val string) (string, error) {
}
/*
+ComputeCreateContext requests the type transition from source to target for class from the kernel.
+*/
+func ComputeCreateContext(source string, target string, class string) (string, error) {
+ return "", nil
+}
+
+/*
SetExecLabel sets the SELinux label that the kernel will use for any programs
that are executed by the current process thread, or an error.
*/
diff --git a/vendor/github.com/opencontainers/selinux/go-selinux/xattrs.go b/vendor/github.com/opencontainers/selinux/go-selinux/xattrs.go
index 67a9d8ee8..de5c80ef3 100644
--- a/vendor/github.com/opencontainers/selinux/go-selinux/xattrs.go
+++ b/vendor/github.com/opencontainers/selinux/go-selinux/xattrs.go
@@ -3,76 +3,28 @@
package selinux
import (
- "syscall"
- "unsafe"
+ "golang.org/x/sys/unix"
)
-var _zero uintptr
-
// Returns a []byte slice if the xattr is set and nil otherwise
// Requires path and its attribute as arguments
func lgetxattr(path string, attr string) ([]byte, error) {
- var sz int
- pathBytes, err := syscall.BytePtrFromString(path)
- if err != nil {
- return nil, err
- }
- attrBytes, err := syscall.BytePtrFromString(attr)
- if err != nil {
- return nil, err
- }
-
// Start with a 128 length byte array
- sz = 128
- dest := make([]byte, sz)
- destBytes := unsafe.Pointer(&dest[0])
- _sz, _, errno := syscall.Syscall6(syscall.SYS_LGETXATTR, uintptr(unsafe.Pointer(pathBytes)), uintptr(unsafe.Pointer(attrBytes)), uintptr(destBytes), uintptr(len(dest)), 0, 0)
-
- switch {
- case errno == syscall.ENODATA:
- return nil, errno
- case errno == syscall.ENOTSUP:
- return nil, errno
- case errno == syscall.ERANGE:
- // 128 byte array might just not be good enough,
- // A dummy buffer is used ``uintptr(0)`` to get real size
- // of the xattrs on disk
- _sz, _, errno = syscall.Syscall6(syscall.SYS_LGETXATTR, uintptr(unsafe.Pointer(pathBytes)), uintptr(unsafe.Pointer(attrBytes)), uintptr(unsafe.Pointer(nil)), uintptr(0), 0, 0)
- sz = int(_sz)
- if sz < 0 {
+ dest := make([]byte, 128)
+ sz, errno := unix.Lgetxattr(path, attr, dest)
+ for errno == unix.ERANGE {
+ // Buffer too small, use zero-sized buffer to get the actual size
+ sz, errno = unix.Lgetxattr(path, attr, []byte{})
+ if errno != nil {
return nil, errno
}
+
dest = make([]byte, sz)
- destBytes := unsafe.Pointer(&dest[0])
- _sz, _, errno = syscall.Syscall6(syscall.SYS_LGETXATTR, uintptr(unsafe.Pointer(pathBytes)), uintptr(unsafe.Pointer(attrBytes)), uintptr(destBytes), uintptr(len(dest)), 0, 0)
- if errno != 0 {
- return nil, errno
- }
- case errno != 0:
+ sz, errno = unix.Lgetxattr(path, attr, dest)
+ }
+ if errno != nil {
return nil, errno
}
- sz = int(_sz)
- return dest[:sz], nil
-}
-func lsetxattr(path string, attr string, data []byte, flags int) error {
- pathBytes, err := syscall.BytePtrFromString(path)
- if err != nil {
- return err
- }
- attrBytes, err := syscall.BytePtrFromString(attr)
- if err != nil {
- return err
- }
- var dataBytes unsafe.Pointer
- if len(data) > 0 {
- dataBytes = unsafe.Pointer(&data[0])
- } else {
- dataBytes = unsafe.Pointer(&_zero)
- }
- _, _, errno := syscall.Syscall6(syscall.SYS_LSETXATTR, uintptr(unsafe.Pointer(pathBytes)), uintptr(unsafe.Pointer(attrBytes)), uintptr(dataBytes), uintptr(len(data)), uintptr(flags), 0)
- if errno != 0 {
- return errno
- }
- return nil
+ return dest[:sz], nil
}
diff --git a/vendor/github.com/opencontainers/selinux/pkg/pwalk/README.md b/vendor/github.com/opencontainers/selinux/pkg/pwalk/README.md
new file mode 100644
index 000000000..16c4dfd3e
--- /dev/null
+++ b/vendor/github.com/opencontainers/selinux/pkg/pwalk/README.md
@@ -0,0 +1,42 @@
+## pwalk: parallel implementation of filepath.Walk
+
+This is a wrapper for [filepath.Walk](https://pkg.go.dev/path/filepath?tab=doc#Walk)
+which may speed it up by calling multiple callback functions (WalkFunc) in parallel,
+utilizing goroutines.
+
+By default, it utilizes 2\*runtime.NumCPU() goroutines for callbacks.
+This can be changed by using WalkN function which has the additional
+parameter, specifying the number of goroutines (concurrency).
+
+### Caveats
+
+Please note the following limitations of this code:
+
+* Unlike filepath.Walk, the order of calls is non-deterministic;
+
+* Only primitive error handling is supported:
+
+ * filepath.SkipDir is not supported;
+
+ * no errors are ever passed to WalkFunc;
+
+ * once any error is returned from any WalkFunc instance, no more new calls
+ to WalkFunc are made, and the error is returned to the caller of Walk;
+
+ * if more than one walkFunc instance will return an error, only one
+ of such errors will be propagated and returned by Walk, others
+ will be silently discarded.
+
+### Documentation
+
+For the official documentation, see
+https://pkg.go.dev/github.com/opencontainers/selinux/pkg/pwalk?tab=doc
+
+### Benchmarks
+
+For a WalkFunc that consists solely of the return statement, this
+implementation is about 10% slower than the standard library's
+filepath.Walk.
+
+Otherwise (if a WalkFunc is doing something) this is usually faster,
+except when the WalkN(..., 1) is used.
diff --git a/vendor/github.com/opencontainers/selinux/pkg/pwalk/pwalk.go b/vendor/github.com/opencontainers/selinux/pkg/pwalk/pwalk.go
new file mode 100644
index 000000000..2ee0d0150
--- /dev/null
+++ b/vendor/github.com/opencontainers/selinux/pkg/pwalk/pwalk.go
@@ -0,0 +1,99 @@
+package pwalk
+
+import (
+ "os"
+ "path/filepath"
+ "runtime"
+ "sync"
+
+ "github.com/pkg/errors"
+)
+
+type WalkFunc = filepath.WalkFunc
+
+// Walk is a wrapper for filepath.Walk which can call multiple walkFn
+// in parallel, allowing to handle each item concurrently. A maximum of
+// twice the runtime.NumCPU() walkFn will be called at any one time.
+// If you want to change the maximum, use WalkN instead.
+//
+// The order of calls is non-deterministic.
+//
+// Note that this implementation only supports primitive error handling:
+//
+// * no errors are ever passed to WalkFn
+//
+// * once a walkFn returns any error, all further processing stops
+// and the error is returned to the caller of Walk;
+//
+// * filepath.SkipDir is not supported;
+//
+// * if more than one walkFn instance will return an error, only one
+// of such errors will be propagated and returned by Walk, others
+// will be silently discarded.
+//
+func Walk(root string, walkFn WalkFunc) error {
+ return WalkN(root, walkFn, runtime.NumCPU()*2)
+}
+
+// WalkN is a wrapper for filepath.Walk which can call multiple walkFn
+// in parallel, allowing to handle each item concurrently. A maximum of
+// num walkFn will be called at any one time.
+func WalkN(root string, walkFn WalkFunc, num int) error {
+ // make sure limit is sensible
+ if num < 1 {
+ return errors.Errorf("walk(%q): num must be > 0", root)
+ }
+
+ files := make(chan *walkArgs, 2*num)
+ errCh := make(chan error, 1) // get the first error, ignore others
+
+ // Start walking a tree asap
+ var err error
+ go func() {
+ err = filepath.Walk(root, func(p string, info os.FileInfo, err error) error {
+ if err != nil {
+ close(files)
+ return err
+ }
+ // add a file to the queue unless a callback sent an error
+ select {
+ case e := <-errCh:
+ close(files)
+ return e
+ default:
+ files <- &walkArgs{path: p, info: &info}
+ return nil
+ }
+ })
+ if err == nil {
+ close(files)
+ }
+ }()
+
+ var wg sync.WaitGroup
+ wg.Add(num)
+ for i := 0; i < num; i++ {
+ go func() {
+ for file := range files {
+ if e := walkFn(file.path, *file.info, nil); e != nil {
+ select {
+ case errCh <- e: // sent ok
+ default: // buffer full
+ }
+ }
+ }
+ wg.Done()
+ }()
+ }
+
+ wg.Wait()
+
+ return err
+}
+
+// walkArgs holds the arguments that were passed to the Walk or WalkLimit
+// functions.
+type walkArgs struct {
+ path string
+ info *os.FileInfo
+}
diff --git a/vendor/github.com/openshift/imagebuilder/builder.go b/vendor/github.com/openshift/imagebuilder/builder.go
index 5a2d0d539..81d7b8421 100644
--- a/vendor/github.com/openshift/imagebuilder/builder.go
+++ b/vendor/github.com/openshift/imagebuilder/builder.go
@@ -288,8 +288,12 @@ func NewBuilder(args map[string]string) *Builder {
for k, v := range builtinAllowedBuildArgs {
allowed[k] = v
}
+ provided := make(map[string]string)
+ for k, v := range args {
+ provided[k] = v
+ }
return &Builder{
- Args: args,
+ Args: provided,
AllowedArgs: allowed,
}
}
diff --git a/vendor/github.com/openshift/imagebuilder/dispatchers.go b/vendor/github.com/openshift/imagebuilder/dispatchers.go
index ff365848a..e7f2f97bf 100644
--- a/vendor/github.com/openshift/imagebuilder/dispatchers.go
+++ b/vendor/github.com/openshift/imagebuilder/dispatchers.go
@@ -19,6 +19,7 @@ import (
docker "github.com/fsouza/go-dockerclient"
+ "github.com/containerd/containerd/platforms"
"github.com/openshift/imagebuilder/signal"
"github.com/openshift/imagebuilder/strslice"
)
@@ -27,6 +28,27 @@ var (
obRgex = regexp.MustCompile(`(?i)^\s*ONBUILD\s*`)
)
+var localspec = platforms.DefaultSpec()
+
+// https://docs.docker.com/engine/reference/builder/#automatic-platform-args-in-the-global-scope
+var builtinBuildArgs = map[string]string{
+ "TARGETPLATFORM": localspec.OS + "/" + localspec.Architecture,
+ "TARGETOS": localspec.OS,
+ "TARGETARCH": localspec.Architecture,
+ "TARGETVARIANT": localspec.Variant,
+ "BUILDPLATFORM": localspec.OS + "/" + localspec.Architecture,
+ "BUILDOS": localspec.OS,
+ "BUILDARCH": localspec.Architecture,
+ "BUILDVARIANT": localspec.Variant,
+}
+
+func init() {
+ if localspec.Variant != "" {
+ builtinBuildArgs["TARGETPLATFORM"] = builtinBuildArgs["TARGETPLATFORM"] + "/" + localspec.Variant
+ builtinBuildArgs["BUILDPLATFORM"] = builtinBuildArgs["BUILDPLATFORM"] + "/" + localspec.Variant
+ }
+}
+
// ENV foo bar
//
// Sets the environment variable foo to bar, also makes interpolation
@@ -131,14 +153,16 @@ func add(b *Builder, args []string, attributes map[string]bool, flagArgs []strin
var chown string
last := len(args) - 1
dest := makeAbsolute(args[last], b.RunConfig.WorkingDir)
- if len(flagArgs) > 0 {
- for _, arg := range flagArgs {
- switch {
- case strings.HasPrefix(arg, "--chown="):
- chown = strings.TrimPrefix(arg, "--chown=")
- default:
- return fmt.Errorf("ADD only supports the --chown=<uid:gid> flag")
- }
+ for _, a := range flagArgs {
+ arg, err := ProcessWord(a, b.Env)
+ if err != nil {
+ return err
+ }
+ switch {
+ case strings.HasPrefix(arg, "--chown="):
+ chown = strings.TrimPrefix(arg, "--chown=")
+ default:
+ return fmt.Errorf("ADD only supports the --chown=<uid:gid> flag")
}
}
b.PendingCopies = append(b.PendingCopies, Copy{Src: args[0:last], Dest: dest, Download: true, Chown: chown})
@@ -157,16 +181,18 @@ func dispatchCopy(b *Builder, args []string, attributes map[string]bool, flagArg
dest := makeAbsolute(args[last], b.RunConfig.WorkingDir)
var chown string
var from string
- if len(flagArgs) > 0 {
- for _, arg := range flagArgs {
- switch {
- case strings.HasPrefix(arg, "--chown="):
- chown = strings.TrimPrefix(arg, "--chown=")
- case strings.HasPrefix(arg, "--from="):
- from = strings.TrimPrefix(arg, "--from=")
- default:
- return fmt.Errorf("COPY only supports the --chown=<uid:gid> and the --from=<image|stage> flags")
- }
+ for _, a := range flagArgs {
+ arg, err := ProcessWord(a, b.Env)
+ if err != nil {
+ return err
+ }
+ switch {
+ case strings.HasPrefix(arg, "--chown="):
+ chown = strings.TrimPrefix(arg, "--chown=")
+ case strings.HasPrefix(arg, "--from="):
+ from = strings.TrimPrefix(arg, "--from=")
+ default:
+ return fmt.Errorf("COPY only supports the --chown=<uid:gid> and the --from=<image|stage> flags")
}
}
b.PendingCopies = append(b.PendingCopies, Copy{From: from, Src: args[0:last], Dest: dest, Download: false, Chown: chown})
@@ -516,6 +542,8 @@ func healthcheck(b *Builder, args []string, attributes map[string]bool, flagArgs
return nil
}
+var targetArgs = []string{"TARGETOS", "TARGETARCH", "TARGETVARIANT"}
+
// ARG name[=value]
//
// Adds the variable foo to the trusted list of variables that can be passed
@@ -543,6 +571,26 @@ func arg(b *Builder, args []string, attributes map[string]bool, flagArgs []strin
name = parts[0]
value = parts[1]
hasDefault = true
+ if name == "TARGETPLATFORM" {
+ p, err := platforms.Parse(value)
+ if err != nil {
+ return fmt.Errorf("error parsing TARGETPLATFORM argument")
+ }
+ for _, val := range targetArgs {
+ b.AllowedArgs[val] = true
+ }
+ b.Args["TARGETPLATFORM"] = p.OS + "/" + p.Architecture
+ b.Args["TARGETOS"] = p.OS
+ b.Args["TARGETARCH"] = p.Architecture
+ b.Args["TARGETVARIANT"] = p.Variant
+ if p.Variant != "" {
+ b.Args["TARGETPLATFORM"] = b.Args["TARGETPLATFORM"] + "/" + p.Variant
+ }
+ }
+ } else if val, ok := builtinBuildArgs[arg]; ok {
+ name = arg
+ value = val
+ hasDefault = true
} else {
name = arg
hasDefault = false
diff --git a/vendor/github.com/openshift/imagebuilder/vendor.conf b/vendor/github.com/openshift/imagebuilder/vendor.conf
index c3f7d1a6b..8074ce80a 100644
--- a/vendor/github.com/openshift/imagebuilder/vendor.conf
+++ b/vendor/github.com/openshift/imagebuilder/vendor.conf
@@ -1,4 +1,5 @@
github.com/Azure/go-ansiterm d6e3b3328b783f23731bc4d058875b0371ff8109
+github.com/containerd/containerd v1.3.0
github.com/containers/storage v1.2
github.com/docker/docker b68221c37ee597950364788204546f9c9d0e46a1
github.com/docker/go-connections 97c2040d34dfae1d1b1275fa3a78dbdd2f41cf7e
@@ -18,3 +19,7 @@ golang.org/x/crypto ff983b9c42bc9fbf91556e191cc8efb585c16908
golang.org/x/net 45ffb0cd1ba084b73e26dee67e667e1be5acce83
golang.org/x/sys 7fbe1cd0fcc20051e1fcb87fbabec4a1bacaaeba
k8s.io/klog 8e90cee79f823779174776412c13478955131846
+google.golang.org/grpc 6eaf6f47437a6b4e2153a190160ef39a92c7eceb # v1.23.0
+github.com/golang/protobuf v1.2.0
+google.golang.org/genproto d80a6e20e776b0b17a324d0ba1ab50a39c8e8944
+
diff --git a/vendor/github.com/rootless-containers/rootlesskit/pkg/port/builtin/child/child.go b/vendor/github.com/rootless-containers/rootlesskit/pkg/port/builtin/child/child.go
index 5477dda51..7cce235a6 100644
--- a/vendor/github.com/rootless-containers/rootlesskit/pkg/port/builtin/child/child.go
+++ b/vendor/github.com/rootless-containers/rootlesskit/pkg/port/builtin/child/child.go
@@ -124,7 +124,12 @@ func (d *childDriver) handleConnectRequest(c *net.UnixConn, req *msg.Request) er
if err != nil {
return err
}
- err = unix.Sendmsg(int(f.Fd()), []byte("dummy"), oob, nil, 0)
+ for {
+ err = unix.Sendmsg(int(f.Fd()), []byte("dummy"), oob, nil, 0)
+ if err != unix.EINTR {
+ break
+ }
+ }
return err
}
diff --git a/vendor/github.com/rootless-containers/rootlesskit/pkg/port/builtin/msg/msg.go b/vendor/github.com/rootless-containers/rootlesskit/pkg/port/builtin/msg/msg.go
index c603f473a..e95b62191 100644
--- a/vendor/github.com/rootless-containers/rootlesskit/pkg/port/builtin/msg/msg.go
+++ b/vendor/github.com/rootless-containers/rootlesskit/pkg/port/builtin/msg/msg.go
@@ -62,7 +62,16 @@ func ConnectToChild(c *net.UnixConn, spec port.Spec) (int, error) {
}
oobSpace := unix.CmsgSpace(4)
oob := make([]byte, oobSpace)
- _, oobN, _, _, err := c.ReadMsgUnix(nil, oob)
+ var (
+ oobN int
+ err error
+ )
+ for {
+ _, oobN, _, _, err = c.ReadMsgUnix(nil, oob)
+ if err != unix.EINTR {
+ break
+ }
+ }
if err != nil {
return 0, err
}
diff --git a/vendor/github.com/sirupsen/logrus/.golangci.yml b/vendor/github.com/sirupsen/logrus/.golangci.yml
new file mode 100644
index 000000000..65dc28503
--- /dev/null
+++ b/vendor/github.com/sirupsen/logrus/.golangci.yml
@@ -0,0 +1,40 @@
+run:
+ # do not run on test files yet
+ tests: false
+
+# all available settings of specific linters
+linters-settings:
+ errcheck:
+ # report about not checking of errors in type assetions: `a := b.(MyStruct)`;
+ # default is false: such cases aren't reported by default.
+ check-type-assertions: false
+
+ # report about assignment of errors to blank identifier: `num, _ := strconv.Atoi(numStr)`;
+ # default is false: such cases aren't reported by default.
+ check-blank: false
+
+ lll:
+ line-length: 100
+ tab-width: 4
+
+ prealloc:
+ simple: false
+ range-loops: false
+ for-loops: false
+
+ whitespace:
+ multi-if: false # Enforces newlines (or comments) after every multi-line if statement
+ multi-func: false # Enforces newlines (or comments) after every multi-line function signature
+
+linters:
+ enable:
+ - megacheck
+ - govet
+ disable:
+ - maligned
+ - prealloc
+ disable-all: false
+ presets:
+ - bugs
+ - unused
+ fast: false
diff --git a/vendor/github.com/sirupsen/logrus/.travis.yml b/vendor/github.com/sirupsen/logrus/.travis.yml
index 848938a6d..5e20aa414 100644
--- a/vendor/github.com/sirupsen/logrus/.travis.yml
+++ b/vendor/github.com/sirupsen/logrus/.travis.yml
@@ -4,21 +4,13 @@ git:
depth: 1
env:
- GO111MODULE=on
- - GO111MODULE=off
-go: [ 1.11.x, 1.12.x ]
-os: [ linux, osx ]
-matrix:
- exclude:
- - go: 1.12.x
- env: GO111MODULE=off
- - go: 1.11.x
- os: osx
+go: [1.13.x, 1.14.x]
+os: [linux, osx]
install:
- ./travis/install.sh
- - if [[ "$GO111MODULE" == "on" ]]; then go mod download; fi
- - if [[ "$GO111MODULE" == "off" ]]; then go get github.com/stretchr/testify/assert golang.org/x/sys/unix github.com/konsorten/go-windows-terminal-sequences; fi
script:
- ./travis/cross_build.sh
+ - ./travis/lint.sh
- export GOMAXPROCS=4
- export GORACE=halt_on_error=1
- go test -race -v ./...
diff --git a/vendor/github.com/sirupsen/logrus/README.md b/vendor/github.com/sirupsen/logrus/README.md
index a4796eb07..5796706db 100644
--- a/vendor/github.com/sirupsen/logrus/README.md
+++ b/vendor/github.com/sirupsen/logrus/README.md
@@ -1,8 +1,28 @@
-# Logrus <img src="http://i.imgur.com/hTeVwmJ.png" width="40" height="40" alt=":walrus:" class="emoji" title=":walrus:"/>&nbsp;[![Build Status](https://travis-ci.org/sirupsen/logrus.svg?branch=master)](https://travis-ci.org/sirupsen/logrus)&nbsp;[![GoDoc](https://godoc.org/github.com/sirupsen/logrus?status.svg)](https://godoc.org/github.com/sirupsen/logrus)
+# Logrus <img src="http://i.imgur.com/hTeVwmJ.png" width="40" height="40" alt=":walrus:" class="emoji" title=":walrus:"/> [![Build Status](https://travis-ci.org/sirupsen/logrus.svg?branch=master)](https://travis-ci.org/sirupsen/logrus) [![GoDoc](https://godoc.org/github.com/sirupsen/logrus?status.svg)](https://godoc.org/github.com/sirupsen/logrus)
Logrus is a structured logger for Go (golang), completely API compatible with
the standard library logger.
+**Logrus is in maintenance-mode.** We will not be introducing new features. It's
+simply too hard to do in a way that won't break many people's projects, which is
+the last thing you want from your Logging library (again...).
+
+This does not mean Logrus is dead. Logrus will continue to be maintained for
+security, (backwards compatible) bug fixes, and performance (where we are
+limited by the interface).
+
+I believe Logrus' biggest contribution is to have played a part in today's
+widespread use of structured logging in Golang. There doesn't seem to be a
+reason to do a major, breaking iteration into Logrus V2, since the fantastic Go
+community has built those independently. Many fantastic alternatives have sprung
+up. Logrus would look like those, had it been re-designed with what we know
+about structured logging in Go today. Check out, for example,
+[Zerolog][zerolog], [Zap][zap], and [Apex][apex].
+
+[zerolog]: https://github.com/rs/zerolog
+[zap]: https://github.com/uber-go/zap
+[apex]: https://github.com/apex/log
+
**Seeing weird case-sensitive problems?** It's in the past been possible to
import Logrus as both upper- and lower-case. Due to the Go package environment,
this caused issues in the community and we needed a standard. Some environments
@@ -15,11 +35,6 @@ comments](https://github.com/sirupsen/logrus/issues/553#issuecomment-306591437).
For an in-depth explanation of the casing issue, see [this
comment](https://github.com/sirupsen/logrus/issues/570#issuecomment-313933276).
-**Are you interested in assisting in maintaining Logrus?** Currently I have a
-lot of obligations, and I am unable to provide Logrus with the maintainership it
-needs. If you'd like to help, please reach out to me at `simon at author's
-username dot com`.
-
Nicely color-coded in development (when a TTY is attached, otherwise just
plain text):
@@ -187,7 +202,7 @@ func main() {
log.Out = os.Stdout
// You could set this to any `io.Writer` such as a file
- // file, err := os.OpenFile("logrus.log", os.O_CREATE|os.O_WRONLY, 0666)
+ // file, err := os.OpenFile("logrus.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
// if err == nil {
// log.Out = file
// } else {
@@ -272,7 +287,7 @@ func init() {
```
Note: Syslog hook also support connecting to local syslog (Ex. "/dev/log" or "/var/run/syslog" or "/var/run/log"). For the detail, please check the [syslog hook README](hooks/syslog/README.md).
-A list of currently known of service hook can be found in this wiki [page](https://github.com/sirupsen/logrus/wiki/Hooks)
+A list of currently known service hooks can be found in this wiki [page](https://github.com/sirupsen/logrus/wiki/Hooks)
#### Level logging
@@ -354,6 +369,7 @@ The built-in logging formatters are:
[github.com/mattn/go-colorable](https://github.com/mattn/go-colorable).
* When colors are enabled, levels are truncated to 4 characters by default. To disable
truncation set the `DisableLevelTruncation` field to `true`.
+ * When outputting to a TTY, it's often helpful to visually scan down a column where all the levels are the same width. Setting the `PadLevelText` field to `true` enables this behavior, by adding padding to the level text.
* All options are listed in the [generated docs](https://godoc.org/github.com/sirupsen/logrus#TextFormatter).
* `logrus.JSONFormatter`. Logs fields as JSON.
* All options are listed in the [generated docs](https://godoc.org/github.com/sirupsen/logrus#JSONFormatter).
@@ -364,8 +380,10 @@ Third party logging formatters:
* [`GELF`](https://github.com/fabienm/go-logrus-formatters). Formats entries so they comply to Graylog's [GELF 1.1 specification](http://docs.graylog.org/en/2.4/pages/gelf.html).
* [`logstash`](https://github.com/bshuster-repo/logrus-logstash-hook). Logs fields as [Logstash](http://logstash.net) Events.
* [`prefixed`](https://github.com/x-cray/logrus-prefixed-formatter). Displays log entry source along with alternative layout.
-* [`zalgo`](https://github.com/aybabtme/logzalgo). Invoking the P͉̫o̳̼̊w̖͈̰͎e̬͔̭͂r͚̼̹̲ ̫͓͉̳͈ō̠͕͖̚f̝͍̠ ͕̲̞͖͑Z̖̫̤̫ͪa͉̬͈̗l͖͎g̳̥o̰̥̅!̣͔̲̻͊̄ ̙̘̦̹̦.
+* [`zalgo`](https://github.com/aybabtme/logzalgo). Invoking the Power of Zalgo.
* [`nested-logrus-formatter`](https://github.com/antonfisher/nested-logrus-formatter). Converts logrus fields to a nested structure.
+* [`powerful-logrus-formatter`](https://github.com/zput/zxcTool). get fileName, log's line number and the latest function's name when print log; Sava log to files.
+* [`caption-json-formatter`](https://github.com/nolleh/caption_json_formatter). logrus's message json formatter with human-readable caption added.
You can define your formatter by implementing the `Formatter` interface,
requiring a `Format` method. `Format` takes an `*Entry`. `entry.Data` is a
@@ -430,14 +448,14 @@ entries. It should not be a feature of the application-level logger.
| Tool | Description |
| ---- | ----------- |
-|[Logrus Mate](https://github.com/gogap/logrus_mate)|Logrus mate is a tool for Logrus to manage loggers, you can initial logger's level, hook and formatter by config file, the logger will generated with different config at different environment.|
+|[Logrus Mate](https://github.com/gogap/logrus_mate)|Logrus mate is a tool for Logrus to manage loggers, you can initial logger's level, hook and formatter by config file, the logger will be generated with different configs in different environments.|
|[Logrus Viper Helper](https://github.com/heirko/go-contrib/tree/master/logrusHelper)|An Helper around Logrus to wrap with spf13/Viper to load configuration with fangs! And to simplify Logrus configuration use some behavior of [Logrus Mate](https://github.com/gogap/logrus_mate). [sample](https://github.com/heirko/iris-contrib/blob/master/middleware/logrus-logger/example) |
#### Testing
Logrus has a built in facility for asserting the presence of log messages. This is implemented through the `test` hook and provides:
-* decorators for existing logger (`test.NewLocal` and `test.NewGlobal`) which basically just add the `test` hook
+* decorators for existing logger (`test.NewLocal` and `test.NewGlobal`) which basically just adds the `test` hook
* a test logger (`test.NewNullLogger`) that just records log messages (and does not output any):
```go
@@ -465,7 +483,7 @@ func TestSomething(t*testing.T){
Logrus can register one or more functions that will be called when any `fatal`
level message is logged. The registered handlers will be executed before
-logrus performs a `os.Exit(1)`. This behavior may be helpful if callers need
+logrus performs an `os.Exit(1)`. This behavior may be helpful if callers need
to gracefully shutdown. Unlike a `panic("Something went wrong...")` call which can be intercepted with a deferred `recover` a call to `os.Exit(1)` can not be intercepted.
```
@@ -490,6 +508,6 @@ Situation when locking is not needed includes:
1) logger.Out is protected by locks.
- 2) logger.Out is a os.File handler opened with `O_APPEND` flag, and every write is smaller than 4k. (This allow multi-thread/multi-process writing)
+ 2) logger.Out is an os.File handler opened with `O_APPEND` flag, and every write is smaller than 4k. (This allows multi-thread/multi-process writing)
(Refer to http://www.notthewizard.com/2014/06/17/are-files-appends-really-atomic/)
diff --git a/vendor/github.com/sirupsen/logrus/entry.go b/vendor/github.com/sirupsen/logrus/entry.go
index 63e25583c..27b14bfb1 100644
--- a/vendor/github.com/sirupsen/logrus/entry.go
+++ b/vendor/github.com/sirupsen/logrus/entry.go
@@ -85,10 +85,15 @@ func NewEntry(logger *Logger) *Entry {
}
}
+// Returns the bytes representation of this entry from the formatter.
+func (entry *Entry) Bytes() ([]byte, error) {
+ return entry.Logger.Formatter.Format(entry)
+}
+
// Returns the string representation from the reader and ultimately the
// formatter.
func (entry *Entry) String() (string, error) {
- serialized, err := entry.Logger.Formatter.Format(entry)
+ serialized, err := entry.Bytes()
if err != nil {
return "", err
}
@@ -103,7 +108,11 @@ func (entry *Entry) WithError(err error) *Entry {
// Add a context to the Entry.
func (entry *Entry) WithContext(ctx context.Context) *Entry {
- return &Entry{Logger: entry.Logger, Data: entry.Data, Time: entry.Time, err: entry.err, Context: ctx}
+ dataCopy := make(Fields, len(entry.Data))
+ for k, v := range entry.Data {
+ dataCopy[k] = v
+ }
+ return &Entry{Logger: entry.Logger, Data: dataCopy, Time: entry.Time, err: entry.err, Context: ctx}
}
// Add a single field to the Entry.
@@ -113,6 +122,8 @@ func (entry *Entry) WithField(key string, value interface{}) *Entry {
// Add a map of fields to the Entry.
func (entry *Entry) WithFields(fields Fields) *Entry {
+ entry.Logger.mu.Lock()
+ defer entry.Logger.mu.Unlock()
data := make(Fields, len(entry.Data)+len(fields))
for k, v := range entry.Data {
data[k] = v
@@ -144,7 +155,11 @@ func (entry *Entry) WithFields(fields Fields) *Entry {
// Overrides the time of the Entry.
func (entry *Entry) WithTime(t time.Time) *Entry {
- return &Entry{Logger: entry.Logger, Data: entry.Data, Time: t, err: entry.err, Context: entry.Context}
+ dataCopy := make(Fields, len(entry.Data))
+ for k, v := range entry.Data {
+ dataCopy[k] = v
+ }
+ return &Entry{Logger: entry.Logger, Data: dataCopy, Time: t, err: entry.err, Context: entry.Context}
}
// getPackageName reduces a fully qualified function name to the package name
@@ -165,15 +180,20 @@ func getPackageName(f string) string {
// getCaller retrieves the name of the first non-logrus calling function
func getCaller() *runtime.Frame {
-
// cache this package's fully-qualified name
callerInitOnce.Do(func() {
- pcs := make([]uintptr, 2)
+ pcs := make([]uintptr, maximumCallerDepth)
_ = runtime.Callers(0, pcs)
- logrusPackage = getPackageName(runtime.FuncForPC(pcs[1]).Name())
- // now that we have the cache, we can skip a minimum count of known-logrus functions
- // XXX this is dubious, the number of frames may vary
+ // dynamic get the package name and the minimum caller depth
+ for i := 0; i < maximumCallerDepth; i++ {
+ funcName := runtime.FuncForPC(pcs[i]).Name()
+ if strings.Contains(funcName, "getCaller") {
+ logrusPackage = getPackageName(funcName)
+ break
+ }
+ }
+
minimumCallerDepth = knownLogrusFrames
})
@@ -187,7 +207,7 @@ func getCaller() *runtime.Frame {
// If the caller isn't part of this package, we're done
if pkg != logrusPackage {
- return &f
+ return &f //nolint:scopelint
}
}
@@ -217,9 +237,11 @@ func (entry Entry) log(level Level, msg string) {
entry.Level = level
entry.Message = msg
+ entry.Logger.mu.Lock()
if entry.Logger.ReportCaller {
entry.Caller = getCaller()
}
+ entry.Logger.mu.Unlock()
entry.fireHooks()
@@ -255,11 +277,10 @@ func (entry *Entry) write() {
serialized, err := entry.Logger.Formatter.Format(entry)
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to obtain reader, %v\n", err)
- } else {
- _, err = entry.Logger.Out.Write(serialized)
- if err != nil {
- fmt.Fprintf(os.Stderr, "Failed to write to log, %v\n", err)
- }
+ return
+ }
+ if _, err = entry.Logger.Out.Write(serialized); err != nil {
+ fmt.Fprintf(os.Stderr, "Failed to write to log, %v\n", err)
}
}
diff --git a/vendor/github.com/sirupsen/logrus/exported.go b/vendor/github.com/sirupsen/logrus/exported.go
index 62fc2f219..42b04f6c8 100644
--- a/vendor/github.com/sirupsen/logrus/exported.go
+++ b/vendor/github.com/sirupsen/logrus/exported.go
@@ -80,7 +80,7 @@ func WithFields(fields Fields) *Entry {
return std.WithFields(fields)
}
-// WithTime creats an entry from the standard logger and overrides the time of
+// WithTime creates an entry from the standard logger and overrides the time of
// logs generated with it.
//
// Note that it doesn't log until you call Debug, Print, Info, Warn, Fatal
diff --git a/vendor/github.com/sirupsen/logrus/go.mod b/vendor/github.com/sirupsen/logrus/go.mod
index 12fdf9898..9ea6e841b 100644
--- a/vendor/github.com/sirupsen/logrus/go.mod
+++ b/vendor/github.com/sirupsen/logrus/go.mod
@@ -4,7 +4,8 @@ require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/konsorten/go-windows-terminal-sequences v1.0.1
github.com/pmezard/go-difflib v1.0.0 // indirect
- github.com/stretchr/objx v0.1.1 // indirect
github.com/stretchr/testify v1.2.2
golang.org/x/sys v0.0.0-20190422165155-953cdadca894
)
+
+go 1.13
diff --git a/vendor/github.com/sirupsen/logrus/go.sum b/vendor/github.com/sirupsen/logrus/go.sum
index 596c318b9..95a3f07de 100644
--- a/vendor/github.com/sirupsen/logrus/go.sum
+++ b/vendor/github.com/sirupsen/logrus/go.sum
@@ -1,16 +1,10 @@
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/konsorten/go-windows-terminal-sequences v0.0.0-20180402223658-b729f2633dfe h1:CHRGQ8V7OlCYtwaKPJi3iA7J+YdNKdo8j7nG5IgDhjs=
-github.com/konsorten/go-windows-terminal-sequences v0.0.0-20180402223658-b729f2633dfe/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
-github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A=
-github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
-golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33 h1:I6FyU15t786LL7oL/hn43zqTuEGr4PN7F4XJ1p4E3Y8=
-golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894 h1:Cz4ceDQGXuKRnVBDTS23GTn/pU5OE2C0WrNTOYK1Uuc=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
diff --git a/vendor/github.com/sirupsen/logrus/json_formatter.go b/vendor/github.com/sirupsen/logrus/json_formatter.go
index 098a21a06..ba7f23711 100644
--- a/vendor/github.com/sirupsen/logrus/json_formatter.go
+++ b/vendor/github.com/sirupsen/logrus/json_formatter.go
@@ -28,6 +28,9 @@ type JSONFormatter struct {
// DisableTimestamp allows disabling automatic timestamps in output
DisableTimestamp bool
+ // DisableHTMLEscape allows disabling html escaping in output
+ DisableHTMLEscape bool
+
// DataKey allows users to put all the log entry parameters into a nested dictionary at a given key.
DataKey string
@@ -110,6 +113,7 @@ func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) {
}
encoder := json.NewEncoder(b)
+ encoder.SetEscapeHTML(!f.DisableHTMLEscape)
if f.PrettyPrint {
encoder.SetIndent("", " ")
}
diff --git a/vendor/github.com/sirupsen/logrus/logger.go b/vendor/github.com/sirupsen/logrus/logger.go
index c0c0b1e55..6fdda748e 100644
--- a/vendor/github.com/sirupsen/logrus/logger.go
+++ b/vendor/github.com/sirupsen/logrus/logger.go
@@ -68,10 +68,10 @@ func (mw *MutexWrap) Disable() {
// `Out` and `Hooks` directly on the default logger instance. You can also just
// instantiate your own:
//
-// var log = &Logger{
+// var log = &logrus.Logger{
// Out: os.Stderr,
-// Formatter: new(JSONFormatter),
-// Hooks: make(LevelHooks),
+// Formatter: new(logrus.JSONFormatter),
+// Hooks: make(logrus.LevelHooks),
// Level: logrus.DebugLevel,
// }
//
@@ -100,8 +100,9 @@ func (logger *Logger) releaseEntry(entry *Entry) {
logger.entryPool.Put(entry)
}
-// Adds a field to the log entry, note that it doesn't log until you call
-// Debug, Print, Info, Warn, Error, Fatal or Panic. It only creates a log entry.
+// WithField allocates a new entry and adds a field to it.
+// Debug, Print, Info, Warn, Error, Fatal or Panic must be then applied to
+// this new returned entry.
// If you want multiple fields, use `WithFields`.
func (logger *Logger) WithField(key string, value interface{}) *Entry {
entry := logger.newEntry()
diff --git a/vendor/github.com/sirupsen/logrus/logrus.go b/vendor/github.com/sirupsen/logrus/logrus.go
index 8644761f7..2f16224cb 100644
--- a/vendor/github.com/sirupsen/logrus/logrus.go
+++ b/vendor/github.com/sirupsen/logrus/logrus.go
@@ -51,7 +51,7 @@ func (level *Level) UnmarshalText(text []byte) error {
return err
}
- *level = Level(l)
+ *level = l
return nil
}
diff --git a/vendor/github.com/sirupsen/logrus/terminal_check_bsd.go b/vendor/github.com/sirupsen/logrus/terminal_check_bsd.go
index 3c4f43f91..499789984 100644
--- a/vendor/github.com/sirupsen/logrus/terminal_check_bsd.go
+++ b/vendor/github.com/sirupsen/logrus/terminal_check_bsd.go
@@ -1,4 +1,5 @@
// +build darwin dragonfly freebsd netbsd openbsd
+// +build !js
package logrus
@@ -10,4 +11,3 @@ func isTerminal(fd int) bool {
_, err := unix.IoctlGetTermios(fd, ioctlReadTermios)
return err == nil
}
-
diff --git a/vendor/github.com/sirupsen/logrus/terminal_check_js.go b/vendor/github.com/sirupsen/logrus/terminal_check_js.go
new file mode 100644
index 000000000..ebdae3ec6
--- /dev/null
+++ b/vendor/github.com/sirupsen/logrus/terminal_check_js.go
@@ -0,0 +1,7 @@
+// +build js
+
+package logrus
+
+func isTerminal(fd int) bool {
+ return false
+}
diff --git a/vendor/github.com/sirupsen/logrus/terminal_check_unix.go b/vendor/github.com/sirupsen/logrus/terminal_check_unix.go
index 355dc966f..cc4fe6e31 100644
--- a/vendor/github.com/sirupsen/logrus/terminal_check_unix.go
+++ b/vendor/github.com/sirupsen/logrus/terminal_check_unix.go
@@ -1,4 +1,5 @@
// +build linux aix
+// +build !js
package logrus
@@ -10,4 +11,3 @@ func isTerminal(fd int) bool {
_, err := unix.IoctlGetTermios(fd, ioctlReadTermios)
return err == nil
}
-
diff --git a/vendor/github.com/sirupsen/logrus/text_formatter.go b/vendor/github.com/sirupsen/logrus/text_formatter.go
index e01587c43..2d15a239f 100644
--- a/vendor/github.com/sirupsen/logrus/text_formatter.go
+++ b/vendor/github.com/sirupsen/logrus/text_formatter.go
@@ -6,9 +6,11 @@ import (
"os"
"runtime"
"sort"
+ "strconv"
"strings"
"sync"
"time"
+ "unicode/utf8"
)
const (
@@ -32,6 +34,9 @@ type TextFormatter struct {
// Force disabling colors.
DisableColors bool
+ // Force quoting of all values
+ ForceQuote bool
+
// Override coloring based on CLICOLOR and CLICOLOR_FORCE. - https://bixense.com/clicolors/
EnvironmentOverrideColors bool
@@ -57,6 +62,10 @@ type TextFormatter struct {
// Disables the truncation of the level text to 4 characters.
DisableLevelTruncation bool
+ // PadLevelText Adds padding the level text so that all the levels output at the same length
+ // PadLevelText is a superset of the DisableLevelTruncation option
+ PadLevelText bool
+
// QuoteEmptyFields will wrap empty fields in quotes if true
QuoteEmptyFields bool
@@ -79,23 +88,32 @@ type TextFormatter struct {
CallerPrettyfier func(*runtime.Frame) (function string, file string)
terminalInitOnce sync.Once
+
+ // The max length of the level text, generated dynamically on init
+ levelTextMaxLength int
}
func (f *TextFormatter) init(entry *Entry) {
if entry.Logger != nil {
f.isTerminal = checkIfTerminal(entry.Logger.Out)
}
+ // Get the max length of the level text
+ for _, level := range AllLevels {
+ levelTextLength := utf8.RuneCount([]byte(level.String()))
+ if levelTextLength > f.levelTextMaxLength {
+ f.levelTextMaxLength = levelTextLength
+ }
+ }
}
func (f *TextFormatter) isColored() bool {
isColored := f.ForceColors || (f.isTerminal && (runtime.GOOS != "windows"))
if f.EnvironmentOverrideColors {
- if force, ok := os.LookupEnv("CLICOLOR_FORCE"); ok && force != "0" {
+ switch force, ok := os.LookupEnv("CLICOLOR_FORCE"); {
+ case ok && force != "0":
isColored = true
- } else if ok && force == "0" {
- isColored = false
- } else if os.Getenv("CLICOLOR") == "0" {
+ case ok && force == "0", os.Getenv("CLICOLOR") == "0":
isColored = false
}
}
@@ -217,9 +235,18 @@ func (f *TextFormatter) printColored(b *bytes.Buffer, entry *Entry, keys []strin
}
levelText := strings.ToUpper(entry.Level.String())
- if !f.DisableLevelTruncation {
+ if !f.DisableLevelTruncation && !f.PadLevelText {
levelText = levelText[0:4]
}
+ if f.PadLevelText {
+ // Generates the format string used in the next line, for example "%-6s" or "%-7s".
+ // Based on the max level text length.
+ formatString := "%-" + strconv.Itoa(f.levelTextMaxLength) + "s"
+ // Formats the level text by appending spaces up to the max length, for example:
+ // - "INFO "
+ // - "WARNING"
+ levelText = fmt.Sprintf(formatString, levelText)
+ }
// Remove a single newline if it already exists in the message to keep
// the behavior of logrus text_formatter the same as the stdlib log package
@@ -243,11 +270,12 @@ func (f *TextFormatter) printColored(b *bytes.Buffer, entry *Entry, keys []strin
}
}
- if f.DisableTimestamp {
+ switch {
+ case f.DisableTimestamp:
fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m%s %-44s ", levelColor, levelText, caller, entry.Message)
- } else if !f.FullTimestamp {
+ case !f.FullTimestamp:
fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%04d]%s %-44s ", levelColor, levelText, int(entry.Time.Sub(baseTimestamp)/time.Second), caller, entry.Message)
- } else {
+ default:
fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%s]%s %-44s ", levelColor, levelText, entry.Time.Format(timestampFormat), caller, entry.Message)
}
for _, k := range keys {
@@ -258,6 +286,9 @@ func (f *TextFormatter) printColored(b *bytes.Buffer, entry *Entry, keys []strin
}
func (f *TextFormatter) needsQuoting(text string) bool {
+ if f.ForceQuote {
+ return true
+ }
if f.QuoteEmptyFields && len(text) == 0 {
return true
}
diff --git a/vendor/github.com/sirupsen/logrus/writer.go b/vendor/github.com/sirupsen/logrus/writer.go
index 9e1f75135..72e8e3a1b 100644
--- a/vendor/github.com/sirupsen/logrus/writer.go
+++ b/vendor/github.com/sirupsen/logrus/writer.go
@@ -6,10 +6,16 @@ import (
"runtime"
)
+// Writer at INFO level. See WriterLevel for details.
func (logger *Logger) Writer() *io.PipeWriter {
return logger.WriterLevel(InfoLevel)
}
+// WriterLevel returns an io.Writer that can be used to write arbitrary text to
+// the logger at the given log level. Each line written to the writer will be
+// printed in the usual way using formatters and hooks. The writer is part of an
+// io.Pipe and it is the callers responsibility to close the writer when done.
+// This can be used to override the standard library logger easily.
func (logger *Logger) WriterLevel(level Level) *io.PipeWriter {
return NewEntry(logger).WriterLevel(level)
}
diff --git a/vendor/github.com/spf13/cobra/.gitignore b/vendor/github.com/spf13/cobra/.gitignore
index 3b053c59e..b2b848e77 100644
--- a/vendor/github.com/spf13/cobra/.gitignore
+++ b/vendor/github.com/spf13/cobra/.gitignore
@@ -32,7 +32,8 @@ Session.vim
tags
*.exe
-
+cobra
cobra.test
-.idea/*
+.idea/
+*.iml
diff --git a/vendor/github.com/spf13/cobra/.travis.yml b/vendor/github.com/spf13/cobra/.travis.yml
index 38b85f499..fca1e6948 100644
--- a/vendor/github.com/spf13/cobra/.travis.yml
+++ b/vendor/github.com/spf13/cobra/.travis.yml
@@ -18,13 +18,10 @@ matrix:
go: 1.12.x
script: diff -u <(echo -n) <(gofmt -d -s .)
-before_install:
- - mkdir -p bin
- - curl -Lso bin/shellcheck https://github.com/caarlos0/shellcheck-docker/releases/download/v0.6.0/shellcheck
- - chmod +x bin/shellcheck
- - go get -u github.com/kyoh86/richgo
+before_install: go get -u github.com/kyoh86/richgo
+
script:
- - PATH=$PATH:$PWD/bin richgo test -v ./...
+ - richgo test -v ./...
- go build
- if [ -z $NOVET ]; then
diff -u <(echo -n) <(go vet . 2>&1 | grep -vE 'ExampleCommand|bash_completions.*Fprint');
diff --git a/vendor/github.com/spf13/cobra/README.md b/vendor/github.com/spf13/cobra/README.md
index 60c5a425b..2f8175bc2 100644
--- a/vendor/github.com/spf13/cobra/README.md
+++ b/vendor/github.com/spf13/cobra/README.md
@@ -24,11 +24,13 @@ Many of the most widely used Go projects are built using Cobra, such as:
[Prototool](https://github.com/uber/prototool),
[mattermost-server](https://github.com/mattermost/mattermost-server),
[Gardener](https://github.com/gardener/gardenctl),
+[Linkerd](https://linkerd.io/),
etc.
[![Build Status](https://travis-ci.org/spf13/cobra.svg "Travis CI status")](https://travis-ci.org/spf13/cobra)
[![CircleCI status](https://circleci.com/gh/spf13/cobra.png?circle-token=:circle-token "CircleCI status")](https://circleci.com/gh/spf13/cobra)
[![GoDoc](https://godoc.org/github.com/spf13/cobra?status.svg)](https://godoc.org/github.com/spf13/cobra)
+[![Go Report Card](https://goreportcard.com/badge/github.com/spf13/cobra)](https://goreportcard.com/report/github.com/spf13/cobra)
# Table of Contents
@@ -208,51 +210,78 @@ You will additionally define flags and handle configuration in your init() funct
For example cmd/root.go:
```go
+package cmd
+
import (
- "fmt"
- "os"
+ "fmt"
+ "os"
- homedir "github.com/mitchellh/go-homedir"
- "github.com/spf13/cobra"
- "github.com/spf13/viper"
+ homedir "github.com/mitchellh/go-homedir"
+ "github.com/spf13/cobra"
+ "github.com/spf13/viper"
)
-func init() {
- cobra.OnInitialize(initConfig)
- rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.cobra.yaml)")
- rootCmd.PersistentFlags().StringVarP(&projectBase, "projectbase", "b", "", "base project directory eg. github.com/spf13/")
- rootCmd.PersistentFlags().StringP("author", "a", "YOUR NAME", "Author name for copyright attribution")
- rootCmd.PersistentFlags().StringVarP(&userLicense, "license", "l", "", "Name of license for the project (can provide `licensetext` in config)")
- rootCmd.PersistentFlags().Bool("viper", true, "Use Viper for configuration")
- viper.BindPFlag("author", rootCmd.PersistentFlags().Lookup("author"))
- viper.BindPFlag("projectbase", rootCmd.PersistentFlags().Lookup("projectbase"))
- viper.BindPFlag("useViper", rootCmd.PersistentFlags().Lookup("viper"))
- viper.SetDefault("author", "NAME HERE <EMAIL ADDRESS>")
- viper.SetDefault("license", "apache")
+var (
+ // Used for flags.
+ cfgFile string
+ userLicense string
+
+ rootCmd = &cobra.Command{
+ Use: "cobra",
+ Short: "A generator for Cobra based Applications",
+ Long: `Cobra is a CLI library for Go that empowers applications.
+This application is a tool to generate the needed files
+to quickly create a Cobra application.`,
+ }
+)
+
+// Execute executes the root command.
+func Execute() error {
+ return rootCmd.Execute()
}
-func initConfig() {
- // Don't forget to read config either from cfgFile or from home directory!
- if cfgFile != "" {
- // Use config file from the flag.
- viper.SetConfigFile(cfgFile)
- } else {
- // Find home directory.
- home, err := homedir.Dir()
- if err != nil {
- fmt.Println(err)
- os.Exit(1)
- }
+func init() {
+ cobra.OnInitialize(initConfig)
+
+ rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.cobra.yaml)")
+ rootCmd.PersistentFlags().StringP("author", "a", "YOUR NAME", "author name for copyright attribution")
+ rootCmd.PersistentFlags().StringVarP(&userLicense, "license", "l", "", "name of license for the project")
+ rootCmd.PersistentFlags().Bool("viper", true, "use Viper for configuration")
+ viper.BindPFlag("author", rootCmd.PersistentFlags().Lookup("author"))
+ viper.BindPFlag("useViper", rootCmd.PersistentFlags().Lookup("viper"))
+ viper.SetDefault("author", "NAME HERE <EMAIL ADDRESS>")
+ viper.SetDefault("license", "apache")
+
+ rootCmd.AddCommand(addCmd)
+ rootCmd.AddCommand(initCmd)
+}
- // Search config in home directory with name ".cobra" (without extension).
- viper.AddConfigPath(home)
- viper.SetConfigName(".cobra")
- }
+func er(msg interface{}) {
+ fmt.Println("Error:", msg)
+ os.Exit(1)
+}
- if err := viper.ReadInConfig(); err != nil {
- fmt.Println("Can't read config:", err)
- os.Exit(1)
- }
+func initConfig() {
+ if cfgFile != "" {
+ // Use config file from the flag.
+ viper.SetConfigFile(cfgFile)
+ } else {
+ // Find home directory.
+ home, err := homedir.Dir()
+ if err != nil {
+ er(err)
+ }
+
+ // Search config in home directory with name ".cobra" (without extension).
+ viper.AddConfigPath(home)
+ viper.SetConfigName(".cobra")
+ }
+
+ viper.AutomaticEnv()
+
+ if err := viper.ReadInConfig(); err == nil {
+ fmt.Println("Using config file:", viper.ConfigFileUsed())
+ }
}
```
@@ -459,7 +488,7 @@ For many years people have printed back to the screen.`,
Echo works a lot like print, except it has a child command.`,
Args: cobra.MinimumNArgs(1),
Run: func(cmd *cobra.Command, args []string) {
- fmt.Println("Print: " + strings.Join(args, " "))
+ fmt.Println("Echo: " + strings.Join(args, " "))
},
}
diff --git a/vendor/github.com/spf13/cobra/bash_completions.go b/vendor/github.com/spf13/cobra/bash_completions.go
index 57bb8e1b3..1e0e25cf6 100644
--- a/vendor/github.com/spf13/cobra/bash_completions.go
+++ b/vendor/github.com/spf13/cobra/bash_completions.go
@@ -61,6 +61,7 @@ __%[1]s_contains_word()
__%[1]s_handle_reply()
{
__%[1]s_debug "${FUNCNAME[0]}"
+ local comp
case $cur in
-*)
if [[ $(type -t compopt) = "builtin" ]]; then
@@ -72,7 +73,9 @@ __%[1]s_handle_reply()
else
allflags=("${flags[*]} ${two_word_flags[*]}")
fi
- COMPREPLY=( $(compgen -W "${allflags[*]}" -- "$cur") )
+ while IFS='' read -r comp; do
+ COMPREPLY+=("$comp")
+ done < <(compgen -W "${allflags[*]}" -- "$cur")
if [[ $(type -t compopt) = "builtin" ]]; then
[[ "${COMPREPLY[0]}" == *= ]] || compopt +o nospace
fi
@@ -122,10 +125,14 @@ __%[1]s_handle_reply()
if [[ ${#must_have_one_flag[@]} -ne 0 ]]; then
completions+=("${must_have_one_flag[@]}")
fi
- COMPREPLY=( $(compgen -W "${completions[*]}" -- "$cur") )
+ while IFS='' read -r comp; do
+ COMPREPLY+=("$comp")
+ done < <(compgen -W "${completions[*]}" -- "$cur")
if [[ ${#COMPREPLY[@]} -eq 0 && ${#noun_aliases[@]} -gt 0 && ${#must_have_one_noun[@]} -ne 0 ]]; then
- COMPREPLY=( $(compgen -W "${noun_aliases[*]}" -- "$cur") )
+ while IFS='' read -r comp; do
+ COMPREPLY+=("$comp")
+ done < <(compgen -W "${noun_aliases[*]}" -- "$cur")
fi
if [[ ${#COMPREPLY[@]} -eq 0 ]]; then
@@ -160,7 +167,7 @@ __%[1]s_handle_filename_extension_flag()
__%[1]s_handle_subdirs_in_dir_flag()
{
local dir="$1"
- pushd "${dir}" >/dev/null 2>&1 && _filedir -d && popd >/dev/null 2>&1
+ pushd "${dir}" >/dev/null 2>&1 && _filedir -d && popd >/dev/null 2>&1 || return
}
__%[1]s_handle_flag()
diff --git a/vendor/github.com/spf13/cobra/cobra.go b/vendor/github.com/spf13/cobra/cobra.go
index 6505c070b..d01becc8f 100644
--- a/vendor/github.com/spf13/cobra/cobra.go
+++ b/vendor/github.com/spf13/cobra/cobra.go
@@ -52,7 +52,7 @@ var EnableCommandSorting = true
// if the CLI is started from explorer.exe.
// To disable the mousetrap, just set this variable to blank string ("").
// Works only on Microsoft Windows.
-var MousetrapHelpText string = `This is a command line tool.
+var MousetrapHelpText = `This is a command line tool.
You need to open cmd.exe and run it from there.
`
@@ -61,7 +61,7 @@ You need to open cmd.exe and run it from there.
// if the CLI is started from explorer.exe. Set to 0 to wait for the return key to be pressed.
// To disable the mousetrap, just set MousetrapHelpText to blank string ("").
// Works only on Microsoft Windows.
-var MousetrapDisplayDuration time.Duration = 5 * time.Second
+var MousetrapDisplayDuration = 5 * time.Second
// AddTemplateFunc adds a template function that's available to Usage and Help
// template generation.
diff --git a/vendor/github.com/spf13/cobra/command.go b/vendor/github.com/spf13/cobra/command.go
index c7e898303..fb60ebd93 100644
--- a/vendor/github.com/spf13/cobra/command.go
+++ b/vendor/github.com/spf13/cobra/command.go
@@ -17,6 +17,8 @@ package cobra
import (
"bytes"
+ "context"
+ "errors"
"fmt"
"io"
"os"
@@ -27,6 +29,8 @@ import (
flag "github.com/spf13/pflag"
)
+var ErrSubCommandRequired = errors.New("subcommand is required")
+
// FParseErrWhitelist configures Flag parse errors to be ignored
type FParseErrWhitelist flag.ParseErrorsWhitelist
@@ -140,9 +144,11 @@ type Command struct {
// TraverseChildren parses flags on all parents before executing child command.
TraverseChildren bool
- //FParseErrWhitelist flag parse errors to be ignored
+ // FParseErrWhitelist flag parse errors to be ignored
FParseErrWhitelist FParseErrWhitelist
+ ctx context.Context
+
// commands is the list of commands supported by this program.
commands []*Command
// parent is a parent command for this command.
@@ -202,6 +208,12 @@ type Command struct {
errWriter io.Writer
}
+// Context returns underlying command context. If command wasn't
+// executed with ExecuteContext Context returns Background context.
+func (c *Command) Context() context.Context {
+ return c.ctx
+}
+
// SetArgs sets arguments for the command. It is set to os.Args[1:] by default, if desired, can be overridden
// particularly useful when testing.
func (c *Command) SetArgs(a []string) {
@@ -228,7 +240,7 @@ func (c *Command) SetErr(newErr io.Writer) {
c.errWriter = newErr
}
-// SetOut sets the source for input data
+// SetIn sets the source for input data
// If newIn is nil, os.Stdin is used.
func (c *Command) SetIn(newIn io.Reader) {
c.inReader = newIn
@@ -297,7 +309,7 @@ func (c *Command) ErrOrStderr() io.Writer {
return c.getErr(os.Stderr)
}
-// ErrOrStderr returns output to stderr
+// InOrStdin returns output to stderr
func (c *Command) InOrStdin() io.Reader {
return c.getIn(os.Stdin)
}
@@ -369,6 +381,8 @@ func (c *Command) HelpFunc() func(*Command, []string) {
}
return func(c *Command, a []string) {
c.mergePersistentFlags()
+ // The help should be sent to stdout
+ // See https://github.com/spf13/cobra/issues/1002
err := tmpl(c.OutOrStdout(), c.HelpTemplate(), c)
if err != nil {
c.Println(err)
@@ -786,7 +800,7 @@ func (c *Command) execute(a []string) (err error) {
}
if !c.Runnable() {
- return flag.ErrHelp
+ return ErrSubCommandRequired
}
c.preRun()
@@ -857,6 +871,13 @@ func (c *Command) preRun() {
}
}
+// ExecuteContext is the same as Execute(), but sets the ctx on the command.
+// Retrieve ctx by calling cmd.Context() inside your *Run lifecycle functions.
+func (c *Command) ExecuteContext(ctx context.Context) error {
+ c.ctx = ctx
+ return c.Execute()
+}
+
// Execute uses the args (os.Args[1:] by default)
// and run through the command tree finding appropriate matches
// for commands and then corresponding flags.
@@ -867,6 +888,10 @@ func (c *Command) Execute() error {
// ExecuteC executes the command.
func (c *Command) ExecuteC() (cmd *Command, err error) {
+ if c.ctx == nil {
+ c.ctx = context.Background()
+ }
+
// Regardless of what command execute is called on, run on Root only
if c.HasParent() {
return c.Root().ExecuteC()
@@ -911,6 +936,12 @@ func (c *Command) ExecuteC() (cmd *Command, err error) {
cmd.commandCalledAs.name = cmd.Name()
}
+ // We have to pass global context to children command
+ // if context is present on the parent command.
+ if cmd.ctx == nil {
+ cmd.ctx = c.ctx
+ }
+
err = cmd.execute(flags)
if err != nil {
// Always show help if requested, even if SilenceErrors is in
@@ -920,6 +951,14 @@ func (c *Command) ExecuteC() (cmd *Command, err error) {
return cmd, nil
}
+ // If command wasn't runnable, show full help, but do return the error.
+ // This will result in apps by default returning a non-success exit code, but also gives them the option to
+ // handle specially.
+ if err == ErrSubCommandRequired {
+ cmd.HelpFunc()(cmd, args)
+ return cmd, err
+ }
+
// If root command has SilentErrors flagged,
// all subcommands should respect it
if !cmd.SilenceErrors && !c.SilenceErrors {
@@ -1547,7 +1586,7 @@ func (c *Command) ParseFlags(args []string) error {
beforeErrorBufLen := c.flagErrorBuf.Len()
c.mergePersistentFlags()
- //do it here after merging all flags and just before parse
+ // do it here after merging all flags and just before parse
c.Flags().ParseErrorsWhitelist = flag.ParseErrorsWhitelist(c.FParseErrWhitelist)
err := c.Flags().Parse(args)
diff --git a/vendor/github.com/spf13/cobra/go.mod b/vendor/github.com/spf13/cobra/go.mod
index 9a9eb65a3..dea1030ba 100644
--- a/vendor/github.com/spf13/cobra/go.mod
+++ b/vendor/github.com/spf13/cobra/go.mod
@@ -3,11 +3,10 @@ module github.com/spf13/cobra
go 1.12
require (
- github.com/BurntSushi/toml v0.3.1 // indirect
- github.com/cpuguy83/go-md2man v1.0.10
+ github.com/cpuguy83/go-md2man/v2 v2.0.0
github.com/inconshreveable/mousetrap v1.0.0
github.com/mitchellh/go-homedir v1.1.0
github.com/spf13/pflag v1.0.3
- github.com/spf13/viper v1.3.2
+ github.com/spf13/viper v1.4.0
gopkg.in/yaml.v2 v2.2.2
)
diff --git a/vendor/github.com/spf13/cobra/go.sum b/vendor/github.com/spf13/cobra/go.sum
index 9761f4d03..3aaa2ac0f 100644
--- a/vendor/github.com/spf13/cobra/go.sum
+++ b/vendor/github.com/spf13/cobra/go.sum
@@ -1,31 +1,91 @@
+cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
+github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
+github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
+github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
+github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
+github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
+github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
+github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
+github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
-github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
-github.com/cpuguy83/go-md2man v1.0.10 h1:BSKMNlYxDvnunlTymqtgONjNnaRV1sTpcovwwjF22jk=
-github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
+github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
+github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
+github.com/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM=
+github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
+github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
+github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
+github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
+github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
+github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
+github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
+github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
+github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
+github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
+github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
+github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
+github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
+github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
+github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
+github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
+github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
+github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
+github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
+github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
+github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
+github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
+github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
+github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
+github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
+github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
+github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
+github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
+github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/magiconair/properties v1.8.0 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDePerRcY=
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
+github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
+github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
+github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
+github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
-github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo=
-github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
+github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
+github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
+github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
+github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
+github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
+github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
+github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
+github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
+github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
+github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
+github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=
+github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
+github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
+github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
+github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
+github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
+github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/spf13/afero v1.1.2 h1:m8/z1t7/fwjysjQRYbP0RD+bUIF/8tJwPdEZsI83ACI=
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8=
@@ -34,18 +94,56 @@ github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
-github.com/spf13/viper v1.3.2 h1:VUFqw5KcqRf7i70GOzW7N+Q7+gxVBkSSqiXB12+JQ4M=
-github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
+github.com/spf13/viper v1.4.0 h1:yXHLWeravcrgGyFSyCgdYpXQ9dR9c/WED3pg1RhxqEU=
+github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
+github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
-github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
+github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
+github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
+github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
-golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
-golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a h1:1n5lsVfiQW3yfsRGu98756EH1YthsFqr/5mxHduZW2A=
-golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
+go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
+go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
+go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
+golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
+golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
+golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
+golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
+golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
+golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
+google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
+google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
+google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
+gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
+gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
+gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
+gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
diff --git a/vendor/github.com/stretchr/testify/assert/assertion_format.go b/vendor/github.com/stretchr/testify/assert/assertion_format.go
index e0364e9e7..bf89ecd21 100644
--- a/vendor/github.com/stretchr/testify/assert/assertion_format.go
+++ b/vendor/github.com/stretchr/testify/assert/assertion_format.go
@@ -32,7 +32,8 @@ func Containsf(t TestingT, s interface{}, contains interface{}, msg string, args
return Contains(t, s, contains, append([]interface{}{msg}, args...)...)
}
-// DirExistsf checks whether a directory exists in the given path. It also fails if the path is a file rather a directory or there is an error checking whether it exists.
+// DirExistsf checks whether a directory exists in the given path. It also fails
+// if the path is a file rather a directory or there is an error checking whether it exists.
func DirExistsf(t TestingT, path string, msg string, args ...interface{}) bool {
if h, ok := t.(tHelper); ok {
h.Helper()
@@ -160,7 +161,8 @@ func Falsef(t TestingT, value bool, msg string, args ...interface{}) bool {
return False(t, value, append([]interface{}{msg}, args...)...)
}
-// FileExistsf checks whether a file exists in the given path. It also fails if the path points to a directory or there is an error when trying to check the file.
+// FileExistsf checks whether a file exists in the given path. It also fails if
+// the path points to a directory or there is an error when trying to check the file.
func FileExistsf(t TestingT, path string, msg string, args ...interface{}) bool {
if h, ok := t.(tHelper); ok {
h.Helper()
@@ -267,7 +269,7 @@ func Implementsf(t TestingT, interfaceObject interface{}, object interface{}, ms
// InDeltaf asserts that the two numerals are within delta of each other.
//
-// assert.InDeltaf(t, math.Pi, (22 / 7.0, "error message %s", "formatted"), 0.01)
+// assert.InDeltaf(t, math.Pi, 22/7.0, 0.01, "error message %s", "formatted")
func InDeltaf(t TestingT, expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) bool {
if h, ok := t.(tHelper); ok {
h.Helper()
@@ -325,14 +327,6 @@ func JSONEqf(t TestingT, expected string, actual string, msg string, args ...int
return JSONEq(t, expected, actual, append([]interface{}{msg}, args...)...)
}
-// YAMLEqf asserts that two YAML strings are equivalent.
-func YAMLEqf(t TestingT, expected string, actual string, msg string, args ...interface{}) bool {
- if h, ok := t.(tHelper); ok {
- h.Helper()
- }
- return YAMLEq(t, expected, actual, append([]interface{}{msg}, args...)...)
-}
-
// Lenf asserts that the specified object has specific length.
// Lenf also fails if the object has a type that len() not accept.
//
@@ -369,6 +363,17 @@ func LessOrEqualf(t TestingT, e1 interface{}, e2 interface{}, msg string, args .
return LessOrEqual(t, e1, e2, append([]interface{}{msg}, args...)...)
}
+// Neverf asserts that the given condition doesn't satisfy in waitFor time,
+// periodically checking the target function each tick.
+//
+// assert.Neverf(t, func() bool { return false; }, time.Second, 10*time.Millisecond, "error message %s", "formatted")
+func Neverf(t TestingT, condition func() bool, waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) bool {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
+ return Never(t, condition, waitFor, tick, append([]interface{}{msg}, args...)...)
+}
+
// Nilf asserts that the specified object is nil.
//
// assert.Nilf(t, err, "error message %s", "formatted")
@@ -379,6 +384,15 @@ func Nilf(t TestingT, object interface{}, msg string, args ...interface{}) bool
return Nil(t, object, append([]interface{}{msg}, args...)...)
}
+// NoDirExistsf checks whether a directory does not exist in the given path.
+// It fails if the path points to an existing _directory_ only.
+func NoDirExistsf(t TestingT, path string, msg string, args ...interface{}) bool {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
+ return NoDirExists(t, path, append([]interface{}{msg}, args...)...)
+}
+
// NoErrorf asserts that a function returned no error (i.e. `nil`).
//
// actualObj, err := SomeFunction()
@@ -392,6 +406,15 @@ func NoErrorf(t TestingT, err error, msg string, args ...interface{}) bool {
return NoError(t, err, append([]interface{}{msg}, args...)...)
}
+// NoFileExistsf checks whether a file does not exist in a given path. It fails
+// if the path points to an existing _file_ only.
+func NoFileExistsf(t TestingT, path string, msg string, args ...interface{}) bool {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
+ return NoFileExists(t, path, append([]interface{}{msg}, args...)...)
+}
+
// NotContainsf asserts that the specified string, list(array, slice...) or map does NOT contain the
// specified substring or element.
//
@@ -462,6 +485,19 @@ func NotRegexpf(t TestingT, rx interface{}, str interface{}, msg string, args ..
return NotRegexp(t, rx, str, append([]interface{}{msg}, args...)...)
}
+// NotSamef asserts that two pointers do not reference the same object.
+//
+// assert.NotSamef(t, ptr1, ptr2, "error message %s", "formatted")
+//
+// Both arguments must be pointer variables. Pointer variable sameness is
+// determined based on the equality of both type and value.
+func NotSamef(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) bool {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
+ return NotSame(t, expected, actual, append([]interface{}{msg}, args...)...)
+}
+
// NotSubsetf asserts that the specified list(array, slice...) contains not all
// elements given in the specified subset(array, slice...).
//
@@ -491,6 +527,18 @@ func Panicsf(t TestingT, f PanicTestFunc, msg string, args ...interface{}) bool
return Panics(t, f, append([]interface{}{msg}, args...)...)
}
+// PanicsWithErrorf asserts that the code inside the specified PanicTestFunc
+// panics, and that the recovered panic value is an error that satisfies the
+// EqualError comparison.
+//
+// assert.PanicsWithErrorf(t, "crazy error", func(){ GoCrazy() }, "error message %s", "formatted")
+func PanicsWithErrorf(t TestingT, errString string, f PanicTestFunc, msg string, args ...interface{}) bool {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
+ return PanicsWithError(t, errString, f, append([]interface{}{msg}, args...)...)
+}
+
// PanicsWithValuef asserts that the code inside the specified PanicTestFunc panics, and that
// the recovered panic value equals the expected panic value.
//
@@ -557,6 +605,14 @@ func WithinDurationf(t TestingT, expected time.Time, actual time.Time, delta tim
return WithinDuration(t, expected, actual, delta, append([]interface{}{msg}, args...)...)
}
+// YAMLEqf asserts that two YAML strings are equivalent.
+func YAMLEqf(t TestingT, expected string, actual string, msg string, args ...interface{}) bool {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
+ return YAMLEq(t, expected, actual, append([]interface{}{msg}, args...)...)
+}
+
// Zerof asserts that i is the zero value for its type.
func Zerof(t TestingT, i interface{}, msg string, args ...interface{}) bool {
if h, ok := t.(tHelper); ok {
diff --git a/vendor/github.com/stretchr/testify/assert/assertion_forward.go b/vendor/github.com/stretchr/testify/assert/assertion_forward.go
index 26830403a..75ecdcaa2 100644
--- a/vendor/github.com/stretchr/testify/assert/assertion_forward.go
+++ b/vendor/github.com/stretchr/testify/assert/assertion_forward.go
@@ -53,7 +53,8 @@ func (a *Assertions) Containsf(s interface{}, contains interface{}, msg string,
return Containsf(a.t, s, contains, msg, args...)
}
-// DirExists checks whether a directory exists in the given path. It also fails if the path is a file rather a directory or there is an error checking whether it exists.
+// DirExists checks whether a directory exists in the given path. It also fails
+// if the path is a file rather a directory or there is an error checking whether it exists.
func (a *Assertions) DirExists(path string, msgAndArgs ...interface{}) bool {
if h, ok := a.t.(tHelper); ok {
h.Helper()
@@ -61,7 +62,8 @@ func (a *Assertions) DirExists(path string, msgAndArgs ...interface{}) bool {
return DirExists(a.t, path, msgAndArgs...)
}
-// DirExistsf checks whether a directory exists in the given path. It also fails if the path is a file rather a directory or there is an error checking whether it exists.
+// DirExistsf checks whether a directory exists in the given path. It also fails
+// if the path is a file rather a directory or there is an error checking whether it exists.
func (a *Assertions) DirExistsf(path string, msg string, args ...interface{}) bool {
if h, ok := a.t.(tHelper); ok {
h.Helper()
@@ -309,7 +311,8 @@ func (a *Assertions) Falsef(value bool, msg string, args ...interface{}) bool {
return Falsef(a.t, value, msg, args...)
}
-// FileExists checks whether a file exists in the given path. It also fails if the path points to a directory or there is an error when trying to check the file.
+// FileExists checks whether a file exists in the given path. It also fails if
+// the path points to a directory or there is an error when trying to check the file.
func (a *Assertions) FileExists(path string, msgAndArgs ...interface{}) bool {
if h, ok := a.t.(tHelper); ok {
h.Helper()
@@ -317,7 +320,8 @@ func (a *Assertions) FileExists(path string, msgAndArgs ...interface{}) bool {
return FileExists(a.t, path, msgAndArgs...)
}
-// FileExistsf checks whether a file exists in the given path. It also fails if the path points to a directory or there is an error when trying to check the file.
+// FileExistsf checks whether a file exists in the given path. It also fails if
+// the path points to a directory or there is an error when trying to check the file.
func (a *Assertions) FileExistsf(path string, msg string, args ...interface{}) bool {
if h, ok := a.t.(tHelper); ok {
h.Helper()
@@ -521,7 +525,7 @@ func (a *Assertions) Implementsf(interfaceObject interface{}, object interface{}
// InDelta asserts that the two numerals are within delta of each other.
//
-// a.InDelta(math.Pi, (22 / 7.0), 0.01)
+// a.InDelta(math.Pi, 22/7.0, 0.01)
func (a *Assertions) InDelta(expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) bool {
if h, ok := a.t.(tHelper); ok {
h.Helper()
@@ -563,7 +567,7 @@ func (a *Assertions) InDeltaSlicef(expected interface{}, actual interface{}, del
// InDeltaf asserts that the two numerals are within delta of each other.
//
-// a.InDeltaf(math.Pi, (22 / 7.0, "error message %s", "formatted"), 0.01)
+// a.InDeltaf(math.Pi, 22/7.0, 0.01, "error message %s", "formatted")
func (a *Assertions) InDeltaf(expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) bool {
if h, ok := a.t.(tHelper); ok {
h.Helper()
@@ -639,22 +643,6 @@ func (a *Assertions) JSONEqf(expected string, actual string, msg string, args ..
return JSONEqf(a.t, expected, actual, msg, args...)
}
-// YAMLEq asserts that two YAML strings are equivalent.
-func (a *Assertions) YAMLEq(expected string, actual string, msgAndArgs ...interface{}) bool {
- if h, ok := a.t.(tHelper); ok {
- h.Helper()
- }
- return YAMLEq(a.t, expected, actual, msgAndArgs...)
-}
-
-// YAMLEqf asserts that two YAML strings are equivalent.
-func (a *Assertions) YAMLEqf(expected string, actual string, msg string, args ...interface{}) bool {
- if h, ok := a.t.(tHelper); ok {
- h.Helper()
- }
- return YAMLEqf(a.t, expected, actual, msg, args...)
-}
-
// Len asserts that the specified object has specific length.
// Len also fails if the object has a type that len() not accept.
//
@@ -727,6 +715,28 @@ func (a *Assertions) Lessf(e1 interface{}, e2 interface{}, msg string, args ...i
return Lessf(a.t, e1, e2, msg, args...)
}
+// Never asserts that the given condition doesn't satisfy in waitFor time,
+// periodically checking the target function each tick.
+//
+// a.Never(func() bool { return false; }, time.Second, 10*time.Millisecond)
+func (a *Assertions) Never(condition func() bool, waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
+ return Never(a.t, condition, waitFor, tick, msgAndArgs...)
+}
+
+// Neverf asserts that the given condition doesn't satisfy in waitFor time,
+// periodically checking the target function each tick.
+//
+// a.Neverf(func() bool { return false; }, time.Second, 10*time.Millisecond, "error message %s", "formatted")
+func (a *Assertions) Neverf(condition func() bool, waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
+ return Neverf(a.t, condition, waitFor, tick, msg, args...)
+}
+
// Nil asserts that the specified object is nil.
//
// a.Nil(err)
@@ -747,6 +757,24 @@ func (a *Assertions) Nilf(object interface{}, msg string, args ...interface{}) b
return Nilf(a.t, object, msg, args...)
}
+// NoDirExists checks whether a directory does not exist in the given path.
+// It fails if the path points to an existing _directory_ only.
+func (a *Assertions) NoDirExists(path string, msgAndArgs ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
+ return NoDirExists(a.t, path, msgAndArgs...)
+}
+
+// NoDirExistsf checks whether a directory does not exist in the given path.
+// It fails if the path points to an existing _directory_ only.
+func (a *Assertions) NoDirExistsf(path string, msg string, args ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
+ return NoDirExistsf(a.t, path, msg, args...)
+}
+
// NoError asserts that a function returned no error (i.e. `nil`).
//
// actualObj, err := SomeFunction()
@@ -773,6 +801,24 @@ func (a *Assertions) NoErrorf(err error, msg string, args ...interface{}) bool {
return NoErrorf(a.t, err, msg, args...)
}
+// NoFileExists checks whether a file does not exist in a given path. It fails
+// if the path points to an existing _file_ only.
+func (a *Assertions) NoFileExists(path string, msgAndArgs ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
+ return NoFileExists(a.t, path, msgAndArgs...)
+}
+
+// NoFileExistsf checks whether a file does not exist in a given path. It fails
+// if the path points to an existing _file_ only.
+func (a *Assertions) NoFileExistsf(path string, msg string, args ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
+ return NoFileExistsf(a.t, path, msg, args...)
+}
+
// NotContains asserts that the specified string, list(array, slice...) or map does NOT contain the
// specified substring or element.
//
@@ -913,6 +959,32 @@ func (a *Assertions) NotRegexpf(rx interface{}, str interface{}, msg string, arg
return NotRegexpf(a.t, rx, str, msg, args...)
}
+// NotSame asserts that two pointers do not reference the same object.
+//
+// a.NotSame(ptr1, ptr2)
+//
+// Both arguments must be pointer variables. Pointer variable sameness is
+// determined based on the equality of both type and value.
+func (a *Assertions) NotSame(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
+ return NotSame(a.t, expected, actual, msgAndArgs...)
+}
+
+// NotSamef asserts that two pointers do not reference the same object.
+//
+// a.NotSamef(ptr1, ptr2, "error message %s", "formatted")
+//
+// Both arguments must be pointer variables. Pointer variable sameness is
+// determined based on the equality of both type and value.
+func (a *Assertions) NotSamef(expected interface{}, actual interface{}, msg string, args ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
+ return NotSamef(a.t, expected, actual, msg, args...)
+}
+
// NotSubset asserts that the specified list(array, slice...) contains not all
// elements given in the specified subset(array, slice...).
//
@@ -961,6 +1033,30 @@ func (a *Assertions) Panics(f PanicTestFunc, msgAndArgs ...interface{}) bool {
return Panics(a.t, f, msgAndArgs...)
}
+// PanicsWithError asserts that the code inside the specified PanicTestFunc
+// panics, and that the recovered panic value is an error that satisfies the
+// EqualError comparison.
+//
+// a.PanicsWithError("crazy error", func(){ GoCrazy() })
+func (a *Assertions) PanicsWithError(errString string, f PanicTestFunc, msgAndArgs ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
+ return PanicsWithError(a.t, errString, f, msgAndArgs...)
+}
+
+// PanicsWithErrorf asserts that the code inside the specified PanicTestFunc
+// panics, and that the recovered panic value is an error that satisfies the
+// EqualError comparison.
+//
+// a.PanicsWithErrorf("crazy error", func(){ GoCrazy() }, "error message %s", "formatted")
+func (a *Assertions) PanicsWithErrorf(errString string, f PanicTestFunc, msg string, args ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
+ return PanicsWithErrorf(a.t, errString, f, msg, args...)
+}
+
// PanicsWithValue asserts that the code inside the specified PanicTestFunc panics, and that
// the recovered panic value equals the expected panic value.
//
@@ -1103,6 +1199,22 @@ func (a *Assertions) WithinDurationf(expected time.Time, actual time.Time, delta
return WithinDurationf(a.t, expected, actual, delta, msg, args...)
}
+// YAMLEq asserts that two YAML strings are equivalent.
+func (a *Assertions) YAMLEq(expected string, actual string, msgAndArgs ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
+ return YAMLEq(a.t, expected, actual, msgAndArgs...)
+}
+
+// YAMLEqf asserts that two YAML strings are equivalent.
+func (a *Assertions) YAMLEqf(expected string, actual string, msg string, args ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
+ return YAMLEqf(a.t, expected, actual, msg, args...)
+}
+
// Zero asserts that i is the zero value for its type.
func (a *Assertions) Zero(i interface{}, msgAndArgs ...interface{}) bool {
if h, ok := a.t.(tHelper); ok {
diff --git a/vendor/github.com/stretchr/testify/assert/assertions.go b/vendor/github.com/stretchr/testify/assert/assertions.go
index 044da8b01..bdd81389a 100644
--- a/vendor/github.com/stretchr/testify/assert/assertions.go
+++ b/vendor/github.com/stretchr/testify/assert/assertions.go
@@ -11,6 +11,7 @@ import (
"reflect"
"regexp"
"runtime"
+ "runtime/debug"
"strings"
"time"
"unicode"
@@ -21,7 +22,7 @@ import (
yaml "gopkg.in/yaml.v2"
)
-//go:generate go run ../_codegen/main.go -output-package=assert -template=assertion_format.go.tmpl
+//go:generate sh -c "cd ../_codegen && go build && cd - && ../_codegen/_codegen -output-package=assert -template=assertion_format.go.tmpl"
// TestingT is an interface wrapper around *testing.T
type TestingT interface {
@@ -351,6 +352,19 @@ func Equal(t TestingT, expected, actual interface{}, msgAndArgs ...interface{})
}
+// validateEqualArgs checks whether provided arguments can be safely used in the
+// Equal/NotEqual functions.
+func validateEqualArgs(expected, actual interface{}) error {
+ if expected == nil && actual == nil {
+ return nil
+ }
+
+ if isFunction(expected) || isFunction(actual) {
+ return errors.New("cannot take func type as argument")
+ }
+ return nil
+}
+
// Same asserts that two pointers reference the same object.
//
// assert.Same(t, ptr1, ptr2)
@@ -362,18 +376,7 @@ func Same(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) b
h.Helper()
}
- expectedPtr, actualPtr := reflect.ValueOf(expected), reflect.ValueOf(actual)
- if expectedPtr.Kind() != reflect.Ptr || actualPtr.Kind() != reflect.Ptr {
- return Fail(t, "Invalid operation: both arguments must be pointers", msgAndArgs...)
- }
-
- expectedType, actualType := reflect.TypeOf(expected), reflect.TypeOf(actual)
- if expectedType != actualType {
- return Fail(t, fmt.Sprintf("Pointer expected to be of type %v, but was %v",
- expectedType, actualType), msgAndArgs...)
- }
-
- if expected != actual {
+ if !samePointers(expected, actual) {
return Fail(t, fmt.Sprintf("Not same: \n"+
"expected: %p %#v\n"+
"actual : %p %#v", expected, expected, actual, actual), msgAndArgs...)
@@ -382,6 +385,42 @@ func Same(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) b
return true
}
+// NotSame asserts that two pointers do not reference the same object.
+//
+// assert.NotSame(t, ptr1, ptr2)
+//
+// Both arguments must be pointer variables. Pointer variable sameness is
+// determined based on the equality of both type and value.
+func NotSame(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
+
+ if samePointers(expected, actual) {
+ return Fail(t, fmt.Sprintf(
+ "Expected and actual point to the same object: %p %#v",
+ expected, expected), msgAndArgs...)
+ }
+ return true
+}
+
+// samePointers compares two generic interface objects and returns whether
+// they point to the same object
+func samePointers(first, second interface{}) bool {
+ firstPtr, secondPtr := reflect.ValueOf(first), reflect.ValueOf(second)
+ if firstPtr.Kind() != reflect.Ptr || secondPtr.Kind() != reflect.Ptr {
+ return false
+ }
+
+ firstType, secondType := reflect.TypeOf(first), reflect.TypeOf(second)
+ if firstType != secondType {
+ return false
+ }
+
+ // compare pointer addresses
+ return first == second
+}
+
// formatUnequalValues takes two values of arbitrary types and returns string
// representations appropriate to be presented to the user.
//
@@ -393,9 +432,11 @@ func formatUnequalValues(expected, actual interface{}) (e string, a string) {
return fmt.Sprintf("%T(%#v)", expected, expected),
fmt.Sprintf("%T(%#v)", actual, actual)
}
-
- return fmt.Sprintf("%#v", expected),
- fmt.Sprintf("%#v", actual)
+ switch expected.(type) {
+ case time.Duration:
+ return fmt.Sprintf("%v", expected), fmt.Sprintf("%v", actual)
+ }
+ return fmt.Sprintf("%#v", expected), fmt.Sprintf("%#v", actual)
}
// EqualValues asserts that two objects are equal or convertable to the same types
@@ -901,15 +942,17 @@ func Condition(t TestingT, comp Comparison, msgAndArgs ...interface{}) bool {
type PanicTestFunc func()
// didPanic returns true if the function passed to it panics. Otherwise, it returns false.
-func didPanic(f PanicTestFunc) (bool, interface{}) {
+func didPanic(f PanicTestFunc) (bool, interface{}, string) {
didPanic := false
var message interface{}
+ var stack string
func() {
defer func() {
if message = recover(); message != nil {
didPanic = true
+ stack = string(debug.Stack())
}
}()
@@ -918,7 +961,7 @@ func didPanic(f PanicTestFunc) (bool, interface{}) {
}()
- return didPanic, message
+ return didPanic, message, stack
}
@@ -930,7 +973,7 @@ func Panics(t TestingT, f PanicTestFunc, msgAndArgs ...interface{}) bool {
h.Helper()
}
- if funcDidPanic, panicValue := didPanic(f); !funcDidPanic {
+ if funcDidPanic, panicValue, _ := didPanic(f); !funcDidPanic {
return Fail(t, fmt.Sprintf("func %#v should panic\n\tPanic value:\t%#v", f, panicValue), msgAndArgs...)
}
@@ -946,12 +989,34 @@ func PanicsWithValue(t TestingT, expected interface{}, f PanicTestFunc, msgAndAr
h.Helper()
}
- funcDidPanic, panicValue := didPanic(f)
+ funcDidPanic, panicValue, panickedStack := didPanic(f)
if !funcDidPanic {
return Fail(t, fmt.Sprintf("func %#v should panic\n\tPanic value:\t%#v", f, panicValue), msgAndArgs...)
}
if panicValue != expected {
- return Fail(t, fmt.Sprintf("func %#v should panic with value:\t%#v\n\tPanic value:\t%#v", f, expected, panicValue), msgAndArgs...)
+ return Fail(t, fmt.Sprintf("func %#v should panic with value:\t%#v\n\tPanic value:\t%#v\n\tPanic stack:\t%s", f, expected, panicValue, panickedStack), msgAndArgs...)
+ }
+
+ return true
+}
+
+// PanicsWithError asserts that the code inside the specified PanicTestFunc
+// panics, and that the recovered panic value is an error that satisfies the
+// EqualError comparison.
+//
+// assert.PanicsWithError(t, "crazy error", func(){ GoCrazy() })
+func PanicsWithError(t TestingT, errString string, f PanicTestFunc, msgAndArgs ...interface{}) bool {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
+
+ funcDidPanic, panicValue, panickedStack := didPanic(f)
+ if !funcDidPanic {
+ return Fail(t, fmt.Sprintf("func %#v should panic\n\tPanic value:\t%#v", f, panicValue), msgAndArgs...)
+ }
+ panicErr, ok := panicValue.(error)
+ if !ok || panicErr.Error() != errString {
+ return Fail(t, fmt.Sprintf("func %#v should panic with error message:\t%#v\n\tPanic value:\t%#v\n\tPanic stack:\t%s", f, errString, panicValue, panickedStack), msgAndArgs...)
}
return true
@@ -965,8 +1030,8 @@ func NotPanics(t TestingT, f PanicTestFunc, msgAndArgs ...interface{}) bool {
h.Helper()
}
- if funcDidPanic, panicValue := didPanic(f); funcDidPanic {
- return Fail(t, fmt.Sprintf("func %#v should not panic\n\tPanic value:\t%v", f, panicValue), msgAndArgs...)
+ if funcDidPanic, panicValue, panickedStack := didPanic(f); funcDidPanic {
+ return Fail(t, fmt.Sprintf("func %#v should not panic\n\tPanic value:\t%v\n\tPanic stack:\t%s", f, panicValue, panickedStack), msgAndArgs...)
}
return true
@@ -1026,7 +1091,7 @@ func toFloat(x interface{}) (float64, bool) {
// InDelta asserts that the two numerals are within delta of each other.
//
-// assert.InDelta(t, math.Pi, (22 / 7.0), 0.01)
+// assert.InDelta(t, math.Pi, 22/7.0, 0.01)
func InDelta(t TestingT, expected, actual interface{}, delta float64, msgAndArgs ...interface{}) bool {
if h, ok := t.(tHelper); ok {
h.Helper()
@@ -1314,7 +1379,8 @@ func NotZero(t TestingT, i interface{}, msgAndArgs ...interface{}) bool {
return true
}
-// FileExists checks whether a file exists in the given path. It also fails if the path points to a directory or there is an error when trying to check the file.
+// FileExists checks whether a file exists in the given path. It also fails if
+// the path points to a directory or there is an error when trying to check the file.
func FileExists(t TestingT, path string, msgAndArgs ...interface{}) bool {
if h, ok := t.(tHelper); ok {
h.Helper()
@@ -1332,7 +1398,24 @@ func FileExists(t TestingT, path string, msgAndArgs ...interface{}) bool {
return true
}
-// DirExists checks whether a directory exists in the given path. It also fails if the path is a file rather a directory or there is an error checking whether it exists.
+// NoFileExists checks whether a file does not exist in a given path. It fails
+// if the path points to an existing _file_ only.
+func NoFileExists(t TestingT, path string, msgAndArgs ...interface{}) bool {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
+ info, err := os.Lstat(path)
+ if err != nil {
+ return true
+ }
+ if info.IsDir() {
+ return true
+ }
+ return Fail(t, fmt.Sprintf("file %q exists", path), msgAndArgs...)
+}
+
+// DirExists checks whether a directory exists in the given path. It also fails
+// if the path is a file rather a directory or there is an error checking whether it exists.
func DirExists(t TestingT, path string, msgAndArgs ...interface{}) bool {
if h, ok := t.(tHelper); ok {
h.Helper()
@@ -1350,6 +1433,25 @@ func DirExists(t TestingT, path string, msgAndArgs ...interface{}) bool {
return true
}
+// NoDirExists checks whether a directory does not exist in the given path.
+// It fails if the path points to an existing _directory_ only.
+func NoDirExists(t TestingT, path string, msgAndArgs ...interface{}) bool {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
+ info, err := os.Lstat(path)
+ if err != nil {
+ if os.IsNotExist(err) {
+ return true
+ }
+ return true
+ }
+ if !info.IsDir() {
+ return true
+ }
+ return Fail(t, fmt.Sprintf("directory %q exists", path), msgAndArgs...)
+}
+
// JSONEq asserts that two JSON strings are equivalent.
//
// assert.JSONEq(t, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`)
@@ -1439,15 +1541,6 @@ func diff(expected interface{}, actual interface{}) string {
return "\n\nDiff:\n" + diff
}
-// validateEqualArgs checks whether provided arguments can be safely used in the
-// Equal/NotEqual functions.
-func validateEqualArgs(expected, actual interface{}) error {
- if isFunction(expected) || isFunction(actual) {
- return errors.New("cannot take func type as argument")
- }
- return nil
-}
-
func isFunction(arg interface{}) bool {
if arg == nil {
return false
@@ -1475,24 +1568,59 @@ func Eventually(t TestingT, condition func() bool, waitFor time.Duration, tick t
h.Helper()
}
+ ch := make(chan bool, 1)
+
timer := time.NewTimer(waitFor)
- ticker := time.NewTicker(tick)
- checkPassed := make(chan bool)
defer timer.Stop()
+
+ ticker := time.NewTicker(tick)
defer ticker.Stop()
- defer close(checkPassed)
- for {
+
+ for tick := ticker.C; ; {
select {
case <-timer.C:
return Fail(t, "Condition never satisfied", msgAndArgs...)
- case result := <-checkPassed:
- if result {
+ case <-tick:
+ tick = nil
+ go func() { ch <- condition() }()
+ case v := <-ch:
+ if v {
return true
}
- case <-ticker.C:
- go func() {
- checkPassed <- condition()
- }()
+ tick = ticker.C
+ }
+ }
+}
+
+// Never asserts that the given condition doesn't satisfy in waitFor time,
+// periodically checking the target function each tick.
+//
+// assert.Never(t, func() bool { return false; }, time.Second, 10*time.Millisecond)
+func Never(t TestingT, condition func() bool, waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) bool {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
+
+ ch := make(chan bool, 1)
+
+ timer := time.NewTimer(waitFor)
+ defer timer.Stop()
+
+ ticker := time.NewTicker(tick)
+ defer ticker.Stop()
+
+ for tick := ticker.C; ; {
+ select {
+ case <-timer.C:
+ return true
+ case <-tick:
+ tick = nil
+ go func() { ch <- condition() }()
+ case v := <-ch:
+ if v {
+ return Fail(t, "Condition satisfied", msgAndArgs...)
+ }
+ tick = ticker.C
}
}
}
diff --git a/vendor/github.com/stretchr/testify/assert/forward_assertions.go b/vendor/github.com/stretchr/testify/assert/forward_assertions.go
index 9ad56851d..df189d234 100644
--- a/vendor/github.com/stretchr/testify/assert/forward_assertions.go
+++ b/vendor/github.com/stretchr/testify/assert/forward_assertions.go
@@ -13,4 +13,4 @@ func New(t TestingT) *Assertions {
}
}
-//go:generate go run ../_codegen/main.go -output-package=assert -template=assertion_forward.go.tmpl -include-format-funcs
+//go:generate sh -c "cd ../_codegen && go build && cd - && ../_codegen/_codegen -output-package=assert -template=assertion_forward.go.tmpl -include-format-funcs"
diff --git a/vendor/github.com/stretchr/testify/require/forward_requirements.go b/vendor/github.com/stretchr/testify/require/forward_requirements.go
index ac71d4058..1dcb2338c 100644
--- a/vendor/github.com/stretchr/testify/require/forward_requirements.go
+++ b/vendor/github.com/stretchr/testify/require/forward_requirements.go
@@ -13,4 +13,4 @@ func New(t TestingT) *Assertions {
}
}
-//go:generate go run ../_codegen/main.go -output-package=require -template=require_forward.go.tmpl -include-format-funcs
+//go:generate sh -c "cd ../_codegen && go build && cd - && ../_codegen/_codegen -output-package=require -template=require_forward.go.tmpl -include-format-funcs"
diff --git a/vendor/github.com/stretchr/testify/require/require.go b/vendor/github.com/stretchr/testify/require/require.go
index c5903f5db..cf6c7b566 100644
--- a/vendor/github.com/stretchr/testify/require/require.go
+++ b/vendor/github.com/stretchr/testify/require/require.go
@@ -66,7 +66,8 @@ func Containsf(t TestingT, s interface{}, contains interface{}, msg string, args
t.FailNow()
}
-// DirExists checks whether a directory exists in the given path. It also fails if the path is a file rather a directory or there is an error checking whether it exists.
+// DirExists checks whether a directory exists in the given path. It also fails
+// if the path is a file rather a directory or there is an error checking whether it exists.
func DirExists(t TestingT, path string, msgAndArgs ...interface{}) {
if h, ok := t.(tHelper); ok {
h.Helper()
@@ -77,7 +78,8 @@ func DirExists(t TestingT, path string, msgAndArgs ...interface{}) {
t.FailNow()
}
-// DirExistsf checks whether a directory exists in the given path. It also fails if the path is a file rather a directory or there is an error checking whether it exists.
+// DirExistsf checks whether a directory exists in the given path. It also fails
+// if the path is a file rather a directory or there is an error checking whether it exists.
func DirExistsf(t TestingT, path string, msg string, args ...interface{}) {
if h, ok := t.(tHelper); ok {
h.Helper()
@@ -275,12 +277,12 @@ func Errorf(t TestingT, err error, msg string, args ...interface{}) {
//
// assert.Eventually(t, func() bool { return true; }, time.Second, 10*time.Millisecond)
func Eventually(t TestingT, condition func() bool, waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) {
- if assert.Eventually(t, condition, waitFor, tick, msgAndArgs...) {
- return
- }
if h, ok := t.(tHelper); ok {
h.Helper()
}
+ if assert.Eventually(t, condition, waitFor, tick, msgAndArgs...) {
+ return
+ }
t.FailNow()
}
@@ -289,12 +291,12 @@ func Eventually(t TestingT, condition func() bool, waitFor time.Duration, tick t
//
// assert.Eventuallyf(t, func() bool { return true; }, time.Second, 10*time.Millisecond, "error message %s", "formatted")
func Eventuallyf(t TestingT, condition func() bool, waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) {
- if assert.Eventuallyf(t, condition, waitFor, tick, msg, args...) {
- return
- }
if h, ok := t.(tHelper); ok {
h.Helper()
}
+ if assert.Eventuallyf(t, condition, waitFor, tick, msg, args...) {
+ return
+ }
t.FailNow()
}
@@ -394,7 +396,8 @@ func Falsef(t TestingT, value bool, msg string, args ...interface{}) {
t.FailNow()
}
-// FileExists checks whether a file exists in the given path. It also fails if the path points to a directory or there is an error when trying to check the file.
+// FileExists checks whether a file exists in the given path. It also fails if
+// the path points to a directory or there is an error when trying to check the file.
func FileExists(t TestingT, path string, msgAndArgs ...interface{}) {
if h, ok := t.(tHelper); ok {
h.Helper()
@@ -405,7 +408,8 @@ func FileExists(t TestingT, path string, msgAndArgs ...interface{}) {
t.FailNow()
}
-// FileExistsf checks whether a file exists in the given path. It also fails if the path points to a directory or there is an error when trying to check the file.
+// FileExistsf checks whether a file exists in the given path. It also fails if
+// the path points to a directory or there is an error when trying to check the file.
func FileExistsf(t TestingT, path string, msg string, args ...interface{}) {
if h, ok := t.(tHelper); ok {
h.Helper()
@@ -660,7 +664,7 @@ func Implementsf(t TestingT, interfaceObject interface{}, object interface{}, ms
// InDelta asserts that the two numerals are within delta of each other.
//
-// assert.InDelta(t, math.Pi, (22 / 7.0), 0.01)
+// assert.InDelta(t, math.Pi, 22/7.0, 0.01)
func InDelta(t TestingT, expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) {
if h, ok := t.(tHelper); ok {
h.Helper()
@@ -717,7 +721,7 @@ func InDeltaSlicef(t TestingT, expected interface{}, actual interface{}, delta f
// InDeltaf asserts that the two numerals are within delta of each other.
//
-// assert.InDeltaf(t, math.Pi, (22 / 7.0, "error message %s", "formatted"), 0.01)
+// assert.InDeltaf(t, math.Pi, 22/7.0, 0.01, "error message %s", "formatted")
func InDeltaf(t TestingT, expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) {
if h, ok := t.(tHelper); ok {
h.Helper()
@@ -820,28 +824,6 @@ func JSONEqf(t TestingT, expected string, actual string, msg string, args ...int
t.FailNow()
}
-// YAMLEq asserts that two YAML strings are equivalent.
-func YAMLEq(t TestingT, expected string, actual string, msgAndArgs ...interface{}) {
- if h, ok := t.(tHelper); ok {
- h.Helper()
- }
- if assert.YAMLEq(t, expected, actual, msgAndArgs...) {
- return
- }
- t.FailNow()
-}
-
-// YAMLEqf asserts that two YAML strings are equivalent.
-func YAMLEqf(t TestingT, expected string, actual string, msg string, args ...interface{}) {
- if h, ok := t.(tHelper); ok {
- h.Helper()
- }
- if assert.YAMLEqf(t, expected, actual, msg, args...) {
- return
- }
- t.FailNow()
-}
-
// Len asserts that the specified object has specific length.
// Len also fails if the object has a type that len() not accept.
//
@@ -932,6 +914,34 @@ func Lessf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...inter
t.FailNow()
}
+// Never asserts that the given condition doesn't satisfy in waitFor time,
+// periodically checking the target function each tick.
+//
+// assert.Never(t, func() bool { return false; }, time.Second, 10*time.Millisecond)
+func Never(t TestingT, condition func() bool, waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
+ if assert.Never(t, condition, waitFor, tick, msgAndArgs...) {
+ return
+ }
+ t.FailNow()
+}
+
+// Neverf asserts that the given condition doesn't satisfy in waitFor time,
+// periodically checking the target function each tick.
+//
+// assert.Neverf(t, func() bool { return false; }, time.Second, 10*time.Millisecond, "error message %s", "formatted")
+func Neverf(t TestingT, condition func() bool, waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
+ if assert.Neverf(t, condition, waitFor, tick, msg, args...) {
+ return
+ }
+ t.FailNow()
+}
+
// Nil asserts that the specified object is nil.
//
// assert.Nil(t, err)
@@ -958,6 +968,30 @@ func Nilf(t TestingT, object interface{}, msg string, args ...interface{}) {
t.FailNow()
}
+// NoDirExists checks whether a directory does not exist in the given path.
+// It fails if the path points to an existing _directory_ only.
+func NoDirExists(t TestingT, path string, msgAndArgs ...interface{}) {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
+ if assert.NoDirExists(t, path, msgAndArgs...) {
+ return
+ }
+ t.FailNow()
+}
+
+// NoDirExistsf checks whether a directory does not exist in the given path.
+// It fails if the path points to an existing _directory_ only.
+func NoDirExistsf(t TestingT, path string, msg string, args ...interface{}) {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
+ if assert.NoDirExistsf(t, path, msg, args...) {
+ return
+ }
+ t.FailNow()
+}
+
// NoError asserts that a function returned no error (i.e. `nil`).
//
// actualObj, err := SomeFunction()
@@ -990,6 +1024,30 @@ func NoErrorf(t TestingT, err error, msg string, args ...interface{}) {
t.FailNow()
}
+// NoFileExists checks whether a file does not exist in a given path. It fails
+// if the path points to an existing _file_ only.
+func NoFileExists(t TestingT, path string, msgAndArgs ...interface{}) {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
+ if assert.NoFileExists(t, path, msgAndArgs...) {
+ return
+ }
+ t.FailNow()
+}
+
+// NoFileExistsf checks whether a file does not exist in a given path. It fails
+// if the path points to an existing _file_ only.
+func NoFileExistsf(t TestingT, path string, msg string, args ...interface{}) {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
+ if assert.NoFileExistsf(t, path, msg, args...) {
+ return
+ }
+ t.FailNow()
+}
+
// NotContains asserts that the specified string, list(array, slice...) or map does NOT contain the
// specified substring or element.
//
@@ -1166,6 +1224,38 @@ func NotRegexpf(t TestingT, rx interface{}, str interface{}, msg string, args ..
t.FailNow()
}
+// NotSame asserts that two pointers do not reference the same object.
+//
+// assert.NotSame(t, ptr1, ptr2)
+//
+// Both arguments must be pointer variables. Pointer variable sameness is
+// determined based on the equality of both type and value.
+func NotSame(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
+ if assert.NotSame(t, expected, actual, msgAndArgs...) {
+ return
+ }
+ t.FailNow()
+}
+
+// NotSamef asserts that two pointers do not reference the same object.
+//
+// assert.NotSamef(t, ptr1, ptr2, "error message %s", "formatted")
+//
+// Both arguments must be pointer variables. Pointer variable sameness is
+// determined based on the equality of both type and value.
+func NotSamef(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
+ if assert.NotSamef(t, expected, actual, msg, args...) {
+ return
+ }
+ t.FailNow()
+}
+
// NotSubset asserts that the specified list(array, slice...) contains not all
// elements given in the specified subset(array, slice...).
//
@@ -1229,6 +1319,36 @@ func Panics(t TestingT, f assert.PanicTestFunc, msgAndArgs ...interface{}) {
t.FailNow()
}
+// PanicsWithError asserts that the code inside the specified PanicTestFunc
+// panics, and that the recovered panic value is an error that satisfies the
+// EqualError comparison.
+//
+// assert.PanicsWithError(t, "crazy error", func(){ GoCrazy() })
+func PanicsWithError(t TestingT, errString string, f assert.PanicTestFunc, msgAndArgs ...interface{}) {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
+ if assert.PanicsWithError(t, errString, f, msgAndArgs...) {
+ return
+ }
+ t.FailNow()
+}
+
+// PanicsWithErrorf asserts that the code inside the specified PanicTestFunc
+// panics, and that the recovered panic value is an error that satisfies the
+// EqualError comparison.
+//
+// assert.PanicsWithErrorf(t, "crazy error", func(){ GoCrazy() }, "error message %s", "formatted")
+func PanicsWithErrorf(t TestingT, errString string, f assert.PanicTestFunc, msg string, args ...interface{}) {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
+ if assert.PanicsWithErrorf(t, errString, f, msg, args...) {
+ return
+ }
+ t.FailNow()
+}
+
// PanicsWithValue asserts that the code inside the specified PanicTestFunc panics, and that
// the recovered panic value equals the expected panic value.
//
@@ -1410,6 +1530,28 @@ func WithinDurationf(t TestingT, expected time.Time, actual time.Time, delta tim
t.FailNow()
}
+// YAMLEq asserts that two YAML strings are equivalent.
+func YAMLEq(t TestingT, expected string, actual string, msgAndArgs ...interface{}) {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
+ if assert.YAMLEq(t, expected, actual, msgAndArgs...) {
+ return
+ }
+ t.FailNow()
+}
+
+// YAMLEqf asserts that two YAML strings are equivalent.
+func YAMLEqf(t TestingT, expected string, actual string, msg string, args ...interface{}) {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
+ if assert.YAMLEqf(t, expected, actual, msg, args...) {
+ return
+ }
+ t.FailNow()
+}
+
// Zero asserts that i is the zero value for its type.
func Zero(t TestingT, i interface{}, msgAndArgs ...interface{}) {
if h, ok := t.(tHelper); ok {
diff --git a/vendor/github.com/stretchr/testify/require/require_forward.go b/vendor/github.com/stretchr/testify/require/require_forward.go
index 804fae035..5aac226df 100644
--- a/vendor/github.com/stretchr/testify/require/require_forward.go
+++ b/vendor/github.com/stretchr/testify/require/require_forward.go
@@ -54,7 +54,8 @@ func (a *Assertions) Containsf(s interface{}, contains interface{}, msg string,
Containsf(a.t, s, contains, msg, args...)
}
-// DirExists checks whether a directory exists in the given path. It also fails if the path is a file rather a directory or there is an error checking whether it exists.
+// DirExists checks whether a directory exists in the given path. It also fails
+// if the path is a file rather a directory or there is an error checking whether it exists.
func (a *Assertions) DirExists(path string, msgAndArgs ...interface{}) {
if h, ok := a.t.(tHelper); ok {
h.Helper()
@@ -62,7 +63,8 @@ func (a *Assertions) DirExists(path string, msgAndArgs ...interface{}) {
DirExists(a.t, path, msgAndArgs...)
}
-// DirExistsf checks whether a directory exists in the given path. It also fails if the path is a file rather a directory or there is an error checking whether it exists.
+// DirExistsf checks whether a directory exists in the given path. It also fails
+// if the path is a file rather a directory or there is an error checking whether it exists.
func (a *Assertions) DirExistsf(path string, msg string, args ...interface{}) {
if h, ok := a.t.(tHelper); ok {
h.Helper()
@@ -310,7 +312,8 @@ func (a *Assertions) Falsef(value bool, msg string, args ...interface{}) {
Falsef(a.t, value, msg, args...)
}
-// FileExists checks whether a file exists in the given path. It also fails if the path points to a directory or there is an error when trying to check the file.
+// FileExists checks whether a file exists in the given path. It also fails if
+// the path points to a directory or there is an error when trying to check the file.
func (a *Assertions) FileExists(path string, msgAndArgs ...interface{}) {
if h, ok := a.t.(tHelper); ok {
h.Helper()
@@ -318,7 +321,8 @@ func (a *Assertions) FileExists(path string, msgAndArgs ...interface{}) {
FileExists(a.t, path, msgAndArgs...)
}
-// FileExistsf checks whether a file exists in the given path. It also fails if the path points to a directory or there is an error when trying to check the file.
+// FileExistsf checks whether a file exists in the given path. It also fails if
+// the path points to a directory or there is an error when trying to check the file.
func (a *Assertions) FileExistsf(path string, msg string, args ...interface{}) {
if h, ok := a.t.(tHelper); ok {
h.Helper()
@@ -522,7 +526,7 @@ func (a *Assertions) Implementsf(interfaceObject interface{}, object interface{}
// InDelta asserts that the two numerals are within delta of each other.
//
-// a.InDelta(math.Pi, (22 / 7.0), 0.01)
+// a.InDelta(math.Pi, 22/7.0, 0.01)
func (a *Assertions) InDelta(expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) {
if h, ok := a.t.(tHelper); ok {
h.Helper()
@@ -564,7 +568,7 @@ func (a *Assertions) InDeltaSlicef(expected interface{}, actual interface{}, del
// InDeltaf asserts that the two numerals are within delta of each other.
//
-// a.InDeltaf(math.Pi, (22 / 7.0, "error message %s", "formatted"), 0.01)
+// a.InDeltaf(math.Pi, 22/7.0, 0.01, "error message %s", "formatted")
func (a *Assertions) InDeltaf(expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) {
if h, ok := a.t.(tHelper); ok {
h.Helper()
@@ -640,22 +644,6 @@ func (a *Assertions) JSONEqf(expected string, actual string, msg string, args ..
JSONEqf(a.t, expected, actual, msg, args...)
}
-// YAMLEq asserts that two YAML strings are equivalent.
-func (a *Assertions) YAMLEq(expected string, actual string, msgAndArgs ...interface{}) {
- if h, ok := a.t.(tHelper); ok {
- h.Helper()
- }
- YAMLEq(a.t, expected, actual, msgAndArgs...)
-}
-
-// YAMLEqf asserts that two YAML strings are equivalent.
-func (a *Assertions) YAMLEqf(expected string, actual string, msg string, args ...interface{}) {
- if h, ok := a.t.(tHelper); ok {
- h.Helper()
- }
- YAMLEqf(a.t, expected, actual, msg, args...)
-}
-
// Len asserts that the specified object has specific length.
// Len also fails if the object has a type that len() not accept.
//
@@ -728,6 +716,28 @@ func (a *Assertions) Lessf(e1 interface{}, e2 interface{}, msg string, args ...i
Lessf(a.t, e1, e2, msg, args...)
}
+// Never asserts that the given condition doesn't satisfy in waitFor time,
+// periodically checking the target function each tick.
+//
+// a.Never(func() bool { return false; }, time.Second, 10*time.Millisecond)
+func (a *Assertions) Never(condition func() bool, waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
+ Never(a.t, condition, waitFor, tick, msgAndArgs...)
+}
+
+// Neverf asserts that the given condition doesn't satisfy in waitFor time,
+// periodically checking the target function each tick.
+//
+// a.Neverf(func() bool { return false; }, time.Second, 10*time.Millisecond, "error message %s", "formatted")
+func (a *Assertions) Neverf(condition func() bool, waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
+ Neverf(a.t, condition, waitFor, tick, msg, args...)
+}
+
// Nil asserts that the specified object is nil.
//
// a.Nil(err)
@@ -748,6 +758,24 @@ func (a *Assertions) Nilf(object interface{}, msg string, args ...interface{}) {
Nilf(a.t, object, msg, args...)
}
+// NoDirExists checks whether a directory does not exist in the given path.
+// It fails if the path points to an existing _directory_ only.
+func (a *Assertions) NoDirExists(path string, msgAndArgs ...interface{}) {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
+ NoDirExists(a.t, path, msgAndArgs...)
+}
+
+// NoDirExistsf checks whether a directory does not exist in the given path.
+// It fails if the path points to an existing _directory_ only.
+func (a *Assertions) NoDirExistsf(path string, msg string, args ...interface{}) {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
+ NoDirExistsf(a.t, path, msg, args...)
+}
+
// NoError asserts that a function returned no error (i.e. `nil`).
//
// actualObj, err := SomeFunction()
@@ -774,6 +802,24 @@ func (a *Assertions) NoErrorf(err error, msg string, args ...interface{}) {
NoErrorf(a.t, err, msg, args...)
}
+// NoFileExists checks whether a file does not exist in a given path. It fails
+// if the path points to an existing _file_ only.
+func (a *Assertions) NoFileExists(path string, msgAndArgs ...interface{}) {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
+ NoFileExists(a.t, path, msgAndArgs...)
+}
+
+// NoFileExistsf checks whether a file does not exist in a given path. It fails
+// if the path points to an existing _file_ only.
+func (a *Assertions) NoFileExistsf(path string, msg string, args ...interface{}) {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
+ NoFileExistsf(a.t, path, msg, args...)
+}
+
// NotContains asserts that the specified string, list(array, slice...) or map does NOT contain the
// specified substring or element.
//
@@ -914,6 +960,32 @@ func (a *Assertions) NotRegexpf(rx interface{}, str interface{}, msg string, arg
NotRegexpf(a.t, rx, str, msg, args...)
}
+// NotSame asserts that two pointers do not reference the same object.
+//
+// a.NotSame(ptr1, ptr2)
+//
+// Both arguments must be pointer variables. Pointer variable sameness is
+// determined based on the equality of both type and value.
+func (a *Assertions) NotSame(expected interface{}, actual interface{}, msgAndArgs ...interface{}) {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
+ NotSame(a.t, expected, actual, msgAndArgs...)
+}
+
+// NotSamef asserts that two pointers do not reference the same object.
+//
+// a.NotSamef(ptr1, ptr2, "error message %s", "formatted")
+//
+// Both arguments must be pointer variables. Pointer variable sameness is
+// determined based on the equality of both type and value.
+func (a *Assertions) NotSamef(expected interface{}, actual interface{}, msg string, args ...interface{}) {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
+ NotSamef(a.t, expected, actual, msg, args...)
+}
+
// NotSubset asserts that the specified list(array, slice...) contains not all
// elements given in the specified subset(array, slice...).
//
@@ -962,6 +1034,30 @@ func (a *Assertions) Panics(f assert.PanicTestFunc, msgAndArgs ...interface{}) {
Panics(a.t, f, msgAndArgs...)
}
+// PanicsWithError asserts that the code inside the specified PanicTestFunc
+// panics, and that the recovered panic value is an error that satisfies the
+// EqualError comparison.
+//
+// a.PanicsWithError("crazy error", func(){ GoCrazy() })
+func (a *Assertions) PanicsWithError(errString string, f assert.PanicTestFunc, msgAndArgs ...interface{}) {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
+ PanicsWithError(a.t, errString, f, msgAndArgs...)
+}
+
+// PanicsWithErrorf asserts that the code inside the specified PanicTestFunc
+// panics, and that the recovered panic value is an error that satisfies the
+// EqualError comparison.
+//
+// a.PanicsWithErrorf("crazy error", func(){ GoCrazy() }, "error message %s", "formatted")
+func (a *Assertions) PanicsWithErrorf(errString string, f assert.PanicTestFunc, msg string, args ...interface{}) {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
+ PanicsWithErrorf(a.t, errString, f, msg, args...)
+}
+
// PanicsWithValue asserts that the code inside the specified PanicTestFunc panics, and that
// the recovered panic value equals the expected panic value.
//
@@ -1104,6 +1200,22 @@ func (a *Assertions) WithinDurationf(expected time.Time, actual time.Time, delta
WithinDurationf(a.t, expected, actual, delta, msg, args...)
}
+// YAMLEq asserts that two YAML strings are equivalent.
+func (a *Assertions) YAMLEq(expected string, actual string, msgAndArgs ...interface{}) {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
+ YAMLEq(a.t, expected, actual, msgAndArgs...)
+}
+
+// YAMLEqf asserts that two YAML strings are equivalent.
+func (a *Assertions) YAMLEqf(expected string, actual string, msg string, args ...interface{}) {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
+ YAMLEqf(a.t, expected, actual, msg, args...)
+}
+
// Zero asserts that i is the zero value for its type.
func (a *Assertions) Zero(i interface{}, msgAndArgs ...interface{}) {
if h, ok := a.t.(tHelper); ok {
diff --git a/vendor/github.com/stretchr/testify/require/requirements.go b/vendor/github.com/stretchr/testify/require/requirements.go
index 6b85c5ece..91772dfeb 100644
--- a/vendor/github.com/stretchr/testify/require/requirements.go
+++ b/vendor/github.com/stretchr/testify/require/requirements.go
@@ -26,4 +26,4 @@ type BoolAssertionFunc func(TestingT, bool, ...interface{})
// for table driven tests.
type ErrorAssertionFunc func(TestingT, error, ...interface{})
-//go:generate go run ../_codegen/main.go -output-package=require -template=require.go.tmpl -include-format-funcs
+//go:generate sh -c "cd ../_codegen && go build && cd - && ../_codegen/_codegen -output-package=require -template=require.go.tmpl -include-format-funcs"
diff --git a/vendor/github.com/uber/jaeger-lib/metrics/metrics.go b/vendor/github.com/uber/jaeger-lib/metrics/metrics.go
index 0c6396888..0df0c662e 100644
--- a/vendor/github.com/uber/jaeger-lib/metrics/metrics.go
+++ b/vendor/github.com/uber/jaeger-lib/metrics/metrics.go
@@ -37,7 +37,7 @@ func MustInit(metrics interface{}, factory Factory, globalTags map[string]string
}
}
-// Init does the same as Init, but returns an error instead of
+// Init does the same as MustInit, but returns an error instead of
// panicking.
func Init(m interface{}, factory Factory, globalTags map[string]string) error {
// Allow user to opt out of reporting metrics by passing in nil.
diff --git a/vendor/github.com/vbauerster/mpb/v4/bar_option.go b/vendor/github.com/vbauerster/mpb/v4/bar_option.go
index bb79ac6a4..7fb152562 100644
--- a/vendor/github.com/vbauerster/mpb/v4/bar_option.go
+++ b/vendor/github.com/vbauerster/mpb/v4/bar_option.go
@@ -10,11 +10,10 @@ import (
// BarOption is a function option which changes the default behavior of a bar.
type BarOption func(*bState)
-type mergeWrapper interface {
- MergeUnwrap() []decor.Decorator
-}
-
func (s *bState) addDecorators(dest *[]decor.Decorator, decorators ...decor.Decorator) {
+ type mergeWrapper interface {
+ MergeUnwrap() []decor.Decorator
+ }
for _, decorator := range decorators {
if mw, ok := decorator.(mergeWrapper); ok {
*dest = append(*dest, mw.MergeUnwrap()...)
diff --git a/vendor/github.com/vbauerster/mpb/v4/decor/decorator.go b/vendor/github.com/vbauerster/mpb/v4/decor/decorator.go
index 5c0d16880..2271cbbe1 100644
--- a/vendor/github.com/vbauerster/mpb/v4/decor/decorator.go
+++ b/vendor/github.com/vbauerster/mpb/v4/decor/decorator.go
@@ -4,6 +4,8 @@ import (
"fmt"
"time"
"unicode/utf8"
+
+ "github.com/acarl005/stripansi"
)
const (
@@ -117,25 +119,29 @@ var (
// W represents width and C represents bit set of width related config.
// A decorator should embed WC, to enable width synchronization.
type WC struct {
- W int
- C int
- dynFormat string
- staticFormat string
- wsync chan int
+ W int
+ C int
+ dynFormat string
+ wsync chan int
}
// FormatMsg formats final message according to WC.W and WC.C.
// Should be called by any Decorator implementation.
func (wc *WC) FormatMsg(msg string) string {
+ var format string
+ runeCount := utf8.RuneCountInString(stripansi.Strip(msg))
+ ansiCount := utf8.RuneCountInString(msg) - runeCount
if (wc.C & DSyncWidth) != 0 {
- wc.wsync <- utf8.RuneCountInString(msg)
- max := <-wc.wsync
if (wc.C & DextraSpace) != 0 {
- max++
+ runeCount++
}
- return fmt.Sprintf(fmt.Sprintf(wc.dynFormat, max), msg)
+ wc.wsync <- runeCount
+ max := <-wc.wsync
+ format = fmt.Sprintf(wc.dynFormat, ansiCount+max)
+ } else {
+ format = fmt.Sprintf(wc.dynFormat, ansiCount+wc.W)
}
- return fmt.Sprintf(wc.staticFormat, msg)
+ return fmt.Sprintf(format, msg)
}
// Init initializes width related config.
@@ -145,7 +151,6 @@ func (wc *WC) Init() WC {
wc.dynFormat += "-"
}
wc.dynFormat += "%ds"
- wc.staticFormat = fmt.Sprintf(wc.dynFormat, wc.W)
if (wc.C & DSyncWidth) != 0 {
// it's deliberate choice to override wsync on each Init() call,
// this way globals like WCSyncSpace can be reused
diff --git a/vendor/github.com/vbauerster/mpb/v4/decor/merge.go b/vendor/github.com/vbauerster/mpb/v4/decor/merge.go
index fdf9e107b..723869209 100644
--- a/vendor/github.com/vbauerster/mpb/v4/decor/merge.go
+++ b/vendor/github.com/vbauerster/mpb/v4/decor/merge.go
@@ -2,6 +2,7 @@ package decor
import (
"fmt"
+ "strings"
"unicode/utf8"
)
@@ -28,10 +29,7 @@ func Merge(decorator Decorator, placeholders ...WC) Decorator {
if (wc.C & DSyncWidth) == 0 {
return decorator
}
- md.placeHolders[i] = &placeHolderDecorator{
- WC: wc.Init(),
- wch: make(chan int),
- }
+ md.placeHolders[i] = &placeHolderDecorator{wc.Init()}
}
return md
}
@@ -69,29 +67,40 @@ func (d *mergeDecorator) Base() Decorator {
func (d *mergeDecorator) Decor(st *Statistics) string {
msg := d.Decorator.Decor(st)
msgLen := utf8.RuneCountInString(msg)
-
- var space int
- for _, ph := range d.placeHolders {
- space += <-ph.wch
+ if (d.wc.C & DextraSpace) != 0 {
+ msgLen++
}
- d.wc.wsync <- msgLen - space
+ var total int
+ max := utf8.RuneCountInString(d.placeHolders[0].FormatMsg(""))
+ total += max
+ pw := (msgLen - max) / len(d.placeHolders)
+ rem := (msgLen - max) % len(d.placeHolders)
- max := <-d.wc.wsync
- if (d.wc.C & DextraSpace) != 0 {
- max++
+ var diff int
+ for i := 1; i < len(d.placeHolders); i++ {
+ ph := d.placeHolders[i]
+ width := pw - diff
+ if (ph.WC.C & DextraSpace) != 0 {
+ width--
+ if width < 0 {
+ width = 0
+ }
+ }
+ max = utf8.RuneCountInString(ph.FormatMsg(strings.Repeat(" ", width)))
+ total += max
+ diff = max - pw
}
- return fmt.Sprintf(fmt.Sprintf(d.wc.dynFormat, max+space), msg)
+
+ d.wc.wsync <- pw + rem
+ max = <-d.wc.wsync
+ return fmt.Sprintf(fmt.Sprintf(d.wc.dynFormat, max+total), msg)
}
type placeHolderDecorator struct {
WC
- wch chan int
}
-func (d *placeHolderDecorator) Decor(st *Statistics) string {
- go func() {
- d.wch <- utf8.RuneCountInString(d.FormatMsg(""))
- }()
+func (d *placeHolderDecorator) Decor(_ *Statistics) string {
return ""
}
diff --git a/vendor/github.com/vbauerster/mpb/v4/go.mod b/vendor/github.com/vbauerster/mpb/v4/go.mod
index 0c5ce51f1..9e7287d5d 100644
--- a/vendor/github.com/vbauerster/mpb/v4/go.mod
+++ b/vendor/github.com/vbauerster/mpb/v4/go.mod
@@ -2,6 +2,7 @@ module github.com/vbauerster/mpb/v4
require (
github.com/VividCortex/ewma v1.1.1
+ github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d
golang.org/x/crypto v0.0.0-20191112222119-e1110fd1c708
golang.org/x/sys v0.0.0-20191113165036-4c7a9d0fe056 // indirect
)
diff --git a/vendor/github.com/vbauerster/mpb/v4/go.sum b/vendor/github.com/vbauerster/mpb/v4/go.sum
index 94a9f1a28..5a1316274 100644
--- a/vendor/github.com/vbauerster/mpb/v4/go.sum
+++ b/vendor/github.com/vbauerster/mpb/v4/go.sum
@@ -1,5 +1,7 @@
github.com/VividCortex/ewma v1.1.1 h1:MnEK4VOv6n0RSY4vtRe3h11qjxL3+t0B8yOL8iMXdcM=
github.com/VividCortex/ewma v1.1.1/go.mod h1:2Tkkvm3sRDVXaiyucHiACn4cqf7DpdyLvmxzcbUokwA=
+github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d h1:licZJFw2RwpHMqeKTCYkitsPqHNxTmd4SNR5r94FGM8=
+github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d/go.mod h1:asat636LX7Bqt5lYEZ27JNDcqxfjdBQuJ/MM4CN/Lzo=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191112222119-e1110fd1c708 h1:pXVtWnwHkrWD9ru3sDxY/qFK/bfc0egRovX91EjWjf4=
golang.org/x/crypto v0.0.0-20191112222119-e1110fd1c708/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
diff --git a/vendor/github.com/vbauerster/mpb/v4/proxyreader.go b/vendor/github.com/vbauerster/mpb/v4/proxyreader.go
index 736142412..0e4b51f09 100644
--- a/vendor/github.com/vbauerster/mpb/v4/proxyreader.go
+++ b/vendor/github.com/vbauerster/mpb/v4/proxyreader.go
@@ -18,9 +18,7 @@ func (prox *proxyReader) Read(p []byte) (n int, err error) {
prox.iT = time.Now()
}
if err == io.EOF {
- go func() {
- prox.bar.SetTotal(0, true)
- }()
+ go prox.bar.SetTotal(0, true)
}
return
}
@@ -37,9 +35,7 @@ func (prox *proxyWriterTo) WriteTo(w io.Writer) (n int64, err error) {
prox.iT = time.Now()
}
if err == io.EOF {
- go func() {
- prox.bar.SetTotal(0, true)
- }()
+ go prox.bar.SetTotal(0, true)
}
return
}
diff --git a/vendor/github.com/xeipuuv/gojsonschema/.travis.yml b/vendor/github.com/xeipuuv/gojsonschema/.travis.yml
index 09ee789ca..36155164d 100644
--- a/vendor/github.com/xeipuuv/gojsonschema/.travis.yml
+++ b/vendor/github.com/xeipuuv/gojsonschema/.travis.yml
@@ -1,11 +1,8 @@
language: go
go:
- - "1.5"
- - "1.6"
- - "1.7"
- - "1.8"
- - "1.9"
- "1.10"
+ - "1.11"
+ - "1.12"
before_install:
- go get github.com/xeipuuv/gojsonreference
- go get github.com/xeipuuv/gojsonpointer
diff --git a/vendor/github.com/xeipuuv/gojsonschema/README.md b/vendor/github.com/xeipuuv/gojsonschema/README.md
index 24ca34744..758f26df0 100644
--- a/vendor/github.com/xeipuuv/gojsonschema/README.md
+++ b/vendor/github.com/xeipuuv/gojsonschema/README.md
@@ -1,5 +1,6 @@
[![GoDoc](https://godoc.org/github.com/xeipuuv/gojsonschema?status.svg)](https://godoc.org/github.com/xeipuuv/gojsonschema)
[![Build Status](https://travis-ci.org/xeipuuv/gojsonschema.svg)](https://travis-ci.org/xeipuuv/gojsonschema)
+[![Go Report Card](https://goreportcard.com/badge/github.com/xeipuuv/gojsonschema)](https://goreportcard.com/report/github.com/xeipuuv/gojsonschema)
# gojsonschema
@@ -343,7 +344,7 @@ Not all formats defined in draft-07 are available. Implemented formats are:
`email`, `uri` and `uri-reference` use the same validation code as their unicode counterparts `idn-email`, `iri` and `iri-reference`. If you rely on unicode support you should use the specific
unicode enabled formats for the sake of interoperability as other implementations might not support unicode in the regular formats.
-The validation code for `uri`, `idn-email` and their relatives use mostly standard library code. Go 1.5 and 1.6 contain some minor bugs with handling URIs and unicode. You are encouraged to use Go 1.7+ if you rely on these formats.
+The validation code for `uri`, `idn-email` and their relatives use mostly standard library code.
For repetitive or more complex formats, you can create custom format checkers and add them to gojsonschema like this:
diff --git a/vendor/github.com/xeipuuv/gojsonschema/draft.go b/vendor/github.com/xeipuuv/gojsonschema/draft.go
index bfde4a2e1..7a0123cc7 100644
--- a/vendor/github.com/xeipuuv/gojsonschema/draft.go
+++ b/vendor/github.com/xeipuuv/gojsonschema/draft.go
@@ -22,8 +22,10 @@ import (
"github.com/xeipuuv/gojsonreference"
)
+// Draft is a JSON-schema draft version
type Draft int
+// Supported Draft versions
const (
Draft4 Draft = 4
Draft6 Draft = 6
@@ -42,17 +44,17 @@ var drafts draftConfigs
func init() {
drafts = []draftConfig{
- draftConfig{
+ {
Version: Draft4,
MetaSchemaURL: "http://json-schema.org/draft-04/schema",
MetaSchema: `{"id":"http://json-schema.org/draft-04/schema#","$schema":"http://json-schema.org/draft-04/schema#","description":"Core schema meta-schema","definitions":{"schemaArray":{"type":"array","minItems":1,"items":{"$ref":"#"}},"positiveInteger":{"type":"integer","minimum":0},"positiveIntegerDefault0":{"allOf":[{"$ref":"#/definitions/positiveInteger"},{"default":0}]},"simpleTypes":{"enum":["array","boolean","integer","null","number","object","string"]},"stringArray":{"type":"array","items":{"type":"string"},"minItems":1,"uniqueItems":true}},"type":"object","properties":{"id":{"type":"string"},"$schema":{"type":"string"},"title":{"type":"string"},"description":{"type":"string"},"default":{},"multipleOf":{"type":"number","minimum":0,"exclusiveMinimum":true},"maximum":{"type":"number"},"exclusiveMaximum":{"type":"boolean","default":false},"minimum":{"type":"number"},"exclusiveMinimum":{"type":"boolean","default":false},"maxLength":{"$ref":"#/definitions/positiveInteger"},"minLength":{"$ref":"#/definitions/positiveIntegerDefault0"},"pattern":{"type":"string","format":"regex"},"additionalItems":{"anyOf":[{"type":"boolean"},{"$ref":"#"}],"default":{}},"items":{"anyOf":[{"$ref":"#"},{"$ref":"#/definitions/schemaArray"}],"default":{}},"maxItems":{"$ref":"#/definitions/positiveInteger"},"minItems":{"$ref":"#/definitions/positiveIntegerDefault0"},"uniqueItems":{"type":"boolean","default":false},"maxProperties":{"$ref":"#/definitions/positiveInteger"},"minProperties":{"$ref":"#/definitions/positiveIntegerDefault0"},"required":{"$ref":"#/definitions/stringArray"},"additionalProperties":{"anyOf":[{"type":"boolean"},{"$ref":"#"}],"default":{}},"definitions":{"type":"object","additionalProperties":{"$ref":"#"},"default":{}},"properties":{"type":"object","additionalProperties":{"$ref":"#"},"default":{}},"patternProperties":{"type":"object","additionalProperties":{"$ref":"#"},"default":{}},"dependencies":{"type":"object","additionalProperties":{"anyOf":[{"$ref":"#"},{"$ref":"#/definitions/stringArray"}]}},"enum":{"type":"array","minItems":1,"uniqueItems":true},"type":{"anyOf":[{"$ref":"#/definitions/simpleTypes"},{"type":"array","items":{"$ref":"#/definitions/simpleTypes"},"minItems":1,"uniqueItems":true}]},"format":{"type":"string"},"allOf":{"$ref":"#/definitions/schemaArray"},"anyOf":{"$ref":"#/definitions/schemaArray"},"oneOf":{"$ref":"#/definitions/schemaArray"},"not":{"$ref":"#"}},"dependencies":{"exclusiveMaximum":["maximum"],"exclusiveMinimum":["minimum"]},"default":{}}`,
},
- draftConfig{
+ {
Version: Draft6,
MetaSchemaURL: "http://json-schema.org/draft-06/schema",
MetaSchema: `{"$schema":"http://json-schema.org/draft-06/schema#","$id":"http://json-schema.org/draft-06/schema#","title":"Core schema meta-schema","definitions":{"schemaArray":{"type":"array","minItems":1,"items":{"$ref":"#"}},"nonNegativeInteger":{"type":"integer","minimum":0},"nonNegativeIntegerDefault0":{"allOf":[{"$ref":"#/definitions/nonNegativeInteger"},{"default":0}]},"simpleTypes":{"enum":["array","boolean","integer","null","number","object","string"]},"stringArray":{"type":"array","items":{"type":"string"},"uniqueItems":true,"default":[]}},"type":["object","boolean"],"properties":{"$id":{"type":"string","format":"uri-reference"},"$schema":{"type":"string","format":"uri"},"$ref":{"type":"string","format":"uri-reference"},"title":{"type":"string"},"description":{"type":"string"},"default":{},"examples":{"type":"array","items":{}},"multipleOf":{"type":"number","exclusiveMinimum":0},"maximum":{"type":"number"},"exclusiveMaximum":{"type":"number"},"minimum":{"type":"number"},"exclusiveMinimum":{"type":"number"},"maxLength":{"$ref":"#/definitions/nonNegativeInteger"},"minLength":{"$ref":"#/definitions/nonNegativeIntegerDefault0"},"pattern":{"type":"string","format":"regex"},"additionalItems":{"$ref":"#"},"items":{"anyOf":[{"$ref":"#"},{"$ref":"#/definitions/schemaArray"}],"default":{}},"maxItems":{"$ref":"#/definitions/nonNegativeInteger"},"minItems":{"$ref":"#/definitions/nonNegativeIntegerDefault0"},"uniqueItems":{"type":"boolean","default":false},"contains":{"$ref":"#"},"maxProperties":{"$ref":"#/definitions/nonNegativeInteger"},"minProperties":{"$ref":"#/definitions/nonNegativeIntegerDefault0"},"required":{"$ref":"#/definitions/stringArray"},"additionalProperties":{"$ref":"#"},"definitions":{"type":"object","additionalProperties":{"$ref":"#"},"default":{}},"properties":{"type":"object","additionalProperties":{"$ref":"#"},"default":{}},"patternProperties":{"type":"object","additionalProperties":{"$ref":"#"},"default":{}},"dependencies":{"type":"object","additionalProperties":{"anyOf":[{"$ref":"#"},{"$ref":"#/definitions/stringArray"}]}},"propertyNames":{"$ref":"#"},"const":{},"enum":{"type":"array","minItems":1,"uniqueItems":true},"type":{"anyOf":[{"$ref":"#/definitions/simpleTypes"},{"type":"array","items":{"$ref":"#/definitions/simpleTypes"},"minItems":1,"uniqueItems":true}]},"format":{"type":"string"},"allOf":{"$ref":"#/definitions/schemaArray"},"anyOf":{"$ref":"#/definitions/schemaArray"},"oneOf":{"$ref":"#/definitions/schemaArray"},"not":{"$ref":"#"}},"default":{}}`,
},
- draftConfig{
+ {
Version: Draft7,
MetaSchemaURL: "http://json-schema.org/draft-07/schema",
MetaSchema: `{"$schema":"http://json-schema.org/draft-07/schema#","$id":"http://json-schema.org/draft-07/schema#","title":"Core schema meta-schema","definitions":{"schemaArray":{"type":"array","minItems":1,"items":{"$ref":"#"}},"nonNegativeInteger":{"type":"integer","minimum":0},"nonNegativeIntegerDefault0":{"allOf":[{"$ref":"#/definitions/nonNegativeInteger"},{"default":0}]},"simpleTypes":{"enum":["array","boolean","integer","null","number","object","string"]},"stringArray":{"type":"array","items":{"type":"string"},"uniqueItems":true,"default":[]}},"type":["object","boolean"],"properties":{"$id":{"type":"string","format":"uri-reference"},"$schema":{"type":"string","format":"uri"},"$ref":{"type":"string","format":"uri-reference"},"$comment":{"type":"string"},"title":{"type":"string"},"description":{"type":"string"},"default":true,"readOnly":{"type":"boolean","default":false},"examples":{"type":"array","items":true},"multipleOf":{"type":"number","exclusiveMinimum":0},"maximum":{"type":"number"},"exclusiveMaximum":{"type":"number"},"minimum":{"type":"number"},"exclusiveMinimum":{"type":"number"},"maxLength":{"$ref":"#/definitions/nonNegativeInteger"},"minLength":{"$ref":"#/definitions/nonNegativeIntegerDefault0"},"pattern":{"type":"string","format":"regex"},"additionalItems":{"$ref":"#"},"items":{"anyOf":[{"$ref":"#"},{"$ref":"#/definitions/schemaArray"}],"default":true},"maxItems":{"$ref":"#/definitions/nonNegativeInteger"},"minItems":{"$ref":"#/definitions/nonNegativeIntegerDefault0"},"uniqueItems":{"type":"boolean","default":false},"contains":{"$ref":"#"},"maxProperties":{"$ref":"#/definitions/nonNegativeInteger"},"minProperties":{"$ref":"#/definitions/nonNegativeIntegerDefault0"},"required":{"$ref":"#/definitions/stringArray"},"additionalProperties":{"$ref":"#"},"definitions":{"type":"object","additionalProperties":{"$ref":"#"},"default":{}},"properties":{"type":"object","additionalProperties":{"$ref":"#"},"default":{}},"patternProperties":{"type":"object","additionalProperties":{"$ref":"#"},"propertyNames":{"format":"regex"},"default":{}},"dependencies":{"type":"object","additionalProperties":{"anyOf":[{"$ref":"#"},{"$ref":"#/definitions/stringArray"}]}},"propertyNames":{"$ref":"#"},"const":true,"enum":{"type":"array","items":true,"minItems":1,"uniqueItems":true},"type":{"anyOf":[{"$ref":"#/definitions/simpleTypes"},{"type":"array","items":{"$ref":"#/definitions/simpleTypes"},"minItems":1,"uniqueItems":true}]},"format":{"type":"string"},"contentMediaType":{"type":"string"},"contentEncoding":{"type":"string"},"if":{"$ref":"#"},"then":{"$ref":"#"},"else":{"$ref":"#"},"allOf":{"$ref":"#/definitions/schemaArray"},"anyOf":{"$ref":"#/definitions/schemaArray"},"oneOf":{"$ref":"#/definitions/schemaArray"},"not":{"$ref":"#"}},"default":true}`,
diff --git a/vendor/github.com/xeipuuv/gojsonschema/errors.go b/vendor/github.com/xeipuuv/gojsonschema/errors.go
index 2f01a1c2c..e4e9814f3 100644
--- a/vendor/github.com/xeipuuv/gojsonschema/errors.go
+++ b/vendor/github.com/xeipuuv/gojsonschema/errors.go
@@ -6,7 +6,7 @@ import (
"text/template"
)
-var errorTemplates errorTemplate = errorTemplate{template.New("errors-new"), sync.RWMutex{}}
+var errorTemplates = errorTemplate{template.New("errors-new"), sync.RWMutex{}}
// template.Template is not thread-safe for writing, so some locking is done
// sync.RWMutex is used for efficiently locking when new templates are created
@@ -16,157 +16,194 @@ type errorTemplate struct {
}
type (
- // RequiredError. ErrorDetails: property string
+
+ // FalseError. ErrorDetails: -
+ FalseError struct {
+ ResultErrorFields
+ }
+
+ // RequiredError indicates that a required field is missing
+ // ErrorDetails: property string
RequiredError struct {
ResultErrorFields
}
- // InvalidTypeError. ErrorDetails: expected, given
+ // InvalidTypeError indicates that a field has the incorrect type
+ // ErrorDetails: expected, given
InvalidTypeError struct {
ResultErrorFields
}
- // NumberAnyOfError. ErrorDetails: -
+ // NumberAnyOfError is produced in case of a failing "anyOf" validation
+ // ErrorDetails: -
NumberAnyOfError struct {
ResultErrorFields
}
- // NumberOneOfError. ErrorDetails: -
+ // NumberOneOfError is produced in case of a failing "oneOf" validation
+ // ErrorDetails: -
NumberOneOfError struct {
ResultErrorFields
}
- // NumberAllOfError. ErrorDetails: -
+ // NumberAllOfError is produced in case of a failing "allOf" validation
+ // ErrorDetails: -
NumberAllOfError struct {
ResultErrorFields
}
- // NumberNotError. ErrorDetails: -
+ // NumberNotError is produced if a "not" validation failed
+ // ErrorDetails: -
NumberNotError struct {
ResultErrorFields
}
- // MissingDependencyError. ErrorDetails: dependency
+ // MissingDependencyError is produced in case of a "missing dependency" problem
+ // ErrorDetails: dependency
MissingDependencyError struct {
ResultErrorFields
}
- // InternalError. ErrorDetails: error
+ // InternalError indicates an internal error
+ // ErrorDetails: error
InternalError struct {
ResultErrorFields
}
- // ConstError. ErrorDetails: allowed
+ // ConstError indicates a const error
+ // ErrorDetails: allowed
ConstError struct {
ResultErrorFields
}
- // EnumError. ErrorDetails: allowed
+ // EnumError indicates an enum error
+ // ErrorDetails: allowed
EnumError struct {
ResultErrorFields
}
- // ArrayNoAdditionalItemsError. ErrorDetails: -
+ // ArrayNoAdditionalItemsError is produced if additional items were found, but not allowed
+ // ErrorDetails: -
ArrayNoAdditionalItemsError struct {
ResultErrorFields
}
- // ArrayMinItemsError. ErrorDetails: min
+ // ArrayMinItemsError is produced if an array contains less items than the allowed minimum
+ // ErrorDetails: min
ArrayMinItemsError struct {
ResultErrorFields
}
- // ArrayMaxItemsError. ErrorDetails: max
+ // ArrayMaxItemsError is produced if an array contains more items than the allowed maximum
+ // ErrorDetails: max
ArrayMaxItemsError struct {
ResultErrorFields
}
- // ItemsMustBeUniqueError. ErrorDetails: type, i, j
+ // ItemsMustBeUniqueError is produced if an array requires unique items, but contains non-unique items
+ // ErrorDetails: type, i, j
ItemsMustBeUniqueError struct {
ResultErrorFields
}
- // ArrayContainsError. ErrorDetails:
+ // ArrayContainsError is produced if an array contains invalid items
+ // ErrorDetails:
ArrayContainsError struct {
ResultErrorFields
}
- // ArrayMinPropertiesError. ErrorDetails: min
+ // ArrayMinPropertiesError is produced if an object contains less properties than the allowed minimum
+ // ErrorDetails: min
ArrayMinPropertiesError struct {
ResultErrorFields
}
- // ArrayMaxPropertiesError. ErrorDetails: max
+ // ArrayMaxPropertiesError is produced if an object contains more properties than the allowed maximum
+ // ErrorDetails: max
ArrayMaxPropertiesError struct {
ResultErrorFields
}
- // AdditionalPropertyNotAllowedError. ErrorDetails: property
+ // AdditionalPropertyNotAllowedError is produced if an object has additional properties, but not allowed
+ // ErrorDetails: property
AdditionalPropertyNotAllowedError struct {
ResultErrorFields
}
- // InvalidPropertyPatternError. ErrorDetails: property, pattern
+ // InvalidPropertyPatternError is produced if an pattern was found
+ // ErrorDetails: property, pattern
InvalidPropertyPatternError struct {
ResultErrorFields
}
- // InvalidPopertyNameError. ErrorDetails: property
+ // InvalidPropertyNameError is produced if an invalid-named property was found
+ // ErrorDetails: property
InvalidPropertyNameError struct {
ResultErrorFields
}
- // StringLengthGTEError. ErrorDetails: min
+ // StringLengthGTEError is produced if a string is shorter than the minimum required length
+ // ErrorDetails: min
StringLengthGTEError struct {
ResultErrorFields
}
- // StringLengthLTEError. ErrorDetails: max
+ // StringLengthLTEError is produced if a string is longer than the maximum allowed length
+ // ErrorDetails: max
StringLengthLTEError struct {
ResultErrorFields
}
- // DoesNotMatchPatternError. ErrorDetails: pattern
+ // DoesNotMatchPatternError is produced if a string does not match the defined pattern
+ // ErrorDetails: pattern
DoesNotMatchPatternError struct {
ResultErrorFields
}
- // DoesNotMatchFormatError. ErrorDetails: format
+ // DoesNotMatchFormatError is produced if a string does not match the defined format
+ // ErrorDetails: format
DoesNotMatchFormatError struct {
ResultErrorFields
}
- // MultipleOfError. ErrorDetails: multiple
+ // MultipleOfError is produced if a number is not a multiple of the defined multipleOf
+ // ErrorDetails: multiple
MultipleOfError struct {
ResultErrorFields
}
- // NumberGTEError. ErrorDetails: min
+ // NumberGTEError is produced if a number is lower than the allowed minimum
+ // ErrorDetails: min
NumberGTEError struct {
ResultErrorFields
}
- // NumberGTError. ErrorDetails: min
+ // NumberGTError is produced if a number is lower than, or equal to the specified minimum, and exclusiveMinimum is set
+ // ErrorDetails: min
NumberGTError struct {
ResultErrorFields
}
- // NumberLTEError. ErrorDetails: max
+ // NumberLTEError is produced if a number is higher than the allowed maximum
+ // ErrorDetails: max
NumberLTEError struct {
ResultErrorFields
}
- // NumberLTError. ErrorDetails: max
+ // NumberLTError is produced if a number is higher than, or equal to the specified maximum, and exclusiveMaximum is set
+ // ErrorDetails: max
NumberLTError struct {
ResultErrorFields
}
- // ConditionThenError. ErrorDetails: -
+ // ConditionThenError is produced if a condition's "then" validation is invalid
+ // ErrorDetails: -
ConditionThenError struct {
ResultErrorFields
}
- // ConditionElseError. ErrorDetails: -
+ // ConditionElseError is produced if a condition's "else" condition is invalid
+ // ErrorDetails: -
ConditionElseError struct {
ResultErrorFields
}
@@ -177,6 +214,9 @@ func newError(err ResultError, context *JsonContext, value interface{}, locale l
var t string
var d string
switch err.(type) {
+ case *FalseError:
+ t = "false"
+ d = locale.False()
case *RequiredError:
t = "required"
d = locale.Required()
diff --git a/vendor/github.com/xeipuuv/gojsonschema/format_checkers.go b/vendor/github.com/xeipuuv/gojsonschema/format_checkers.go
index 26217fca1..873ffc7d7 100644
--- a/vendor/github.com/xeipuuv/gojsonschema/format_checkers.go
+++ b/vendor/github.com/xeipuuv/gojsonschema/format_checkers.go
@@ -13,6 +13,7 @@ import (
type (
// FormatChecker is the interface all formatters added to FormatCheckerChain must implement
FormatChecker interface {
+ // IsFormat checks if input has the correct format and type
IsFormat(input interface{}) bool
}
@@ -21,13 +22,13 @@ type (
formatters map[string]FormatChecker
}
- // EmailFormatter verifies email address formats
+ // EmailFormatChecker verifies email address formats
EmailFormatChecker struct{}
- // IPV4FormatChecker verifies IP addresses in the ipv4 format
+ // IPV4FormatChecker verifies IP addresses in the IPv4 format
IPV4FormatChecker struct{}
- // IPV6FormatChecker verifies IP addresses in the ipv6 format
+ // IPV6FormatChecker verifies IP addresses in the IPv6 format
IPV6FormatChecker struct{}
// DateTimeFormatChecker verifies date/time formats per RFC3339 5.6
@@ -53,8 +54,29 @@ type (
// http://tools.ietf.org/html/rfc3339#section-5.6
DateTimeFormatChecker struct{}
+ // DateFormatChecker verifies date formats
+ //
+ // Valid format:
+ // Full Date: YYYY-MM-DD
+ //
+ // Where
+ // YYYY = 4DIGIT year
+ // MM = 2DIGIT month ; 01-12
+ // DD = 2DIGIT day-month ; 01-28, 01-29, 01-30, 01-31 based on month/year
DateFormatChecker struct{}
+ // TimeFormatChecker verifies time formats
+ //
+ // Valid formats:
+ // Partial Time: HH:MM:SS
+ // Full Time: HH:MM:SSZ-07:00
+ //
+ // Where
+ // HH = 2DIGIT hour ; 00-23
+ // MM = 2DIGIT ; 00-59
+ // SS = 2DIGIT ; 00-58, 00-60 based on leap second rules
+ // T = Literal
+ // Z = Literal
TimeFormatChecker struct{}
// URIFormatChecker validates a URI with a valid Scheme per RFC3986
@@ -83,7 +105,7 @@ type (
)
var (
- // Formatters holds the valid formatters, and is a public variable
+ // FormatCheckers holds the valid formatters, and is a public variable
// so library users can add custom formatters
FormatCheckers = FormatCheckerChain{
formatters: map[string]FormatChecker{
@@ -119,7 +141,7 @@ var (
rxRelJSONPointer = regexp.MustCompile("^(?:0|[1-9][0-9]*)(?:#|(?:/(?:[^~/]|~0|~1)*)*)$")
- lock = new(sync.Mutex)
+ lock = new(sync.RWMutex)
)
// Add adds a FormatChecker to the FormatCheckerChain
@@ -143,9 +165,9 @@ func (c *FormatCheckerChain) Remove(name string) *FormatCheckerChain {
// Has checks to see if the FormatCheckerChain holds a FormatChecker with the given name
func (c *FormatCheckerChain) Has(name string) bool {
- lock.Lock()
+ lock.RLock()
_, ok := c.formatters[name]
- lock.Unlock()
+ lock.RUnlock()
return ok
}
@@ -153,55 +175,57 @@ func (c *FormatCheckerChain) Has(name string) bool {
// IsFormat will check an input against a FormatChecker with the given name
// to see if it is the correct format
func (c *FormatCheckerChain) IsFormat(name string, input interface{}) bool {
+ lock.RLock()
f, ok := c.formatters[name]
+ lock.RUnlock()
+ // If a format is unrecognized it should always pass validation
if !ok {
- return false
+ return true
}
return f.IsFormat(input)
}
+// IsFormat checks if input is a correctly formatted e-mail address
func (f EmailFormatChecker) IsFormat(input interface{}) bool {
-
asString, ok := input.(string)
- if ok == false {
+ if !ok {
return false
}
_, err := mail.ParseAddress(asString)
-
return err == nil
}
-// Credit: https://github.com/asaskevich/govalidator
+// IsFormat checks if input is a correctly formatted IPv4-address
func (f IPV4FormatChecker) IsFormat(input interface{}) bool {
-
asString, ok := input.(string)
- if ok == false {
+ if !ok {
return false
}
+ // Credit: https://github.com/asaskevich/govalidator
ip := net.ParseIP(asString)
return ip != nil && strings.Contains(asString, ".")
}
-// Credit: https://github.com/asaskevich/govalidator
+// IsFormat checks if input is a correctly formatted IPv6=address
func (f IPV6FormatChecker) IsFormat(input interface{}) bool {
-
asString, ok := input.(string)
- if ok == false {
+ if !ok {
return false
}
+ // Credit: https://github.com/asaskevich/govalidator
ip := net.ParseIP(asString)
return ip != nil && strings.Contains(asString, ":")
}
+// IsFormat checks if input is a correctly formatted date/time per RFC3339 5.6
func (f DateTimeFormatChecker) IsFormat(input interface{}) bool {
-
asString, ok := input.(string)
- if ok == false {
+ if !ok {
return false
}
@@ -222,18 +246,20 @@ func (f DateTimeFormatChecker) IsFormat(input interface{}) bool {
return false
}
+// IsFormat checks if input is a correctly formatted date (YYYY-MM-DD)
func (f DateFormatChecker) IsFormat(input interface{}) bool {
asString, ok := input.(string)
- if ok == false {
+ if !ok {
return false
}
_, err := time.Parse("2006-01-02", asString)
return err == nil
}
+// IsFormat checks if input correctly formatted time (HH:MM:SS or HH:MM:SSZ-07:00)
func (f TimeFormatChecker) IsFormat(input interface{}) bool {
asString, ok := input.(string)
- if ok == false {
+ if !ok {
return false
}
@@ -245,10 +271,10 @@ func (f TimeFormatChecker) IsFormat(input interface{}) bool {
return err == nil
}
+// IsFormat checks if input is correctly formatted URI with a valid Scheme per RFC3986
func (f URIFormatChecker) IsFormat(input interface{}) bool {
-
asString, ok := input.(string)
- if ok == false {
+ if !ok {
return false
}
@@ -261,10 +287,10 @@ func (f URIFormatChecker) IsFormat(input interface{}) bool {
return !strings.Contains(asString, `\`)
}
+// IsFormat checks if input is a correctly formatted URI or relative-reference per RFC3986
func (f URIReferenceFormatChecker) IsFormat(input interface{}) bool {
-
asString, ok := input.(string)
- if ok == false {
+ if !ok {
return false
}
@@ -272,9 +298,10 @@ func (f URIReferenceFormatChecker) IsFormat(input interface{}) bool {
return err == nil && !strings.Contains(asString, `\`)
}
+// IsFormat checks if input is a correctly formatted URI template per RFC6570
func (f URITemplateFormatChecker) IsFormat(input interface{}) bool {
asString, ok := input.(string)
- if ok == false {
+ if !ok {
return false
}
@@ -286,31 +313,30 @@ func (f URITemplateFormatChecker) IsFormat(input interface{}) bool {
return rxURITemplate.MatchString(u.Path)
}
+// IsFormat checks if input is a correctly formatted hostname
func (f HostnameFormatChecker) IsFormat(input interface{}) bool {
-
asString, ok := input.(string)
- if ok == false {
+ if !ok {
return false
}
return rxHostname.MatchString(asString) && len(asString) < 256
}
+// IsFormat checks if input is a correctly formatted UUID
func (f UUIDFormatChecker) IsFormat(input interface{}) bool {
-
asString, ok := input.(string)
- if ok == false {
+ if !ok {
return false
}
return rxUUID.MatchString(asString)
}
-// IsFormat implements FormatChecker interface.
+// IsFormat checks if input is a correctly formatted regular expression
func (f RegexFormatChecker) IsFormat(input interface{}) bool {
-
asString, ok := input.(string)
- if ok == false {
+ if !ok {
return false
}
@@ -318,24 +344,23 @@ func (f RegexFormatChecker) IsFormat(input interface{}) bool {
return true
}
_, err := regexp.Compile(asString)
- if err != nil {
- return false
- }
- return true
+ return err == nil
}
+// IsFormat checks if input is a correctly formatted JSON Pointer per RFC6901
func (f JSONPointerFormatChecker) IsFormat(input interface{}) bool {
asString, ok := input.(string)
- if ok == false {
+ if !ok {
return false
}
return rxJSONPointer.MatchString(asString)
}
+// IsFormat checks if input is a correctly formatted relative JSON Pointer
func (f RelativeJSONPointerFormatChecker) IsFormat(input interface{}) bool {
asString, ok := input.(string)
- if ok == false {
+ if !ok {
return false
}
diff --git a/vendor/github.com/xeipuuv/gojsonschema/go.mod b/vendor/github.com/xeipuuv/gojsonschema/go.mod
new file mode 100644
index 000000000..b709d7fcd
--- /dev/null
+++ b/vendor/github.com/xeipuuv/gojsonschema/go.mod
@@ -0,0 +1,7 @@
+module github.com/xeipuuv/gojsonschema
+
+require (
+ github.com/stretchr/testify v1.3.0
+ github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f // indirect
+ github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415
+)
diff --git a/vendor/github.com/xeipuuv/gojsonschema/go.sum b/vendor/github.com/xeipuuv/gojsonschema/go.sum
new file mode 100644
index 000000000..0e865ac75
--- /dev/null
+++ b/vendor/github.com/xeipuuv/gojsonschema/go.sum
@@ -0,0 +1,11 @@
+github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
+github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
+github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
+github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c=
+github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
+github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0=
+github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
diff --git a/vendor/github.com/xeipuuv/gojsonschema/jsonContext.go b/vendor/github.com/xeipuuv/gojsonschema/jsonContext.go
index f40668a74..0e979707b 100644
--- a/vendor/github.com/xeipuuv/gojsonschema/jsonContext.go
+++ b/vendor/github.com/xeipuuv/gojsonschema/jsonContext.go
@@ -32,6 +32,7 @@ type JsonContext struct {
tail *JsonContext
}
+// NewJsonContext creates a new JsonContext
func NewJsonContext(head string, tail *JsonContext) *JsonContext {
return &JsonContext{head, tail}
}
diff --git a/vendor/github.com/xeipuuv/gojsonschema/jsonLoader.go b/vendor/github.com/xeipuuv/gojsonschema/jsonLoader.go
index cfa5f6a3a..4f57ff789 100644
--- a/vendor/github.com/xeipuuv/gojsonschema/jsonLoader.go
+++ b/vendor/github.com/xeipuuv/gojsonschema/jsonLoader.go
@@ -43,8 +43,7 @@ import (
var osFS = osFileSystem(os.Open)
-// JSON loader interface
-
+// JSONLoader defines the JSON loader interface
type JSONLoader interface {
JsonSource() interface{}
LoadJSON() (interface{}, error)
@@ -52,17 +51,22 @@ type JSONLoader interface {
LoaderFactory() JSONLoaderFactory
}
+// JSONLoaderFactory defines the JSON loader factory interface
type JSONLoaderFactory interface {
+ // New creates a new JSON loader for the given source
New(source string) JSONLoader
}
+// DefaultJSONLoaderFactory is the default JSON loader factory
type DefaultJSONLoaderFactory struct {
}
+// FileSystemJSONLoaderFactory is a JSON loader factory that uses http.FileSystem
type FileSystemJSONLoaderFactory struct {
fs http.FileSystem
}
+// New creates a new JSON loader for the given source
func (d DefaultJSONLoaderFactory) New(source string) JSONLoader {
return &jsonReferenceLoader{
fs: osFS,
@@ -70,6 +74,7 @@ func (d DefaultJSONLoaderFactory) New(source string) JSONLoader {
}
}
+// New creates a new JSON loader for the given source
func (f FileSystemJSONLoaderFactory) New(source string) JSONLoader {
return &jsonReferenceLoader{
fs: f.fs,
@@ -80,6 +85,7 @@ func (f FileSystemJSONLoaderFactory) New(source string) JSONLoader {
// osFileSystem is a functional wrapper for os.Open that implements http.FileSystem.
type osFileSystem func(string) (*os.File, error)
+// Opens a file with the given name
func (o osFileSystem) Open(name string) (http.File, error) {
return o(name)
}
@@ -131,14 +137,14 @@ func (l *jsonReferenceLoader) LoadJSON() (interface{}, error) {
return nil, err
}
- refToUrl := reference
- refToUrl.GetUrl().Fragment = ""
+ refToURL := reference
+ refToURL.GetUrl().Fragment = ""
var document interface{}
if reference.HasFileScheme {
- filename := strings.TrimPrefix(refToUrl.String(), "file://")
+ filename := strings.TrimPrefix(refToURL.String(), "file://")
if runtime.GOOS == "windows" {
// on Windows, a file URL may have an extra leading slash, use slashes
// instead of backslashes, and have spaces escaped
@@ -153,7 +159,7 @@ func (l *jsonReferenceLoader) LoadJSON() (interface{}, error) {
} else {
- document, err = l.loadFromHTTP(refToUrl.String())
+ document, err = l.loadFromHTTP(refToURL.String())
if err != nil {
return nil, err
}
@@ -169,7 +175,7 @@ func (l *jsonReferenceLoader) loadFromHTTP(address string) (interface{}, error)
// returned cached versions for metaschemas for drafts 4, 6 and 7
// for performance and allow for easier offline use
if metaSchema := drafts.GetMetaSchema(address); metaSchema != "" {
- return decodeJsonUsingNumber(strings.NewReader(metaSchema))
+ return decodeJSONUsingNumber(strings.NewReader(metaSchema))
}
resp, err := http.Get(address)
@@ -187,7 +193,7 @@ func (l *jsonReferenceLoader) loadFromHTTP(address string) (interface{}, error)
return nil, err
}
- return decodeJsonUsingNumber(bytes.NewReader(bodyBuff))
+ return decodeJSONUsingNumber(bytes.NewReader(bodyBuff))
}
func (l *jsonReferenceLoader) loadFromFile(path string) (interface{}, error) {
@@ -202,7 +208,7 @@ func (l *jsonReferenceLoader) loadFromFile(path string) (interface{}, error) {
return nil, err
}
- return decodeJsonUsingNumber(bytes.NewReader(bodyBuff))
+ return decodeJSONUsingNumber(bytes.NewReader(bodyBuff))
}
@@ -224,13 +230,14 @@ func (l *jsonStringLoader) LoaderFactory() JSONLoaderFactory {
return &DefaultJSONLoaderFactory{}
}
+// NewStringLoader creates a new JSONLoader, taking a string as source
func NewStringLoader(source string) JSONLoader {
return &jsonStringLoader{source: source}
}
func (l *jsonStringLoader) LoadJSON() (interface{}, error) {
- return decodeJsonUsingNumber(strings.NewReader(l.JsonSource().(string)))
+ return decodeJSONUsingNumber(strings.NewReader(l.JsonSource().(string)))
}
@@ -252,12 +259,13 @@ func (l *jsonBytesLoader) LoaderFactory() JSONLoaderFactory {
return &DefaultJSONLoaderFactory{}
}
+// NewBytesLoader creates a new JSONLoader, taking a `[]byte` as source
func NewBytesLoader(source []byte) JSONLoader {
return &jsonBytesLoader{source: source}
}
func (l *jsonBytesLoader) LoadJSON() (interface{}, error) {
- return decodeJsonUsingNumber(bytes.NewReader(l.JsonSource().([]byte)))
+ return decodeJSONUsingNumber(bytes.NewReader(l.JsonSource().([]byte)))
}
// JSON Go (types) loader
@@ -279,6 +287,7 @@ func (l *jsonGoLoader) LoaderFactory() JSONLoaderFactory {
return &DefaultJSONLoaderFactory{}
}
+// NewGoLoader creates a new JSONLoader from a given Go struct
func NewGoLoader(source interface{}) JSONLoader {
return &jsonGoLoader{source: source}
}
@@ -292,7 +301,7 @@ func (l *jsonGoLoader) LoadJSON() (interface{}, error) {
return nil, err
}
- return decodeJsonUsingNumber(bytes.NewReader(jsonBytes))
+ return decodeJSONUsingNumber(bytes.NewReader(jsonBytes))
}
@@ -300,11 +309,13 @@ type jsonIOLoader struct {
buf *bytes.Buffer
}
+// NewReaderLoader creates a new JSON loader using the provided io.Reader
func NewReaderLoader(source io.Reader) (JSONLoader, io.Reader) {
buf := &bytes.Buffer{}
return &jsonIOLoader{buf: buf}, io.TeeReader(source, buf)
}
+// NewWriterLoader creates a new JSON loader using the provided io.Writer
func NewWriterLoader(source io.Writer) (JSONLoader, io.Writer) {
buf := &bytes.Buffer{}
return &jsonIOLoader{buf: buf}, io.MultiWriter(source, buf)
@@ -315,7 +326,7 @@ func (l *jsonIOLoader) JsonSource() interface{} {
}
func (l *jsonIOLoader) LoadJSON() (interface{}, error) {
- return decodeJsonUsingNumber(l.buf)
+ return decodeJSONUsingNumber(l.buf)
}
func (l *jsonIOLoader) JsonReference() (gojsonreference.JsonReference, error) {
@@ -334,7 +345,8 @@ type jsonRawLoader struct {
source interface{}
}
-func NewRawLoader(source interface{}) *jsonRawLoader {
+// NewRawLoader creates a new JSON raw loader for the given source
+func NewRawLoader(source interface{}) JSONLoader {
return &jsonRawLoader{source: source}
}
func (l *jsonRawLoader) JsonSource() interface{} {
@@ -350,7 +362,7 @@ func (l *jsonRawLoader) LoaderFactory() JSONLoaderFactory {
return &DefaultJSONLoaderFactory{}
}
-func decodeJsonUsingNumber(r io.Reader) (interface{}, error) {
+func decodeJSONUsingNumber(r io.Reader) (interface{}, error) {
var document interface{}
diff --git a/vendor/github.com/xeipuuv/gojsonschema/locales.go b/vendor/github.com/xeipuuv/gojsonschema/locales.go
index 9b4570f01..a416225cd 100644
--- a/vendor/github.com/xeipuuv/gojsonschema/locales.go
+++ b/vendor/github.com/xeipuuv/gojsonschema/locales.go
@@ -28,61 +28,163 @@ package gojsonschema
type (
// locale is an interface for defining custom error strings
locale interface {
+
+ // False returns a format-string for "false" schema validation errors
+ False() string
+
+ // Required returns a format-string for "required" schema validation errors
Required() string
+
+ // InvalidType returns a format-string for "invalid type" schema validation errors
InvalidType() string
+
+ // NumberAnyOf returns a format-string for "anyOf" schema validation errors
NumberAnyOf() string
+
+ // NumberOneOf returns a format-string for "oneOf" schema validation errors
NumberOneOf() string
+
+ // NumberAllOf returns a format-string for "allOf" schema validation errors
NumberAllOf() string
+
+ // NumberNot returns a format-string to format a NumberNotError
NumberNot() string
+
+ // MissingDependency returns a format-string for "missing dependency" schema validation errors
MissingDependency() string
+
+ // Internal returns a format-string for internal errors
Internal() string
+
+ // Const returns a format-string to format a ConstError
Const() string
+
+ // Enum returns a format-string to format an EnumError
Enum() string
+
+ // ArrayNotEnoughItems returns a format-string to format an error for arrays having not enough items to match positional list of schema
ArrayNotEnoughItems() string
+
+ // ArrayNoAdditionalItems returns a format-string to format an ArrayNoAdditionalItemsError
ArrayNoAdditionalItems() string
+
+ // ArrayMinItems returns a format-string to format an ArrayMinItemsError
ArrayMinItems() string
+
+ // ArrayMaxItems returns a format-string to format an ArrayMaxItemsError
ArrayMaxItems() string
+
+ // Unique returns a format-string to format an ItemsMustBeUniqueError
Unique() string
+
+ // ArrayContains returns a format-string to format an ArrayContainsError
ArrayContains() string
+
+ // ArrayMinProperties returns a format-string to format an ArrayMinPropertiesError
ArrayMinProperties() string
+
+ // ArrayMaxProperties returns a format-string to format an ArrayMaxPropertiesError
ArrayMaxProperties() string
+
+ // AdditionalPropertyNotAllowed returns a format-string to format an AdditionalPropertyNotAllowedError
AdditionalPropertyNotAllowed() string
+
+ // InvalidPropertyPattern returns a format-string to format an InvalidPropertyPatternError
InvalidPropertyPattern() string
+
+ // InvalidPropertyName returns a format-string to format an InvalidPropertyNameError
InvalidPropertyName() string
+
+ // StringGTE returns a format-string to format an StringLengthGTEError
StringGTE() string
+
+ // StringLTE returns a format-string to format an StringLengthLTEError
StringLTE() string
+
+ // DoesNotMatchPattern returns a format-string to format an DoesNotMatchPatternError
DoesNotMatchPattern() string
+
+ // DoesNotMatchFormat returns a format-string to format an DoesNotMatchFormatError
DoesNotMatchFormat() string
+
+ // MultipleOf returns a format-string to format an MultipleOfError
MultipleOf() string
+
+ // NumberGTE returns a format-string to format an NumberGTEError
NumberGTE() string
+
+ // NumberGT returns a format-string to format an NumberGTError
NumberGT() string
+
+ // NumberLTE returns a format-string to format an NumberLTEError
NumberLTE() string
+
+ // NumberLT returns a format-string to format an NumberLTError
NumberLT() string
// Schema validations
+
+ // RegexPattern returns a format-string to format a regex-pattern error
RegexPattern() string
+
+ // GreaterThanZero returns a format-string to format an error where a number must be greater than zero
GreaterThanZero() string
+
+ // MustBeOfA returns a format-string to format an error where a value is of the wrong type
MustBeOfA() string
+
+ // MustBeOfAn returns a format-string to format an error where a value is of the wrong type
MustBeOfAn() string
+
+ // CannotBeUsedWithout returns a format-string to format a "cannot be used without" error
CannotBeUsedWithout() string
+
+ // CannotBeGT returns a format-string to format an error where a value are greater than allowed
CannotBeGT() string
+
+ // MustBeOfType returns a format-string to format an error where a value does not match the required type
MustBeOfType() string
+
+ // MustBeValidRegex returns a format-string to format an error where a regex is invalid
MustBeValidRegex() string
+
+ // MustBeValidFormat returns a format-string to format an error where a value does not match the expected format
MustBeValidFormat() string
+
+ // MustBeGTEZero returns a format-string to format an error where a value must be greater or equal than 0
MustBeGTEZero() string
+
+ // KeyCannotBeGreaterThan returns a format-string to format an error where a key is greater than the maximum allowed
KeyCannotBeGreaterThan() string
+
+ // KeyItemsMustBeOfType returns a format-string to format an error where a key is of the wrong type
KeyItemsMustBeOfType() string
+
+ // KeyItemsMustBeUnique returns a format-string to format an error where keys are not unique
KeyItemsMustBeUnique() string
+
+ // ReferenceMustBeCanonical returns a format-string to format a "reference must be canonical" error
ReferenceMustBeCanonical() string
+
+ // NotAValidType returns a format-string to format an invalid type error
NotAValidType() string
+
+ // Duplicated returns a format-string to format an error where types are duplicated
Duplicated() string
+
+ // HttpBadStatus returns a format-string for errors when loading a schema using HTTP
HttpBadStatus() string
+
+ // ParseError returns a format-string for JSON parsing errors
ParseError() string
+ // ConditionThen returns a format-string for ConditionThenError errors
ConditionThen() string
+
+ // ConditionElse returns a format-string for ConditionElseError errors
ConditionElse() string
- // ErrorFormat
+ // ErrorFormat returns a format string for errors
ErrorFormat() string
}
@@ -90,214 +192,271 @@ type (
DefaultLocale struct{}
)
+// False returns a format-string for "false" schema validation errors
+func (l DefaultLocale) False() string {
+ return "False always fails validation"
+}
+
+// Required returns a format-string for "required" schema validation errors
func (l DefaultLocale) Required() string {
return `{{.property}} is required`
}
+// InvalidType returns a format-string for "invalid type" schema validation errors
func (l DefaultLocale) InvalidType() string {
return `Invalid type. Expected: {{.expected}}, given: {{.given}}`
}
+// NumberAnyOf returns a format-string for "anyOf" schema validation errors
func (l DefaultLocale) NumberAnyOf() string {
return `Must validate at least one schema (anyOf)`
}
+// NumberOneOf returns a format-string for "oneOf" schema validation errors
func (l DefaultLocale) NumberOneOf() string {
return `Must validate one and only one schema (oneOf)`
}
+// NumberAllOf returns a format-string for "allOf" schema validation errors
func (l DefaultLocale) NumberAllOf() string {
return `Must validate all the schemas (allOf)`
}
+// NumberNot returns a format-string to format a NumberNotError
func (l DefaultLocale) NumberNot() string {
return `Must not validate the schema (not)`
}
+// MissingDependency returns a format-string for "missing dependency" schema validation errors
func (l DefaultLocale) MissingDependency() string {
return `Has a dependency on {{.dependency}}`
}
+// Internal returns a format-string for internal errors
func (l DefaultLocale) Internal() string {
return `Internal Error {{.error}}`
}
+// Const returns a format-string to format a ConstError
func (l DefaultLocale) Const() string {
return `{{.field}} does not match: {{.allowed}}`
}
+// Enum returns a format-string to format an EnumError
func (l DefaultLocale) Enum() string {
return `{{.field}} must be one of the following: {{.allowed}}`
}
+// ArrayNoAdditionalItems returns a format-string to format an ArrayNoAdditionalItemsError
func (l DefaultLocale) ArrayNoAdditionalItems() string {
return `No additional items allowed on array`
}
+// ArrayNotEnoughItems returns a format-string to format an error for arrays having not enough items to match positional list of schema
func (l DefaultLocale) ArrayNotEnoughItems() string {
return `Not enough items on array to match positional list of schema`
}
+// ArrayMinItems returns a format-string to format an ArrayMinItemsError
func (l DefaultLocale) ArrayMinItems() string {
return `Array must have at least {{.min}} items`
}
+// ArrayMaxItems returns a format-string to format an ArrayMaxItemsError
func (l DefaultLocale) ArrayMaxItems() string {
return `Array must have at most {{.max}} items`
}
+// Unique returns a format-string to format an ItemsMustBeUniqueError
func (l DefaultLocale) Unique() string {
return `{{.type}} items[{{.i}},{{.j}}] must be unique`
}
+// ArrayContains returns a format-string to format an ArrayContainsError
func (l DefaultLocale) ArrayContains() string {
return `At least one of the items must match`
}
+// ArrayMinProperties returns a format-string to format an ArrayMinPropertiesError
func (l DefaultLocale) ArrayMinProperties() string {
return `Must have at least {{.min}} properties`
}
+// ArrayMaxProperties returns a format-string to format an ArrayMaxPropertiesError
func (l DefaultLocale) ArrayMaxProperties() string {
return `Must have at most {{.max}} properties`
}
+// AdditionalPropertyNotAllowed returns a format-string to format an AdditionalPropertyNotAllowedError
func (l DefaultLocale) AdditionalPropertyNotAllowed() string {
return `Additional property {{.property}} is not allowed`
}
+// InvalidPropertyPattern returns a format-string to format an InvalidPropertyPatternError
func (l DefaultLocale) InvalidPropertyPattern() string {
return `Property "{{.property}}" does not match pattern {{.pattern}}`
}
+// InvalidPropertyName returns a format-string to format an InvalidPropertyNameError
func (l DefaultLocale) InvalidPropertyName() string {
return `Property name of "{{.property}}" does not match`
}
+// StringGTE returns a format-string to format an StringLengthGTEError
func (l DefaultLocale) StringGTE() string {
return `String length must be greater than or equal to {{.min}}`
}
+// StringLTE returns a format-string to format an StringLengthLTEError
func (l DefaultLocale) StringLTE() string {
return `String length must be less than or equal to {{.max}}`
}
+// DoesNotMatchPattern returns a format-string to format an DoesNotMatchPatternError
func (l DefaultLocale) DoesNotMatchPattern() string {
return `Does not match pattern '{{.pattern}}'`
}
+// DoesNotMatchFormat returns a format-string to format an DoesNotMatchFormatError
func (l DefaultLocale) DoesNotMatchFormat() string {
return `Does not match format '{{.format}}'`
}
+// MultipleOf returns a format-string to format an MultipleOfError
func (l DefaultLocale) MultipleOf() string {
return `Must be a multiple of {{.multiple}}`
}
+// NumberGTE returns the format string to format a NumberGTEError
func (l DefaultLocale) NumberGTE() string {
return `Must be greater than or equal to {{.min}}`
}
+// NumberGT returns the format string to format a NumberGTError
func (l DefaultLocale) NumberGT() string {
return `Must be greater than {{.min}}`
}
+// NumberLTE returns the format string to format a NumberLTEError
func (l DefaultLocale) NumberLTE() string {
return `Must be less than or equal to {{.max}}`
}
+// NumberLT returns the format string to format a NumberLTError
func (l DefaultLocale) NumberLT() string {
return `Must be less than {{.max}}`
}
// Schema validators
+
+// RegexPattern returns a format-string to format a regex-pattern error
func (l DefaultLocale) RegexPattern() string {
return `Invalid regex pattern '{{.pattern}}'`
}
+// GreaterThanZero returns a format-string to format an error where a number must be greater than zero
func (l DefaultLocale) GreaterThanZero() string {
return `{{.number}} must be strictly greater than 0`
}
+// MustBeOfA returns a format-string to format an error where a value is of the wrong type
func (l DefaultLocale) MustBeOfA() string {
return `{{.x}} must be of a {{.y}}`
}
+// MustBeOfAn returns a format-string to format an error where a value is of the wrong type
func (l DefaultLocale) MustBeOfAn() string {
return `{{.x}} must be of an {{.y}}`
}
+// CannotBeUsedWithout returns a format-string to format a "cannot be used without" error
func (l DefaultLocale) CannotBeUsedWithout() string {
return `{{.x}} cannot be used without {{.y}}`
}
+// CannotBeGT returns a format-string to format an error where a value are greater than allowed
func (l DefaultLocale) CannotBeGT() string {
return `{{.x}} cannot be greater than {{.y}}`
}
+// MustBeOfType returns a format-string to format an error where a value does not match the required type
func (l DefaultLocale) MustBeOfType() string {
return `{{.key}} must be of type {{.type}}`
}
+// MustBeValidRegex returns a format-string to format an error where a regex is invalid
func (l DefaultLocale) MustBeValidRegex() string {
return `{{.key}} must be a valid regex`
}
+// MustBeValidFormat returns a format-string to format an error where a value does not match the expected format
func (l DefaultLocale) MustBeValidFormat() string {
return `{{.key}} must be a valid format {{.given}}`
}
+// MustBeGTEZero returns a format-string to format an error where a value must be greater or equal than 0
func (l DefaultLocale) MustBeGTEZero() string {
return `{{.key}} must be greater than or equal to 0`
}
+// KeyCannotBeGreaterThan returns a format-string to format an error where a value is greater than the maximum allowed
func (l DefaultLocale) KeyCannotBeGreaterThan() string {
return `{{.key}} cannot be greater than {{.y}}`
}
+// KeyItemsMustBeOfType returns a format-string to format an error where a key is of the wrong type
func (l DefaultLocale) KeyItemsMustBeOfType() string {
return `{{.key}} items must be {{.type}}`
}
+// KeyItemsMustBeUnique returns a format-string to format an error where keys are not unique
func (l DefaultLocale) KeyItemsMustBeUnique() string {
return `{{.key}} items must be unique`
}
+// ReferenceMustBeCanonical returns a format-string to format a "reference must be canonical" error
func (l DefaultLocale) ReferenceMustBeCanonical() string {
return `Reference {{.reference}} must be canonical`
}
+// NotAValidType returns a format-string to format an invalid type error
func (l DefaultLocale) NotAValidType() string {
return `has a primitive type that is NOT VALID -- given: {{.given}} Expected valid values are:{{.expected}}`
}
+// Duplicated returns a format-string to format an error where types are duplicated
func (l DefaultLocale) Duplicated() string {
return `{{.type}} type is duplicated`
}
+// HttpBadStatus returns a format-string for errors when loading a schema using HTTP
func (l DefaultLocale) HttpBadStatus() string {
return `Could not read schema from HTTP, response status is {{.status}}`
}
+// ErrorFormat returns a format string for errors
// Replacement options: field, description, context, value
func (l DefaultLocale) ErrorFormat() string {
return `{{.field}}: {{.description}}`
}
-//Parse error
+// ParseError returns a format-string for JSON parsing errors
func (l DefaultLocale) ParseError() string {
return `Expected: {{.expected}}, given: Invalid JSON`
}
-//If/Else
+// ConditionThen returns a format-string for ConditionThenError errors
+// If/Else
func (l DefaultLocale) ConditionThen() string {
return `Must validate "then" as "if" was valid`
}
+// ConditionElse returns a format-string for ConditionElseError errors
func (l DefaultLocale) ConditionElse() string {
return `Must validate "else" as "if" was not valid`
}
+// constants
const (
STRING_NUMBER = "number"
STRING_ARRAY_OF_STRINGS = "array of strings"
diff --git a/vendor/github.com/xeipuuv/gojsonschema/result.go b/vendor/github.com/xeipuuv/gojsonschema/result.go
index 040d35c8d..0a0179148 100644
--- a/vendor/github.com/xeipuuv/gojsonschema/result.go
+++ b/vendor/github.com/xeipuuv/gojsonschema/result.go
@@ -37,19 +37,34 @@ type (
// ResultError is the interface that library errors must implement
ResultError interface {
+ // Field returns the field name without the root context
+ // i.e. firstName or person.firstName instead of (root).firstName or (root).person.firstName
Field() string
+ // SetType sets the error-type
SetType(string)
+ // Type returns the error-type
Type() string
+ // SetContext sets the JSON-context for the error
SetContext(*JsonContext)
+ // Context returns the JSON-context of the error
Context() *JsonContext
+ // SetDescription sets a description for the error
SetDescription(string)
+ // Description returns the description of the error
Description() string
+ // SetDescriptionFormat sets the format for the description in the default text/template format
SetDescriptionFormat(string)
+ // DescriptionFormat returns the format for the description in the default text/template format
DescriptionFormat() string
+ // SetValue sets the value related to the error
SetValue(interface{})
+ // Value returns the value related to the error
Value() interface{}
+ // SetDetails sets the details specific to the error
SetDetails(ErrorDetails)
+ // Details returns details about the error
Details() ErrorDetails
+ // String returns a string representation of the error
String() string
}
@@ -65,6 +80,7 @@ type (
details ErrorDetails
}
+ // Result holds the result of a validation
Result struct {
errors []ResultError
// Scores how well the validation matched. Useful in generating
@@ -73,60 +89,73 @@ type (
}
)
-// Field outputs the field name without the root context
+// Field returns the field name without the root context
// i.e. firstName or person.firstName instead of (root).firstName or (root).person.firstName
func (v *ResultErrorFields) Field() string {
return strings.TrimPrefix(v.context.String(), STRING_ROOT_SCHEMA_PROPERTY+".")
}
+// SetType sets the error-type
func (v *ResultErrorFields) SetType(errorType string) {
v.errorType = errorType
}
+// Type returns the error-type
func (v *ResultErrorFields) Type() string {
return v.errorType
}
+// SetContext sets the JSON-context for the error
func (v *ResultErrorFields) SetContext(context *JsonContext) {
v.context = context
}
+// Context returns the JSON-context of the error
func (v *ResultErrorFields) Context() *JsonContext {
return v.context
}
+// SetDescription sets a description for the error
func (v *ResultErrorFields) SetDescription(description string) {
v.description = description
}
+// Description returns the description of the error
func (v *ResultErrorFields) Description() string {
return v.description
}
+// SetDescriptionFormat sets the format for the description in the default text/template format
func (v *ResultErrorFields) SetDescriptionFormat(descriptionFormat string) {
v.descriptionFormat = descriptionFormat
}
+// DescriptionFormat returns the format for the description in the default text/template format
func (v *ResultErrorFields) DescriptionFormat() string {
return v.descriptionFormat
}
+// SetValue sets the value related to the error
func (v *ResultErrorFields) SetValue(value interface{}) {
v.value = value
}
+// Value returns the value related to the error
func (v *ResultErrorFields) Value() interface{} {
return v.value
}
+// SetDetails sets the details specific to the error
func (v *ResultErrorFields) SetDetails(details ErrorDetails) {
v.details = details
}
+// Details returns details about the error
func (v *ResultErrorFields) Details() ErrorDetails {
return v.details
}
+// String returns a string representation of the error
func (v ResultErrorFields) String() string {
// as a fallback, the value is displayed go style
valueString := fmt.Sprintf("%v", v.value)
@@ -135,7 +164,7 @@ func (v ResultErrorFields) String() string {
if v.value == nil {
valueString = TYPE_NULL
} else {
- if vs, err := marshalToJsonString(v.value); err == nil {
+ if vs, err := marshalToJSONString(v.value); err == nil {
if vs == nil {
valueString = TYPE_NULL
} else {
@@ -152,15 +181,17 @@ func (v ResultErrorFields) String() string {
})
}
+// Valid indicates if no errors were found
func (v *Result) Valid() bool {
return len(v.errors) == 0
}
+// Errors returns the errors that were found
func (v *Result) Errors() []ResultError {
return v.errors
}
-// Add a fully filled error to the error set
+// AddError appends a fully filled error to the error set
// SetDescription() will be called with the result of the parsed err.DescriptionFormat()
func (v *Result) AddError(err ResultError, details ErrorDetails) {
if _, exists := details["context"]; !exists && err.Context() != nil {
diff --git a/vendor/github.com/xeipuuv/gojsonschema/schema.go b/vendor/github.com/xeipuuv/gojsonschema/schema.go
index 323fe8559..9e93cd795 100644
--- a/vendor/github.com/xeipuuv/gojsonschema/schema.go
+++ b/vendor/github.com/xeipuuv/gojsonschema/schema.go
@@ -45,10 +45,12 @@ var (
ErrorTemplateFuncs template.FuncMap
)
+// NewSchema instances a schema using the given JSONLoader
func NewSchema(l JSONLoader) (*Schema, error) {
return NewSchemaLoader().Compile(l)
}
+// Schema holds a schema
type Schema struct {
documentReference gojsonreference.JsonReference
rootSchema *subSchema
@@ -61,6 +63,7 @@ func (d *Schema) parse(document interface{}, draft Draft) error {
return d.parseSchema(document, d.rootSchema)
}
+// SetRootSchemaName sets the root-schema name
func (d *Schema) SetRootSchemaName(name string) {
d.rootSchema.property = name
}
@@ -83,11 +86,8 @@ func (d *Schema) parseSchema(documentNode interface{}, currentSchema *subSchema)
// As of draft 6 "true" is equivalent to an empty schema "{}" and false equals "{"not":{}}"
if *currentSchema.draft >= Draft6 && isKind(documentNode, reflect.Bool) {
b := documentNode.(bool)
- if b {
- documentNode = map[string]interface{}{}
- } else {
- documentNode = map[string]interface{}{"not": true}
- }
+ currentSchema.pass = &b
+ return nil
}
if !isKind(documentNode, reflect.Map) {
@@ -267,8 +267,9 @@ func (d *Schema) parseSchema(documentNode interface{}, currentSchema *subSchema)
"given": KEY_TYPE,
},
))
- } else {
- currentSchema.types.Add(typeInArray.(string))
+ }
+ if err := currentSchema.types.Add(typeInArray.(string)); err != nil {
+ return err
}
}
@@ -382,7 +383,7 @@ func (d *Schema) parseSchema(documentNode interface{}, currentSchema *subSchema)
if isKind(itemElement, reflect.Map, reflect.Bool) {
newSchema := &subSchema{parent: currentSchema, property: KEY_ITEMS}
newSchema.ref = currentSchema.ref
- currentSchema.AddItemsChild(newSchema)
+ currentSchema.itemsChildren = append(currentSchema.itemsChildren, newSchema)
err := d.parseSchema(itemElement, newSchema)
if err != nil {
return err
@@ -401,7 +402,7 @@ func (d *Schema) parseSchema(documentNode interface{}, currentSchema *subSchema)
} else if isKind(m[KEY_ITEMS], reflect.Map, reflect.Bool) {
newSchema := &subSchema{parent: currentSchema, property: KEY_ITEMS}
newSchema.ref = currentSchema.ref
- currentSchema.AddItemsChild(newSchema)
+ currentSchema.itemsChildren = append(currentSchema.itemsChildren, newSchema)
err := d.parseSchema(m[KEY_ITEMS], newSchema)
if err != nil {
return err
@@ -507,7 +508,7 @@ func (d *Schema) parseSchema(documentNode interface{}, currentSchema *subSchema)
currentSchema.exclusiveMinimum = currentSchema.minimum
currentSchema.minimum = nil
}
- } else if isJsonNumber(m[KEY_EXCLUSIVE_MINIMUM]) {
+ } else if isJSONNumber(m[KEY_EXCLUSIVE_MINIMUM]) {
currentSchema.exclusiveMinimum = mustBeNumber(m[KEY_EXCLUSIVE_MINIMUM])
} else {
return errors.New(formatErrorDescription(
@@ -519,7 +520,7 @@ func (d *Schema) parseSchema(documentNode interface{}, currentSchema *subSchema)
))
}
default:
- if isJsonNumber(m[KEY_EXCLUSIVE_MINIMUM]) {
+ if isJSONNumber(m[KEY_EXCLUSIVE_MINIMUM]) {
currentSchema.exclusiveMinimum = mustBeNumber(m[KEY_EXCLUSIVE_MINIMUM])
} else {
return errors.New(formatErrorDescription(
@@ -578,7 +579,7 @@ func (d *Schema) parseSchema(documentNode interface{}, currentSchema *subSchema)
currentSchema.exclusiveMaximum = currentSchema.maximum
currentSchema.maximum = nil
}
- } else if isJsonNumber(m[KEY_EXCLUSIVE_MAXIMUM]) {
+ } else if isJSONNumber(m[KEY_EXCLUSIVE_MAXIMUM]) {
currentSchema.exclusiveMaximum = mustBeNumber(m[KEY_EXCLUSIVE_MAXIMUM])
} else {
return errors.New(formatErrorDescription(
@@ -590,7 +591,7 @@ func (d *Schema) parseSchema(documentNode interface{}, currentSchema *subSchema)
))
}
default:
- if isJsonNumber(m[KEY_EXCLUSIVE_MAXIMUM]) {
+ if isJSONNumber(m[KEY_EXCLUSIVE_MAXIMUM]) {
currentSchema.exclusiveMaximum = mustBeNumber(m[KEY_EXCLUSIVE_MAXIMUM])
} else {
return errors.New(formatErrorDescription(
@@ -669,9 +670,13 @@ func (d *Schema) parseSchema(documentNode interface{}, currentSchema *subSchema)
if existsMapKey(m, KEY_FORMAT) {
formatString, ok := m[KEY_FORMAT].(string)
- if ok && FormatCheckers.Has(formatString) {
- currentSchema.format = formatString
+ if !ok {
+ return errors.New(formatErrorDescription(
+ Locale.MustBeOfType(),
+ ErrorDetails{"key": KEY_FORMAT, "type": TYPE_STRING},
+ ))
}
+ currentSchema.format = formatString
}
// validation : object
@@ -724,10 +729,13 @@ func (d *Schema) parseSchema(documentNode interface{}, currentSchema *subSchema)
requiredValues := m[KEY_REQUIRED].([]interface{})
for _, requiredValue := range requiredValues {
if isKind(requiredValue, reflect.String) {
- err := currentSchema.AddRequired(requiredValue.(string))
- if err != nil {
- return err
+ if isStringInSlice(currentSchema.required, requiredValue.(string)) {
+ return errors.New(formatErrorDescription(
+ Locale.KeyItemsMustBeUnique(),
+ ErrorDetails{"key": KEY_REQUIRED},
+ ))
}
+ currentSchema.required = append(currentSchema.required, requiredValue.(string))
} else {
return errors.New(formatErrorDescription(
Locale.KeyItemsMustBeOfType(),
@@ -802,19 +810,27 @@ func (d *Schema) parseSchema(documentNode interface{}, currentSchema *subSchema)
// validation : all
if existsMapKey(m, KEY_CONST) && *currentSchema.draft >= Draft6 {
- err := currentSchema.AddConst(m[KEY_CONST])
+ is, err := marshalWithoutNumber(m[KEY_CONST])
if err != nil {
return err
}
+ currentSchema._const = is
}
if existsMapKey(m, KEY_ENUM) {
if isKind(m[KEY_ENUM], reflect.Slice) {
for _, v := range m[KEY_ENUM].([]interface{}) {
- err := currentSchema.AddEnum(v)
+ is, err := marshalWithoutNumber(v)
if err != nil {
return err
}
+ if isStringInSlice(currentSchema.enum, *is) {
+ return errors.New(formatErrorDescription(
+ Locale.KeyItemsMustBeUnique(),
+ ErrorDetails{"key": KEY_ENUM},
+ ))
+ }
+ currentSchema.enum = append(currentSchema.enum, *is)
}
} else {
return errors.New(formatErrorDescription(
@@ -830,7 +846,7 @@ func (d *Schema) parseSchema(documentNode interface{}, currentSchema *subSchema)
if isKind(m[KEY_ONE_OF], reflect.Slice) {
for _, v := range m[KEY_ONE_OF].([]interface{}) {
newSchema := &subSchema{property: KEY_ONE_OF, parent: currentSchema, ref: currentSchema.ref}
- currentSchema.AddOneOf(newSchema)
+ currentSchema.oneOf = append(currentSchema.oneOf, newSchema)
err := d.parseSchema(v, newSchema)
if err != nil {
return err
@@ -848,7 +864,7 @@ func (d *Schema) parseSchema(documentNode interface{}, currentSchema *subSchema)
if isKind(m[KEY_ANY_OF], reflect.Slice) {
for _, v := range m[KEY_ANY_OF].([]interface{}) {
newSchema := &subSchema{property: KEY_ANY_OF, parent: currentSchema, ref: currentSchema.ref}
- currentSchema.AddAnyOf(newSchema)
+ currentSchema.anyOf = append(currentSchema.anyOf, newSchema)
err := d.parseSchema(v, newSchema)
if err != nil {
return err
@@ -866,7 +882,7 @@ func (d *Schema) parseSchema(documentNode interface{}, currentSchema *subSchema)
if isKind(m[KEY_ALL_OF], reflect.Slice) {
for _, v := range m[KEY_ALL_OF].([]interface{}) {
newSchema := &subSchema{property: KEY_ALL_OF, parent: currentSchema, ref: currentSchema.ref}
- currentSchema.AddAllOf(newSchema)
+ currentSchema.allOf = append(currentSchema.allOf, newSchema)
err := d.parseSchema(v, newSchema)
if err != nil {
return err
@@ -883,7 +899,7 @@ func (d *Schema) parseSchema(documentNode interface{}, currentSchema *subSchema)
if existsMapKey(m, KEY_NOT) {
if isKind(m[KEY_NOT], reflect.Map, reflect.Bool) {
newSchema := &subSchema{property: KEY_NOT, parent: currentSchema, ref: currentSchema.ref}
- currentSchema.SetNot(newSchema)
+ currentSchema.not = newSchema
err := d.parseSchema(m[KEY_NOT], newSchema)
if err != nil {
return err
@@ -900,7 +916,7 @@ func (d *Schema) parseSchema(documentNode interface{}, currentSchema *subSchema)
if existsMapKey(m, KEY_IF) {
if isKind(m[KEY_IF], reflect.Map, reflect.Bool) {
newSchema := &subSchema{property: KEY_IF, parent: currentSchema, ref: currentSchema.ref}
- currentSchema.SetIf(newSchema)
+ currentSchema._if = newSchema
err := d.parseSchema(m[KEY_IF], newSchema)
if err != nil {
return err
@@ -916,7 +932,7 @@ func (d *Schema) parseSchema(documentNode interface{}, currentSchema *subSchema)
if existsMapKey(m, KEY_THEN) {
if isKind(m[KEY_THEN], reflect.Map, reflect.Bool) {
newSchema := &subSchema{property: KEY_THEN, parent: currentSchema, ref: currentSchema.ref}
- currentSchema.SetThen(newSchema)
+ currentSchema._then = newSchema
err := d.parseSchema(m[KEY_THEN], newSchema)
if err != nil {
return err
@@ -932,7 +948,7 @@ func (d *Schema) parseSchema(documentNode interface{}, currentSchema *subSchema)
if existsMapKey(m, KEY_ELSE) {
if isKind(m[KEY_ELSE], reflect.Map, reflect.Bool) {
newSchema := &subSchema{property: KEY_ELSE, parent: currentSchema, ref: currentSchema.ref}
- currentSchema.SetElse(newSchema)
+ currentSchema._else = newSchema
err := d.parseSchema(m[KEY_ELSE], newSchema)
if err != nil {
return err
@@ -1004,7 +1020,7 @@ func (d *Schema) parseProperties(documentNode interface{}, currentSchema *subSch
for k := range m {
schemaProperty := k
newSchema := &subSchema{property: schemaProperty, parent: currentSchema, ref: currentSchema.ref}
- currentSchema.AddPropertiesChild(newSchema)
+ currentSchema.propertiesChildren = append(currentSchema.propertiesChildren, newSchema)
err := d.parseSchema(m[k], newSchema)
if err != nil {
return err
@@ -1042,9 +1058,8 @@ func (d *Schema) parseDependencies(documentNode interface{}, currentSchema *subS
"type": STRING_SCHEMA_OR_ARRAY_OF_STRINGS,
},
))
- } else {
- valuesToRegister = append(valuesToRegister, value.(string))
}
+ valuesToRegister = append(valuesToRegister, value.(string))
currentSchema.dependencies[k] = valuesToRegister
}
diff --git a/vendor/github.com/xeipuuv/gojsonschema/schemaLoader.go b/vendor/github.com/xeipuuv/gojsonschema/schemaLoader.go
index 95e0568ab..20db0c1f9 100644
--- a/vendor/github.com/xeipuuv/gojsonschema/schemaLoader.go
+++ b/vendor/github.com/xeipuuv/gojsonschema/schemaLoader.go
@@ -21,6 +21,7 @@ import (
"github.com/xeipuuv/gojsonreference"
)
+// SchemaLoader is used to load schemas
type SchemaLoader struct {
pool *schemaPool
AutoDetect bool
@@ -28,6 +29,7 @@ type SchemaLoader struct {
Draft Draft
}
+// NewSchemaLoader creates a new NewSchemaLoader
func NewSchemaLoader() *SchemaLoader {
ps := &SchemaLoader{
@@ -141,6 +143,7 @@ func (sl *SchemaLoader) AddSchema(url string, loader JSONLoader) error {
return sl.pool.parseReferences(doc, ref, true)
}
+// Compile loads and compiles a schema
func (sl *SchemaLoader) Compile(rootSchema JSONLoader) (*Schema, error) {
ref, err := rootSchema.JsonReference()
diff --git a/vendor/github.com/xeipuuv/gojsonschema/schemaPool.go b/vendor/github.com/xeipuuv/gojsonschema/schemaPool.go
index f124e038d..35b1cc630 100644
--- a/vendor/github.com/xeipuuv/gojsonschema/schemaPool.go
+++ b/vendor/github.com/xeipuuv/gojsonschema/schemaPool.go
@@ -150,12 +150,12 @@ func (p *schemaPool) GetDocument(reference gojsonreference.JsonReference) (*sche
}
// Create a deep copy, so we can remove the fragment part later on without altering the original
- refToUrl, _ := gojsonreference.NewJsonReference(reference.String())
+ refToURL, _ := gojsonreference.NewJsonReference(reference.String())
// First check if the given fragment is a location independent identifier
// http://json-schema.org/latest/json-schema-core.html#rfc.section.8.2.3
- if spd, ok = p.schemaPoolDocuments[refToUrl.String()]; ok {
+ if spd, ok = p.schemaPoolDocuments[refToURL.String()]; ok {
if internalLogEnabled {
internalLog(" From pool")
}
@@ -165,9 +165,9 @@ func (p *schemaPool) GetDocument(reference gojsonreference.JsonReference) (*sche
// If the given reference is not a location independent identifier,
// strip the fragment and look for a document with it's base URI
- refToUrl.GetUrl().Fragment = ""
+ refToURL.GetUrl().Fragment = ""
- if cachedSpd, ok := p.schemaPoolDocuments[refToUrl.String()]; ok {
+ if cachedSpd, ok := p.schemaPoolDocuments[refToURL.String()]; ok {
document, _, err := reference.GetPointer().Get(cachedSpd.Document)
if err != nil {
@@ -200,7 +200,7 @@ func (p *schemaPool) GetDocument(reference gojsonreference.JsonReference) (*sche
}
// add the whole document to the pool for potential re-use
- p.parseReferences(document, refToUrl, true)
+ p.parseReferences(document, refToURL, true)
_, draft, _ = parseSchemaURL(document)
diff --git a/vendor/github.com/xeipuuv/gojsonschema/subSchema.go b/vendor/github.com/xeipuuv/gojsonschema/subSchema.go
index 362d86ca9..ec779812c 100644
--- a/vendor/github.com/xeipuuv/gojsonschema/subSchema.go
+++ b/vendor/github.com/xeipuuv/gojsonschema/subSchema.go
@@ -27,14 +27,12 @@
package gojsonschema
import (
- "errors"
+ "github.com/xeipuuv/gojsonreference"
"math/big"
"regexp"
- "strings"
-
- "github.com/xeipuuv/gojsonreference"
)
+// Constants
const (
KEY_SCHEMA = "$schema"
KEY_ID = "id"
@@ -88,6 +86,9 @@ type subSchema struct {
property string
+ // Quick pass/fail for boolean schemas
+ pass *bool
+
// Types associated with the subSchema
types jsonSchemaType
@@ -146,111 +147,3 @@ type subSchema struct {
_then *subSchema
_else *subSchema
}
-
-func (s *subSchema) AddConst(i interface{}) error {
-
- is, err := marshalWithoutNumber(i)
- if err != nil {
- return err
- }
- s._const = is
- return nil
-}
-
-func (s *subSchema) AddEnum(i interface{}) error {
-
- is, err := marshalWithoutNumber(i)
- if err != nil {
- return err
- }
-
- if isStringInSlice(s.enum, *is) {
- return errors.New(formatErrorDescription(
- Locale.KeyItemsMustBeUnique(),
- ErrorDetails{"key": KEY_ENUM},
- ))
- }
-
- s.enum = append(s.enum, *is)
-
- return nil
-}
-
-func (s *subSchema) ContainsEnum(i interface{}) (bool, error) {
-
- is, err := marshalWithoutNumber(i)
- if err != nil {
- return false, err
- }
-
- return isStringInSlice(s.enum, *is), nil
-}
-
-func (s *subSchema) AddOneOf(subSchema *subSchema) {
- s.oneOf = append(s.oneOf, subSchema)
-}
-
-func (s *subSchema) AddAllOf(subSchema *subSchema) {
- s.allOf = append(s.allOf, subSchema)
-}
-
-func (s *subSchema) AddAnyOf(subSchema *subSchema) {
- s.anyOf = append(s.anyOf, subSchema)
-}
-
-func (s *subSchema) SetNot(subSchema *subSchema) {
- s.not = subSchema
-}
-
-func (s *subSchema) SetIf(subSchema *subSchema) {
- s._if = subSchema
-}
-
-func (s *subSchema) SetThen(subSchema *subSchema) {
- s._then = subSchema
-}
-
-func (s *subSchema) SetElse(subSchema *subSchema) {
- s._else = subSchema
-}
-
-func (s *subSchema) AddRequired(value string) error {
-
- if isStringInSlice(s.required, value) {
- return errors.New(formatErrorDescription(
- Locale.KeyItemsMustBeUnique(),
- ErrorDetails{"key": KEY_REQUIRED},
- ))
- }
-
- s.required = append(s.required, value)
-
- return nil
-}
-
-func (s *subSchema) AddItemsChild(child *subSchema) {
- s.itemsChildren = append(s.itemsChildren, child)
-}
-
-func (s *subSchema) AddPropertiesChild(child *subSchema) {
- s.propertiesChildren = append(s.propertiesChildren, child)
-}
-
-func (s *subSchema) PatternPropertiesString() string {
-
- if s.patternProperties == nil || len(s.patternProperties) == 0 {
- return STRING_UNDEFINED // should never happen
- }
-
- patternPropertiesKeySlice := []string{}
- for pk := range s.patternProperties {
- patternPropertiesKeySlice = append(patternPropertiesKeySlice, `"`+pk+`"`)
- }
-
- if len(patternPropertiesKeySlice) == 1 {
- return patternPropertiesKeySlice[0]
- }
-
- return "[" + strings.Join(patternPropertiesKeySlice, ",") + "]"
-
-}
diff --git a/vendor/github.com/xeipuuv/gojsonschema/types.go b/vendor/github.com/xeipuuv/gojsonschema/types.go
index 952d22ef6..0e6fd5173 100644
--- a/vendor/github.com/xeipuuv/gojsonschema/types.go
+++ b/vendor/github.com/xeipuuv/gojsonschema/types.go
@@ -25,6 +25,7 @@
package gojsonschema
+// Type constants
const (
TYPE_ARRAY = `array`
TYPE_BOOLEAN = `boolean`
@@ -35,7 +36,10 @@ const (
TYPE_STRING = `string`
)
+// JSON_TYPES hosts the list of type that are supported in JSON
var JSON_TYPES []string
+
+// SCHEMA_TYPES hosts the list of type that are supported in schemas
var SCHEMA_TYPES []string
func init() {
diff --git a/vendor/github.com/xeipuuv/gojsonschema/utils.go b/vendor/github.com/xeipuuv/gojsonschema/utils.go
index 88d223fbf..a17d22e3b 100644
--- a/vendor/github.com/xeipuuv/gojsonschema/utils.go
+++ b/vendor/github.com/xeipuuv/gojsonschema/utils.go
@@ -27,15 +27,13 @@ package gojsonschema
import (
"encoding/json"
- "fmt"
- "math"
"math/big"
"reflect"
)
func isKind(what interface{}, kinds ...reflect.Kind) bool {
target := what
- if isJsonNumber(what) {
+ if isJSONNumber(what) {
// JSON Numbers are strings!
target = *mustBeNumber(what)
}
@@ -72,7 +70,7 @@ func indexStringInSlice(s []string, what string) int {
return -1
}
-func marshalToJsonString(value interface{}) (*string, error) {
+func marshalToJSONString(value interface{}) (*string, error) {
mBytes, err := json.Marshal(value)
if err != nil {
@@ -90,7 +88,7 @@ func marshalWithoutNumber(value interface{}) (*string, error) {
// One way to eliminate these differences is to decode and encode the JSON one more time without Decoder.UseNumber
// so that these differences in representation are removed
- jsonString, err := marshalToJsonString(value)
+ jsonString, err := marshalToJSONString(value)
if err != nil {
return nil, err
}
@@ -102,10 +100,10 @@ func marshalWithoutNumber(value interface{}) (*string, error) {
return nil, err
}
- return marshalToJsonString(document)
+ return marshalToJSONString(document)
}
-func isJsonNumber(what interface{}) bool {
+func isJSONNumber(what interface{}) bool {
switch what.(type) {
@@ -116,7 +114,7 @@ func isJsonNumber(what interface{}) bool {
return false
}
-func checkJsonInteger(what interface{}) (isInt bool) {
+func checkJSONInteger(what interface{}) (isInt bool) {
jsonNumber := what.(json.Number)
@@ -128,26 +126,17 @@ func checkJsonInteger(what interface{}) (isInt bool) {
// same as ECMA Number.MAX_SAFE_INTEGER and Number.MIN_SAFE_INTEGER
const (
- max_json_float = float64(1<<53 - 1) // 9007199254740991.0 2^53 - 1
- min_json_float = -float64(1<<53 - 1) //-9007199254740991.0 -2^53 - 1
+ maxJSONFloat = float64(1<<53 - 1) // 9007199254740991.0 2^53 - 1
+ minJSONFloat = -float64(1<<53 - 1) //-9007199254740991.0 -2^53 - 1
)
-func isFloat64AnInteger(f float64) bool {
-
- if math.IsNaN(f) || math.IsInf(f, 0) || f < min_json_float || f > max_json_float {
- return false
- }
-
- return f == float64(int64(f)) || f == float64(uint64(f))
-}
-
func mustBeInteger(what interface{}) *int {
- if isJsonNumber(what) {
+ if isJSONNumber(what) {
number := what.(json.Number)
- isInt := checkJsonInteger(number)
+ isInt := checkJSONInteger(number)
if isInt {
@@ -158,9 +147,6 @@ func mustBeInteger(what interface{}) *int {
int32Value := int(int64Value)
return &int32Value
-
- } else {
- return nil
}
}
@@ -170,43 +156,18 @@ func mustBeInteger(what interface{}) *int {
func mustBeNumber(what interface{}) *big.Rat {
- if isJsonNumber(what) {
+ if isJSONNumber(what) {
number := what.(json.Number)
float64Value, success := new(big.Rat).SetString(string(number))
if success {
return float64Value
- } else {
- return nil
}
-
}
return nil
}
-// formats a number so that it is displayed as the smallest string possible
-func resultErrorFormatJsonNumber(n json.Number) string {
-
- if int64Value, err := n.Int64(); err == nil {
- return fmt.Sprintf("%d", int64Value)
- }
-
- float64Value, _ := n.Float64()
-
- return fmt.Sprintf("%g", float64Value)
-}
-
-// formats a number so that it is displayed as the smallest string possible
-func resultErrorFormatNumber(n float64) string {
-
- if isFloat64AnInteger(n) {
- return fmt.Sprintf("%d", int64(n))
- }
-
- return fmt.Sprintf("%g", n)
-}
-
func convertDocumentNode(val interface{}) interface{} {
if lval, ok := val.([]interface{}); ok {
diff --git a/vendor/github.com/xeipuuv/gojsonschema/validation.go b/vendor/github.com/xeipuuv/gojsonschema/validation.go
index 090c11e93..74091bca1 100644
--- a/vendor/github.com/xeipuuv/gojsonschema/validation.go
+++ b/vendor/github.com/xeipuuv/gojsonschema/validation.go
@@ -35,42 +35,29 @@ import (
"unicode/utf8"
)
+// Validate loads and validates a JSON schema
func Validate(ls JSONLoader, ld JSONLoader) (*Result, error) {
-
- var err error
-
// load schema
-
schema, err := NewSchema(ls)
if err != nil {
return nil, err
}
-
- // begine validation
-
return schema.Validate(ld)
-
}
+// Validate loads and validates a JSON document
func (v *Schema) Validate(l JSONLoader) (*Result, error) {
-
- // load document
-
root, err := l.LoadJSON()
if err != nil {
return nil, err
}
-
return v.validateDocument(root), nil
}
func (v *Schema) validateDocument(root interface{}) *Result {
- // begin validation
-
result := &Result{}
context := NewJsonContext(STRING_CONTEXT_ROOT, nil)
v.rootSchema.validateRecursive(v.rootSchema, root, result, context)
-
return result
}
@@ -88,6 +75,19 @@ func (v *subSchema) validateRecursive(currentSubSchema *subSchema, currentNode i
internalLog(" %v", currentNode)
}
+ // Handle true/false schema as early as possible as all other fields will be nil
+ if currentSubSchema.pass != nil {
+ if !*currentSubSchema.pass {
+ result.addInternalError(
+ new(FalseError),
+ context,
+ currentNode,
+ ErrorDetails{},
+ )
+ }
+ return
+ }
+
// Handle referenced schemas, returns directly when a $ref is found
if currentSubSchema.refSchema != nil {
v.validateRecursive(currentSubSchema.refSchema, currentNode, result, context)
@@ -114,11 +114,11 @@ func (v *subSchema) validateRecursive(currentSubSchema *subSchema, currentNode i
} else { // Not a null value
- if isJsonNumber(currentNode) {
+ if isJSONNumber(currentNode) {
value := currentNode.(json.Number)
- isInt := checkJsonInteger(value)
+ isInt := checkJSONInteger(value)
validType := currentSubSchema.types.Contains(TYPE_NUMBER) || (isInt && currentSubSchema.types.Contains(TYPE_INTEGER))
@@ -424,11 +424,11 @@ func (v *subSchema) validateCommon(currentSubSchema *subSchema, value interface{
// enum:
if len(currentSubSchema.enum) > 0 {
- has, err := currentSubSchema.ContainsEnum(value)
+ vString, err := marshalWithoutNumber(value)
if err != nil {
result.addInternalError(new(InternalError), context, value, ErrorDetails{"error": err})
}
- if !has {
+ if !isStringInSlice(currentSubSchema.enum, *vString) {
result.addInternalError(
new(EnumError),
context,
@@ -516,13 +516,13 @@ func (v *subSchema) validateArray(currentSubSchema *subSchema, value []interface
// uniqueItems:
if currentSubSchema.uniqueItems {
- var stringifiedItems []string
+ var stringifiedItems = make(map[string]int)
for j, v := range value {
vString, err := marshalWithoutNumber(v)
if err != nil {
result.addInternalError(new(InternalError), context, value, ErrorDetails{"err": err})
}
- if i := indexStringInSlice(stringifiedItems, *vString); i > -1 {
+ if i, ok := stringifiedItems[*vString]; ok {
result.addInternalError(
new(ItemsMustBeUniqueError),
context,
@@ -530,7 +530,7 @@ func (v *subSchema) validateArray(currentSubSchema *subSchema, value []interface
ErrorDetails{"type": TYPE_ARRAY, "i": i, "j": j},
)
}
- stringifiedItems = append(stringifiedItems, *vString)
+ stringifiedItems[*vString] = j
}
}
@@ -614,101 +614,37 @@ func (v *subSchema) validateObject(currentSubSchema *subSchema, value map[string
}
// additionalProperty & patternProperty:
- if currentSubSchema.additionalProperties != nil {
-
- switch currentSubSchema.additionalProperties.(type) {
- case bool:
-
- if !currentSubSchema.additionalProperties.(bool) {
-
- for pk := range value {
-
- found := false
- for _, spValue := range currentSubSchema.propertiesChildren {
- if pk == spValue.property {
- found = true
- }
- }
-
- pp_has, pp_match := v.validatePatternProperty(currentSubSchema, pk, value[pk], result, context)
-
- if found {
-
- if pp_has && !pp_match {
- result.addInternalError(
- new(AdditionalPropertyNotAllowedError),
- context,
- value[pk],
- ErrorDetails{"property": pk},
- )
- }
-
- } else {
-
- if !pp_has || !pp_match {
- result.addInternalError(
- new(AdditionalPropertyNotAllowedError),
- context,
- value[pk],
- ErrorDetails{"property": pk},
- )
- }
-
- }
- }
- }
-
- case *subSchema:
-
- additionalPropertiesSchema := currentSubSchema.additionalProperties.(*subSchema)
- for pk := range value {
-
- found := false
- for _, spValue := range currentSubSchema.propertiesChildren {
- if pk == spValue.property {
- found = true
- }
- }
-
- pp_has, pp_match := v.validatePatternProperty(currentSubSchema, pk, value[pk], result, context)
-
- if found {
-
- if pp_has && !pp_match {
- validationResult := additionalPropertiesSchema.subValidateWithContext(value[pk], context)
- result.mergeErrors(validationResult)
- }
-
- } else {
-
- if !pp_has || !pp_match {
- validationResult := additionalPropertiesSchema.subValidateWithContext(value[pk], context)
- result.mergeErrors(validationResult)
- }
-
- }
+ for pk := range value {
+ // Check whether this property is described by "properties"
+ found := false
+ for _, spValue := range currentSubSchema.propertiesChildren {
+ if pk == spValue.property {
+ found = true
}
}
- } else {
- for pk := range value {
-
- pp_has, pp_match := v.validatePatternProperty(currentSubSchema, pk, value[pk], result, context)
+ // Check whether this property is described by "patternProperties"
+ ppMatch := v.validatePatternProperty(currentSubSchema, pk, value[pk], result, context)
- if pp_has && !pp_match {
+ // If it is not described by neither "properties" nor "patternProperties" it must pass "additionalProperties"
+ if !found && !ppMatch {
+ switch ap := currentSubSchema.additionalProperties.(type) {
+ case bool:
+ // Handle the boolean case separately as it's cleaner to return a specific error than failing to pass the false schema
+ if !ap {
+ result.addInternalError(
+ new(AdditionalPropertyNotAllowedError),
+ context,
+ value[pk],
+ ErrorDetails{"property": pk},
+ )
- result.addInternalError(
- new(InvalidPropertyPatternError),
- context,
- value[pk],
- ErrorDetails{
- "property": pk,
- "pattern": currentSubSchema.PatternPropertiesString(),
- },
- )
+ }
+ case *subSchema:
+ validationResult := ap.subValidateWithContext(value[pk], NewJsonContext(pk, context))
+ result.mergeErrors(validationResult)
}
-
}
}
@@ -730,40 +666,36 @@ func (v *subSchema) validateObject(currentSubSchema *subSchema, value map[string
result.incrementScore()
}
-func (v *subSchema) validatePatternProperty(currentSubSchema *subSchema, key string, value interface{}, result *Result, context *JsonContext) (has bool, matched bool) {
+func (v *subSchema) validatePatternProperty(currentSubSchema *subSchema, key string, value interface{}, result *Result, context *JsonContext) bool {
if internalLogEnabled {
internalLog("validatePatternProperty %s", context.String())
internalLog(" %s %v", key, value)
}
- has = false
-
- validatedkey := false
+ validated := false
for pk, pv := range currentSubSchema.patternProperties {
if matches, _ := regexp.MatchString(pk, key); matches {
- has = true
+ validated = true
subContext := NewJsonContext(key, context)
validationResult := pv.subValidateWithContext(value, subContext)
result.mergeErrors(validationResult)
- validatedkey = true
}
}
- if !validatedkey {
- return has, false
+ if !validated {
+ return false
}
result.incrementScore()
-
- return has, true
+ return true
}
func (v *subSchema) validateString(currentSubSchema *subSchema, value interface{}, result *Result, context *JsonContext) {
// Ignore JSON numbers
- if isJsonNumber(value) {
+ if isJSONNumber(value) {
return
}
@@ -832,7 +764,7 @@ func (v *subSchema) validateString(currentSubSchema *subSchema, value interface{
func (v *subSchema) validateNumber(currentSubSchema *subSchema, value interface{}, result *Result, context *JsonContext) {
// Ignore non numbers
- if !isJsonNumber(value) {
+ if !isJSONNumber(value) {
return
}
@@ -850,8 +782,10 @@ func (v *subSchema) validateNumber(currentSubSchema *subSchema, value interface{
result.addInternalError(
new(MultipleOfError),
context,
- resultErrorFormatJsonNumber(number),
- ErrorDetails{"multiple": new(big.Float).SetRat(currentSubSchema.multipleOf)},
+ number,
+ ErrorDetails{
+ "multiple": new(big.Float).SetRat(currentSubSchema.multipleOf),
+ },
)
}
}
@@ -862,9 +796,9 @@ func (v *subSchema) validateNumber(currentSubSchema *subSchema, value interface{
result.addInternalError(
new(NumberLTEError),
context,
- resultErrorFormatJsonNumber(number),
+ number,
ErrorDetails{
- "max": currentSubSchema.maximum,
+ "max": new(big.Float).SetRat(currentSubSchema.maximum),
},
)
}
@@ -874,9 +808,9 @@ func (v *subSchema) validateNumber(currentSubSchema *subSchema, value interface{
result.addInternalError(
new(NumberLTError),
context,
- resultErrorFormatJsonNumber(number),
+ number,
ErrorDetails{
- "max": currentSubSchema.exclusiveMaximum,
+ "max": new(big.Float).SetRat(currentSubSchema.exclusiveMaximum),
},
)
}
@@ -888,22 +822,21 @@ func (v *subSchema) validateNumber(currentSubSchema *subSchema, value interface{
result.addInternalError(
new(NumberGTEError),
context,
- resultErrorFormatJsonNumber(number),
+ number,
ErrorDetails{
- "min": currentSubSchema.minimum,
+ "min": new(big.Float).SetRat(currentSubSchema.minimum),
},
)
}
}
if currentSubSchema.exclusiveMinimum != nil {
if float64Value.Cmp(currentSubSchema.exclusiveMinimum) <= 0 {
- // if float64Value <= *currentSubSchema.minimum {
result.addInternalError(
new(NumberGTError),
context,
- resultErrorFormatJsonNumber(number),
+ number,
ErrorDetails{
- "min": currentSubSchema.exclusiveMinimum,
+ "min": new(big.Float).SetRat(currentSubSchema.exclusiveMinimum),
},
)
}