summaryrefslogtreecommitdiff
path: root/vendor/github.com
diff options
context:
space:
mode:
authorDaniel J Walsh <dwalsh@redhat.com>2021-06-16 05:57:09 -0400
committerDaniel J Walsh <dwalsh@redhat.com>2021-06-17 14:59:42 -0400
commitb6662eed3f27ac5466501b046db4f1608845af61 (patch)
tree7a4f80a77f812505a6261bc11ed8151235f903f1 /vendor/github.com
parent725b5001a17f703d95a3c88e4f58225c5290576b (diff)
downloadpodman-b6662eed3f27ac5466501b046db4f1608845af61.tar.gz
podman-b6662eed3f27ac5466501b046db4f1608845af61.tar.bz2
podman-b6662eed3f27ac5466501b046db4f1608845af61.zip
Vendor in containers/common v0.40.0
Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>
Diffstat (limited to 'vendor/github.com')
-rw-r--r--vendor/github.com/containers/common/libimage/import.go10
-rw-r--r--vendor/github.com/containers/common/libimage/pull.go2
-rw-r--r--vendor/github.com/containers/common/libimage/runtime.go12
-rw-r--r--vendor/github.com/containers/common/pkg/auth/auth.go6
-rw-r--r--vendor/github.com/containers/common/pkg/auth/cli.go2
-rw-r--r--vendor/github.com/containers/common/pkg/config/config.go71
-rw-r--r--vendor/github.com/containers/common/pkg/config/containers.conf170
-rw-r--r--vendor/github.com/containers/common/pkg/config/default.go16
-rw-r--r--vendor/github.com/containers/common/pkg/report/template.go6
-rw-r--r--vendor/github.com/containers/common/pkg/seccomp/conversion.go1
-rw-r--r--vendor/github.com/containers/common/pkg/seccomp/default_linux.go192
-rw-r--r--vendor/github.com/containers/common/pkg/seccomp/filter.go2
-rw-r--r--vendor/github.com/containers/common/pkg/seccomp/seccomp.json227
-rw-r--r--vendor/github.com/containers/common/pkg/seccomp/seccomp_linux.go1
-rw-r--r--vendor/github.com/containers/common/pkg/seccomp/types.go3
-rw-r--r--vendor/github.com/containers/common/pkg/secrets/passdriver/passdriver.go176
-rw-r--r--vendor/github.com/containers/common/pkg/secrets/secrets.go6
-rw-r--r--vendor/github.com/containers/common/version/version.go2
-rw-r--r--vendor/github.com/containers/image/v5/copy/copy.go53
-rw-r--r--vendor/github.com/containers/image/v5/internal/pkg/platform/platform_matcher.go2
-rw-r--r--vendor/github.com/containers/image/v5/internal/types/types.go4
-rw-r--r--vendor/github.com/containers/image/v5/pkg/docker/config/config.go50
-rw-r--r--vendor/github.com/containers/image/v5/pkg/docker/config/config_linux.go12
-rw-r--r--vendor/github.com/containers/image/v5/pkg/docker/config/config_unsupported.go8
-rw-r--r--vendor/github.com/containers/image/v5/pkg/shortnames/shortnames.go4
-rw-r--r--vendor/github.com/containers/image/v5/storage/storage_image.go91
-rw-r--r--vendor/github.com/containers/image/v5/version/version.go4
-rw-r--r--vendor/github.com/docker/docker-credential-helpers/client/command.go3
-rw-r--r--vendor/github.com/docker/docker-credential-helpers/credentials/version.go2
-rw-r--r--vendor/github.com/imdario/mergo/.travis.yml3
-rw-r--r--vendor/github.com/imdario/mergo/README.md2
-rw-r--r--vendor/github.com/imdario/mergo/merge.go9
-rw-r--r--vendor/github.com/jinzhu/copier/README.md9
-rw-r--r--vendor/github.com/jinzhu/copier/copier.go174
-rw-r--r--vendor/github.com/klauspost/compress/zstd/blockdec.go4
-rw-r--r--vendor/github.com/klauspost/compress/zstd/decoder_options.go25
-rw-r--r--vendor/github.com/klauspost/compress/zstd/framedec.go32
-rw-r--r--vendor/github.com/mattn/go-runewidth/go.mod2
-rw-r--r--vendor/github.com/mattn/go-runewidth/go.sum4
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/.gitignore5
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/.travis.yml11
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/README.md121
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/UNLICENSE24
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/bar.go492
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/bar_filler.go39
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/bar_filler_bar.go219
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/bar_filler_spinner.go87
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/bar_option.go153
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/container_option.go112
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/cwriter/doc.go2
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/cwriter/util_bsd.go7
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/cwriter/util_linux.go7
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/cwriter/util_solaris.go7
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/cwriter/writer.go84
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/cwriter/writer_posix.go26
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/cwriter/writer_windows.go73
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/decor/any.go21
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/decor/counters.go243
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/decor/decorator.go191
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/decor/doc.go19
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/decor/elapsed.go35
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/decor/eta.go203
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/decor/merge.go107
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/decor/moving_average.go68
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/decor/name.go12
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/decor/on_complete.go37
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/decor/percentage.go58
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/decor/size_type.go109
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/decor/sizeb1000_string.go41
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/decor/sizeb1024_string.go41
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/decor/speed.go171
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/decor/spinner.go21
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/doc.go2
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/go.mod10
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/go.sum10
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/internal/percentage.go19
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/internal/predicate.go6
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/internal/width.go10
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/priority_queue.go32
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/progress.go412
-rw-r--r--vendor/github.com/vbauerster/mpb/v7/proxyreader.go90
81 files changed, 4570 insertions, 269 deletions
diff --git a/vendor/github.com/containers/common/libimage/import.go b/vendor/github.com/containers/common/libimage/import.go
index 4cce4c9ca..2addfdf98 100644
--- a/vendor/github.com/containers/common/libimage/import.go
+++ b/vendor/github.com/containers/common/libimage/import.go
@@ -23,6 +23,10 @@ type ImportOptions struct {
CommitMessage string
// Tag the imported image with this value.
Tag string
+ // Overwrite OS of imported image.
+ OS string
+ // Overwrite Arch of imported image.
+ Arch string
}
// Import imports a custom tarball at the specified path. Returns the name of
@@ -48,8 +52,10 @@ func (r *Runtime) Import(ctx context.Context, path string, options *ImportOption
}
config := v1.Image{
- Config: ic,
- History: hist,
+ Config: ic,
+ History: hist,
+ OS: options.OS,
+ Architecture: options.Arch,
}
u, err := url.ParseRequestURI(path)
diff --git a/vendor/github.com/containers/common/libimage/pull.go b/vendor/github.com/containers/common/libimage/pull.go
index acf5c818f..0271f0051 100644
--- a/vendor/github.com/containers/common/libimage/pull.go
+++ b/vendor/github.com/containers/common/libimage/pull.go
@@ -351,7 +351,7 @@ func (r *Runtime) copySingleImageFromRegistry(ctx context.Context, imageName str
// attempt pulling that instead of doing the full short-name dance.
localImage, resolvedImageName, err = r.LookupImage(imageName, nil)
if err != nil && errors.Cause(err) != storage.ErrImageUnknown {
- return nil, errors.Wrap(err, "error looking up local image")
+ logrus.Errorf("Looking up %s in local storage: %v", imageName, err)
}
if pullPolicy == config.PullPolicyNever {
diff --git a/vendor/github.com/containers/common/libimage/runtime.go b/vendor/github.com/containers/common/libimage/runtime.go
index bbf1c2a61..93a42eb55 100644
--- a/vendor/github.com/containers/common/libimage/runtime.go
+++ b/vendor/github.com/containers/common/libimage/runtime.go
@@ -132,13 +132,21 @@ func (r *Runtime) storageToImage(storageImage *storage.Image, ref types.ImageRef
}
// Exists returns true if the specicifed image exists in the local containers
-// storage.
+// storage. Note that it may return false if an image corrupted.
func (r *Runtime) Exists(name string) (bool, error) {
image, _, err := r.LookupImage(name, &LookupImageOptions{IgnorePlatform: true})
if err != nil && errors.Cause(err) != storage.ErrImageUnknown {
return false, err
}
- return image != nil, nil
+ if image == nil {
+ return false, nil
+ }
+ // Inspect the image to make sure if it's corrupted or not.
+ if _, err := image.Inspect(context.Background(), false); err != nil {
+ logrus.Errorf("Image %s exists in local storage but may be corrupted: %v", name, err)
+ return false, nil
+ }
+ return true, nil
}
// LookupImageOptions allow for customizing local image lookups.
diff --git a/vendor/github.com/containers/common/pkg/auth/auth.go b/vendor/github.com/containers/common/pkg/auth/auth.go
index a9ad60f43..d2e75c1f7 100644
--- a/vendor/github.com/containers/common/pkg/auth/auth.go
+++ b/vendor/github.com/containers/common/pkg/auth/auth.go
@@ -134,9 +134,13 @@ func Login(ctx context.Context, systemContext *types.SystemContext, opts *LoginO
if err = docker.CheckAuth(ctx, systemContext, username, password, server); err == nil {
// Write the new credentials to the authfile
- if err := config.SetAuthentication(systemContext, server, username, password); err != nil {
+ desc, err := config.SetCredentials(systemContext, server, username, password)
+ if err != nil {
return err
}
+ if opts.Verbose {
+ fmt.Fprintln(opts.Stdout, "Used: ", desc)
+ }
}
if err == nil {
fmt.Fprintln(opts.Stdout, "Login Succeeded!")
diff --git a/vendor/github.com/containers/common/pkg/auth/cli.go b/vendor/github.com/containers/common/pkg/auth/cli.go
index 1d8eed4ac..5a7c1137c 100644
--- a/vendor/github.com/containers/common/pkg/auth/cli.go
+++ b/vendor/github.com/containers/common/pkg/auth/cli.go
@@ -20,6 +20,7 @@ type LoginOptions struct {
Username string
StdinPassword bool
GetLoginSet bool
+ Verbose bool // set to true for verbose output
// Options caller can set
Stdin io.Reader // set to os.Stdin
Stdout io.Writer // set to os.Stdout
@@ -47,6 +48,7 @@ func GetLoginFlags(flags *LoginOptions) *pflag.FlagSet {
fs.StringVarP(&flags.Username, "username", "u", "", "Username for registry")
fs.BoolVar(&flags.StdinPassword, "password-stdin", false, "Take the password from stdin")
fs.BoolVar(&flags.GetLoginSet, "get-login", false, "Return the current login user for the registry")
+ fs.BoolVarP(&flags.Verbose, "verbose", "v", false, "Write more detailed information to stdout")
return &fs
}
diff --git a/vendor/github.com/containers/common/pkg/config/config.go b/vendor/github.com/containers/common/pkg/config/config.go
index edd52f49d..0d23d6ac6 100644
--- a/vendor/github.com/containers/common/pkg/config/config.go
+++ b/vendor/github.com/containers/common/pkg/config/config.go
@@ -5,6 +5,7 @@ import (
"os"
"os/exec"
"path/filepath"
+ "sort"
"strings"
"sync"
@@ -23,7 +24,7 @@ const (
_configPath = "containers/containers.conf"
// DefaultContainersConfig holds the default containers config path
DefaultContainersConfig = "/usr/share/" + _configPath
- // OverrideContainersConfig holds the default config paths overridden by the root user
+ // OverrideContainersConfig holds the default config path overridden by the root user
OverrideContainersConfig = "/etc/" + _configPath
// UserOverrideContainersConfig holds the containers config path overridden by the rootless user
UserOverrideContainersConfig = ".config/" + _configPath
@@ -55,6 +56,8 @@ type Config struct {
Engine EngineConfig `toml:"engine"`
// Network section defines the configuration of CNI Plugins
Network NetworkConfig `toml:"network"`
+ // Secret section defines configurations for the secret management
+ Secrets SecretConfig `toml:"secrets"`
}
// ContainersConfig represents the "containers" TOML config table
@@ -137,6 +140,11 @@ type ContainersConfig struct {
// Negative values indicate that the log file won't be truncated.
LogSizeMax int64 `toml:"log_size_max,omitempty"`
+ // Specifies default format tag for container log messages.
+ // This is useful for creating a specific tag for container log messages.
+ // Containers logs default to truncated container ID as a tag.
+ LogTag string `toml:"log_tag,omitempty"`
+
// NetNS indicates how to create a network namespace for the container
NetNS string `toml:"netns,omitempty"`
@@ -440,6 +448,17 @@ type NetworkConfig struct {
NetworkConfigDir string `toml:"network_config_dir,omitempty"`
}
+// SecretConfig represents the "secret" TOML config table
+type SecretConfig struct {
+ // Driver specifies the secret driver to use.
+ // Current valid value:
+ // * file
+ // * pass
+ Driver string `toml:"driver,omitempty"`
+ // Opts contains driver specific options
+ Opts map[string]string `toml:"opts,omitempty"`
+}
+
// Destination represents destination for remote service
type Destination struct {
// URI, required. Example: ssh://root@example.com:22/run/podman/podman.sock
@@ -513,10 +532,49 @@ func readConfigFromFile(path string, config *Config) error {
return nil
}
+// addConfigs will search one level in the config dirPath for config files
+// If the dirPath does not exist, addConfigs will return nil
+func addConfigs(dirPath string, configs []string) ([]string, error) {
+ newConfigs := []string{}
+
+ err := filepath.Walk(dirPath,
+ // WalkFunc to read additional configs
+ func(path string, info os.FileInfo, err error) error {
+ switch {
+ case err != nil:
+ // return error (could be a permission problem)
+ return err
+ case info == nil:
+ // this should only happen when err != nil but let's be sure
+ return nil
+ case info.IsDir():
+ if path != dirPath {
+ // make sure to not recurse into sub-directories
+ return filepath.SkipDir
+ }
+ // ignore directories
+ return nil
+ default:
+ // only add *.conf files
+ if strings.HasSuffix(path, ".conf") {
+ newConfigs = append(newConfigs, path)
+ }
+ return nil
+ }
+ },
+ )
+ if os.IsNotExist(err) {
+ err = nil
+ }
+ sort.Strings(newConfigs)
+ return append(configs, newConfigs...), 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) {
+ var err error
configs := []string{}
path := os.Getenv("CONTAINERS_CONF")
if path != "" {
@@ -531,7 +589,12 @@ func systemConfigs() ([]string, error) {
if _, err := os.Stat(OverrideContainersConfig); err == nil {
configs = append(configs, OverrideContainersConfig)
}
- path, err := ifRootlessConfigPath()
+ configs, err = addConfigs(OverrideContainersConfig+".d", configs)
+ if err != nil {
+ return nil, err
+ }
+
+ path, err = ifRootlessConfigPath()
if err != nil {
return nil, err
}
@@ -539,6 +602,10 @@ func systemConfigs() ([]string, error) {
if _, err := os.Stat(path); err == nil {
configs = append(configs, path)
}
+ configs, err = addConfigs(path+".d", configs)
+ if err != nil {
+ return nil, err
+ }
}
return configs, nil
}
diff --git a/vendor/github.com/containers/common/pkg/config/containers.conf b/vendor/github.com/containers/common/pkg/config/containers.conf
index d9b379eae..0c8c7532e 100644
--- a/vendor/github.com/containers/common/pkg/config/containers.conf
+++ b/vendor/github.com/containers/common/pkg/config/containers.conf
@@ -16,30 +16,16 @@
[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
+# List of annotation. Specified as
+# "key = value"
+# If it is empty or commented out, no annotations will be added
#
-# volumes = []
+# annotations = []
# 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.
@@ -93,6 +79,13 @@ default_sysctls = [
# "nofile=1280:2560",
# ]
+# 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 default DNS options to be added to /etc/resolv.conf inside of the container.
#
# dns_options = []
@@ -166,6 +159,12 @@ default_sysctls = [
#
# log_size_max = -1
+# Specifies default format tag for container log messages.
+# This is useful for creating a specific tag for container log messages.
+# Containers logs default to truncated container ID as a tag.
+#
+# log_tag = ""
+
# Default way to to create a Network namespace for the container
# Options are:
# `private` Create private Network Namespace for the container.
@@ -179,10 +178,6 @@ default_sysctls = [
#
# 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.
@@ -190,6 +185,13 @@ default_sysctls = [
#
# pidns = "private"
+# Maximum number of processes allowed in a container.
+#
+# pids_limit = 2048
+
+# Indicates the networking to be used for rootless containers
+# rootless_networking = "slirp4netns"
+
# Path to the seccomp.json profile which is used as the default seccomp profile
# for the runtime.
#
@@ -209,14 +211,7 @@ default_sysctls = [
# Set umask inside the container
#
-# umask="0022"
-
-# 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"
+# umask = "0022"
# Default way to to create a User namespace for the container
# Options are:
@@ -229,7 +224,21 @@ default_sysctls = [
# UIDs are allocated from the "container" UIDs listed in
# /etc/subuid & /etc/subgid
#
-# userns_size=65536
+# userns_size = 65536
+
+# 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"
+
+# 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 = []
# The network table contains settings pertaining to the management of
# CNI plugins.
@@ -254,14 +263,8 @@ default_sysctls = [
# network_config_dir = "/etc/cni/net.d/"
[engine]
-# Maximum number of image layers to be copied (pulled/pushed) simultaneously.
-# Not setting this field, or setting it to zero, will fall back to containers/image defaults.
-# image_parallel_copies=0
-
-# Manifest Type (oci, v2s2, or v2s1) to use when pulling, pushing, building
-# container images. By default image pulled and pushed match the format of the
-# source image. Building/committing defaults to OCI.
-# image_default_format = ""
+# Index to the active service
+# active_service = production
# Cgroup management implementation used for the runtime.
# Valid options "systemd" or "cgroupfs"
@@ -319,10 +322,19 @@ default_sysctls = [
# "/usr/share/containers/oci/hooks.d",
# ]
+# Manifest Type (oci, v2s2, or v2s1) to use when pulling, pushing, building
+# container images. By default image pulled and pushed match the format of the
+# source image. Building/committing defaults to OCI.
+# image_default_format = ""
+
# Default transport method for pulling and pushing for images
#
# image_default_transport = "docker://"
+# Maximum number of image layers to be copied (pulled/pushed) simultaneously.
+# Not setting this field, or setting it to zero, will fall back to containers/image defaults.
+# image_parallel_copies = 0
+
# Default command to run the infra container
#
# infra_command = "/pause"
@@ -345,7 +357,7 @@ default_sysctls = [
# Indicates if Podman is running inside a VM via Podman Machine.
# Podman uses this value to do extra setup around networking from the
# container inside the VM to to host.
-# machine_enabled=false
+# machine_enabled = false
# MultiImageArchive - if true, the container engine allows for storing archives
# (e.g., of the docker-archive transport) with multiple images. By default,
@@ -364,12 +376,12 @@ default_sysctls = [
# Path to the slirp4netns binary
#
-# network_cmd_path=""
+# network_cmd_path = ""
# Default options to pass to the slirp4netns binary.
# For example "allow_host_loopback=true"
#
-# network_cmd_options=[]
+# network_cmd_options = []
# Whether to use chroot instead of pivot_root in the runtime
#
@@ -389,27 +401,6 @@ default_sysctls = [
# `podman --remote=true` for access to the remote Podman service.
# remote = false
-# Indicates the networking to be used for rootless containers
-# rootless_networking="slirp4netns"
-
-# 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 = "/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 = "crun"
@@ -419,20 +410,24 @@ default_sysctls = [
#
# runtime_supports_json = ["crun", "runc", "kata", "runsc"]
+# List of the OCI runtimes that supports running containers with KVM Separation.
+#
+# runtime_supports_kvm = ["kata"]
+
# List of the OCI runtimes that supports running containers without cgroups.
#
# runtime_supports_nocgroups = ["crun"]
-# List of the OCI runtimes that supports running containers with KVM Separation.
+# 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
#
-# runtime_supports_kvm = ["kata"]
+# static_dir = "/var/lib/containers/storage/libpod"
# Number of seconds to wait for container to exit before sending kill signal.
# stop_timeout = 10
-# Index to the active service
-# active_service = production
-
# map of service destinations
# [service_destinations]
# [service_destinations.production]
@@ -442,10 +437,21 @@ default_sysctls = [
# rootfull "unix://run/podman/podman.sock (Default)
# remote rootless ssh://engineering.lab.company.com/run/user/1000/podman/podman.sock
# remote rootfull ssh://root@10.10.1.136:22/run/podman/podman.sock
-# uri="ssh://user@production.example.com/run/user/1001/podman/podman.sock"
+# uri = "ssh://user@production.example.com/run/user/1001/podman/podman.sock"
# Path to file containing ssh identity key
# identity = "~/.ssh/id_rsa"
+# Directory for temporary files. Must be tmpfs (wiped after reboot)
+#
+# tmp_dir = "/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"
+
# Paths to look for a valid OCI runtime (crun, runc, kata, runsc, etc)
[engine.runtimes]
# crun = [
@@ -458,16 +464,6 @@ default_sysctls = [
# "/run/current-system/sw/bin/crun",
# ]
-# 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",
-# ]
-
# kata = [
# "/usr/bin/kata-runtime",
# "/usr/sbin/kata-runtime",
@@ -479,6 +475,16 @@ default_sysctls = [
# "/usr/bin/kata-fc",
# ]
+# 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",
+# ]
+
# runsc = [
# "/usr/bin/runsc",
# "/usr/sbin/runsc",
@@ -497,3 +503,9 @@ default_sysctls = [
# 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 [volume_plugins] and not the
# main config.
+
+[secret]
+# driver = "file"
+
+[secret.opts]
+# root = "/example/directory"
diff --git a/vendor/github.com/containers/common/pkg/config/default.go b/vendor/github.com/containers/common/pkg/config/default.go
index d5a7d5b84..5abb6326f 100644
--- a/vendor/github.com/containers/common/pkg/config/default.go
+++ b/vendor/github.com/containers/common/pkg/config/default.go
@@ -144,8 +144,6 @@ func DefaultConfig() (*Config, error) {
return nil, err
}
- netns := "bridge"
-
cniConfig := _cniConfigDir
defaultEngineConfig.SignaturePolicyPath = DefaultSignaturePolicyPath
@@ -161,7 +159,6 @@ func DefaultConfig() (*Config, error) {
defaultEngineConfig.SignaturePolicyPath = DefaultSignaturePolicyPath
}
}
- netns = "slirp4netns"
cniConfig = filepath.Join(configHome, _cniConfigDirRootless)
}
@@ -197,12 +194,10 @@ func DefaultConfig() (*Config, error) {
IPCNS: "private",
LogDriver: defaultLogDriver(),
LogSizeMax: DefaultLogSizeMax,
- NetNS: netns,
NoHosts: false,
PidsLimit: DefaultPidsLimit,
PidNS: "private",
RootlessNetworking: DefaultRootlessNetwork,
- SeccompProfile: SeccompDefaultPath,
ShmSize: DefaultShmSize,
TZ: "",
Umask: "0022",
@@ -216,10 +211,19 @@ func DefaultConfig() (*Config, error) {
NetworkConfigDir: cniConfig,
CNIPluginDirs: cniBinDir,
},
- Engine: *defaultEngineConfig,
+ Engine: *defaultEngineConfig,
+ Secrets: defaultSecretConfig(),
}, nil
}
+// defaultSecretConfig returns the default secret configuration.
+// Please note that the default is choosing the "file" driver.
+func defaultSecretConfig() SecretConfig {
+ return SecretConfig{
+ Driver: "file",
+ }
+}
+
// 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) {
diff --git a/vendor/github.com/containers/common/pkg/report/template.go b/vendor/github.com/containers/common/pkg/report/template.go
index f7b4506bb..f86b07034 100644
--- a/vendor/github.com/containers/common/pkg/report/template.go
+++ b/vendor/github.com/containers/common/pkg/report/template.go
@@ -130,7 +130,7 @@ func NewTemplate(name string) *Template {
func (t *Template) Parse(text string) (*Template, error) {
if strings.HasPrefix(text, "table ") {
t.isTable = true
- text = "{{range .}}" + NormalizeFormat(text) + "{{end}}"
+ text = "{{range .}}" + NormalizeFormat(text) + "{{end -}}"
} else {
text = NormalizeFormat(text)
}
@@ -157,12 +157,12 @@ func (t *Template) IsTable() bool {
return t.isTable
}
-var rangeRegex = regexp.MustCompile(`{{\s*range\s*\.\s*}}.*{{\s*end\s*}}`)
+var rangeRegex = regexp.MustCompile(`{{\s*range\s*\.\s*}}.*{{\s*end\s*-?\s*}}`)
// EnforceRange ensures that the format string contains a range
func EnforceRange(format string) string {
if !rangeRegex.MatchString(format) {
- return "{{range .}}" + format + "{{end}}"
+ return "{{range .}}" + format + "{{end -}}"
}
return format
}
diff --git a/vendor/github.com/containers/common/pkg/seccomp/conversion.go b/vendor/github.com/containers/common/pkg/seccomp/conversion.go
index dfab381a5..4c25cb1b1 100644
--- a/vendor/github.com/containers/common/pkg/seccomp/conversion.go
+++ b/vendor/github.com/containers/common/pkg/seccomp/conversion.go
@@ -118,6 +118,7 @@ func specToSeccomp(spec *specs.LinuxSeccomp) (*Seccomp, error) {
return nil, errors.Wrap(err, "convert default action")
}
res.DefaultAction = newDefaultAction
+ res.DefaultErrnoRet = spec.DefaultErrnoRet
// Loop through all syscall blocks and convert them to the internal format
for _, call := range spec.Syscalls {
diff --git a/vendor/github.com/containers/common/pkg/seccomp/default_linux.go b/vendor/github.com/containers/common/pkg/seccomp/default_linux.go
index f86f3e2ba..edb1294d6 100644
--- a/vendor/github.com/containers/common/pkg/seccomp/default_linux.go
+++ b/vendor/github.com/containers/common/pkg/seccomp/default_linux.go
@@ -44,10 +44,56 @@ func arches() []Architecture {
// DefaultProfile defines the allowlist for the default seccomp profile.
func DefaultProfile() *Seccomp {
einval := uint(unix.EINVAL)
+ enosys := uint(unix.ENOSYS)
+ eperm := uint(unix.EPERM)
syscalls := []*Syscall{
{
Names: []string{
+ "bdflush",
+ "clone3",
+ "io_pgetevents",
+ "io_uring_enter",
+ "io_uring_register",
+ "io_uring_setup",
+ "kexec_file_load",
+ "kexec_load",
+ "membarrier",
+ "migrate_pages",
+ "move_pages",
+ "nfsservctl",
+ "nice",
+ "oldfstat",
+ "oldlstat",
+ "oldolduname",
+ "oldstat",
+ "olduname",
+ "pciconfig_iobase",
+ "pciconfig_read",
+ "pciconfig_write",
+ "pkey_alloc",
+ "pkey_free",
+ "pkey_mprotect",
+ "rseq",
+ "sgetmask",
+ "ssetmask",
+ "swapcontext",
+ "swapoff",
+ "swapon",
+ "sysfs",
+ "uselib",
+ "userfaultfd",
+ "ustat",
+ "vm86",
+ "vm86old",
+ "vmsplice",
+ },
+ Action: ActErrno,
+ ErrnoRet: &eperm,
+ Args: []*Arg{},
+ },
+ {
+ Names: []string{
"_llseek",
"_newselect",
"accept",
@@ -128,6 +174,7 @@ func DefaultProfile() *Seccomp {
"ftruncate",
"ftruncate64",
"futex",
+ "futex_time64",
"futimesat",
"get_robust_list",
"get_thread_area",
@@ -212,7 +259,9 @@ func DefaultProfile() *Seccomp {
"mq_notify",
"mq_open",
"mq_timedreceive",
+ "mq_timedreceive_time64",
"mq_timedsend",
+ "mq_timedsend_time64",
"mq_unlink",
"mremap",
"msgctl",
@@ -252,6 +301,7 @@ func DefaultProfile() *Seccomp {
"pwritev2",
"read",
"readahead",
+ "readdir",
"readlink",
"readlinkat",
"readv",
@@ -259,6 +309,7 @@ func DefaultProfile() *Seccomp {
"recv",
"recvfrom",
"recvmmsg",
+ "recvmmsg_time64",
"recvmsg",
"remap_file_pages",
"removexattr",
@@ -274,6 +325,7 @@ func DefaultProfile() *Seccomp {
"rt_sigreturn",
"rt_sigsuspend",
"rt_sigtimedwait",
+ "rt_sigtimedwait_time64",
"rt_tgsigqueueinfo",
"sched_get_priority_max",
"sched_get_priority_min",
@@ -282,6 +334,7 @@ func DefaultProfile() *Seccomp {
"sched_getparam",
"sched_getscheduler",
"sched_rr_get_interval",
+ "sched_rr_get_interval_time64",
"sched_setaffinity",
"sched_setattr",
"sched_setparam",
@@ -293,6 +346,7 @@ func DefaultProfile() *Seccomp {
"semget",
"semop",
"semtimedop",
+ "semtimedop_time64",
"send",
"sendfile",
"sendfile64",
@@ -361,6 +415,7 @@ func DefaultProfile() *Seccomp {
"timer_gettime",
"timer_gettime64",
"timer_settime",
+ "timer_settime64",
"timerfd_create",
"timerfd_gettime",
"timerfd_gettime64",
@@ -516,6 +571,17 @@ func DefaultProfile() *Seccomp {
},
{
Names: []string{
+ "open_by_handle_at",
+ },
+ Action: ActErrno,
+ ErrnoRet: &eperm,
+ Args: []*Arg{},
+ Excludes: Filter{
+ Caps: []string{"CAP_DAC_READ_SEARCH"},
+ },
+ },
+ {
+ Names: []string{
"bpf",
"fanotify_init",
"lookup_dcookie",
@@ -533,6 +599,24 @@ func DefaultProfile() *Seccomp {
},
{
Names: []string{
+ "bpf",
+ "fanotify_init",
+ "lookup_dcookie",
+ "perf_event_open",
+ "quotactl",
+ "setdomainname",
+ "sethostname",
+ "setns",
+ },
+ Action: ActErrno,
+ ErrnoRet: &eperm,
+ Args: []*Arg{},
+ Excludes: Filter{
+ Caps: []string{"CAP_SYS_ADMIN"},
+ },
+ },
+ {
+ Names: []string{
"chroot",
},
Action: ActAllow,
@@ -543,6 +627,17 @@ func DefaultProfile() *Seccomp {
},
{
Names: []string{
+ "chroot",
+ },
+ Action: ActErrno,
+ ErrnoRet: &eperm,
+ Args: []*Arg{},
+ Excludes: Filter{
+ Caps: []string{"CAP_SYS_CHROOT"},
+ },
+ },
+ {
+ Names: []string{
"delete_module",
"init_module",
"finit_module",
@@ -556,6 +651,20 @@ func DefaultProfile() *Seccomp {
},
{
Names: []string{
+ "delete_module",
+ "init_module",
+ "finit_module",
+ "query_module",
+ },
+ Action: ActErrno,
+ ErrnoRet: &eperm,
+ Args: []*Arg{},
+ Excludes: Filter{
+ Caps: []string{"CAP_SYS_MODULE"},
+ },
+ },
+ {
+ Names: []string{
"get_mempolicy",
"mbind",
"set_mempolicy",
@@ -568,6 +677,19 @@ func DefaultProfile() *Seccomp {
},
{
Names: []string{
+ "get_mempolicy",
+ "mbind",
+ "set_mempolicy",
+ },
+ Action: ActErrno,
+ ErrnoRet: &eperm,
+ Args: []*Arg{},
+ Excludes: Filter{
+ Caps: []string{"CAP_SYS_NICE"},
+ },
+ },
+ {
+ Names: []string{
"acct",
},
Action: ActAllow,
@@ -578,6 +700,17 @@ func DefaultProfile() *Seccomp {
},
{
Names: []string{
+ "acct",
+ },
+ Action: ActErrno,
+ ErrnoRet: &eperm,
+ Args: []*Arg{},
+ Excludes: Filter{
+ Caps: []string{"CAP_SYS_PACCT"},
+ },
+ },
+ {
+ Names: []string{
"kcmp",
"process_madvise",
"process_vm_readv",
@@ -592,6 +725,21 @@ func DefaultProfile() *Seccomp {
},
{
Names: []string{
+ "kcmp",
+ "process_madvise",
+ "process_vm_readv",
+ "process_vm_writev",
+ "ptrace",
+ },
+ Action: ActErrno,
+ ErrnoRet: &eperm,
+ Args: []*Arg{},
+ Excludes: Filter{
+ Caps: []string{"CAP_SYS_PTRACE"},
+ },
+ },
+ {
+ Names: []string{
"iopl",
"ioperm",
},
@@ -603,6 +751,18 @@ func DefaultProfile() *Seccomp {
},
{
Names: []string{
+ "iopl",
+ "ioperm",
+ },
+ Action: ActErrno,
+ ErrnoRet: &eperm,
+ Args: []*Arg{},
+ Excludes: Filter{
+ Caps: []string{"CAP_SYS_RAWIO"},
+ },
+ },
+ {
+ Names: []string{
"settimeofday",
"stime",
"clock_settime",
@@ -616,6 +776,20 @@ func DefaultProfile() *Seccomp {
},
{
Names: []string{
+ "settimeofday",
+ "stime",
+ "clock_settime",
+ "clock_settime64",
+ },
+ Action: ActErrno,
+ ErrnoRet: &eperm,
+ Args: []*Arg{},
+ Excludes: Filter{
+ Caps: []string{"CAP_SYS_TIME"},
+ },
+ },
+ {
+ Names: []string{
"vhangup",
},
Action: ActAllow,
@@ -626,6 +800,17 @@ func DefaultProfile() *Seccomp {
},
{
Names: []string{
+ "vhangup",
+ },
+ Action: ActErrno,
+ ErrnoRet: &eperm,
+ Args: []*Arg{},
+ Excludes: Filter{
+ Caps: []string{"CAP_SYS_TTY_CONFIG"},
+ },
+ },
+ {
+ Names: []string{
"socket",
},
Action: ActErrno,
@@ -706,8 +891,9 @@ func DefaultProfile() *Seccomp {
}
return &Seccomp{
- DefaultAction: ActErrno,
- ArchMap: arches(),
- Syscalls: syscalls,
+ DefaultAction: ActErrno,
+ DefaultErrnoRet: &enosys,
+ ArchMap: arches(),
+ Syscalls: syscalls,
}
}
diff --git a/vendor/github.com/containers/common/pkg/seccomp/filter.go b/vendor/github.com/containers/common/pkg/seccomp/filter.go
index ac9b2698f..90da99f0a 100644
--- a/vendor/github.com/containers/common/pkg/seccomp/filter.go
+++ b/vendor/github.com/containers/common/pkg/seccomp/filter.go
@@ -41,7 +41,7 @@ func BuildFilter(spec *specs.LinuxSeccomp) (*libseccomp.ScmpFilter, error) {
return nil, errors.Wrap(err, "convert spec to seccomp profile")
}
- defaultAction, err := toAction(profile.DefaultAction, nil)
+ defaultAction, err := toAction(profile.DefaultAction, profile.DefaultErrnoRet)
if err != nil {
return nil, errors.Wrapf(err, "convert default action %s", profile.DefaultAction)
}
diff --git a/vendor/github.com/containers/common/pkg/seccomp/seccomp.json b/vendor/github.com/containers/common/pkg/seccomp/seccomp.json
index 8d799fd02..885240e50 100644
--- a/vendor/github.com/containers/common/pkg/seccomp/seccomp.json
+++ b/vendor/github.com/containers/common/pkg/seccomp/seccomp.json
@@ -1,5 +1,6 @@
{
"defaultAction": "SCMP_ACT_ERRNO",
+ "defaultErrnoRet": 38,
"archMap": [
{
"architecture": "SCMP_ARCH_X86_64",
@@ -52,6 +53,53 @@
"syscalls": [
{
"names": [
+ "bdflush",
+ "clone3",
+ "io_pgetevents",
+ "io_uring_enter",
+ "io_uring_register",
+ "io_uring_setup",
+ "kexec_file_load",
+ "kexec_load",
+ "membarrier",
+ "migrate_pages",
+ "move_pages",
+ "nfsservctl",
+ "nice",
+ "oldfstat",
+ "oldlstat",
+ "oldolduname",
+ "oldstat",
+ "olduname",
+ "pciconfig_iobase",
+ "pciconfig_read",
+ "pciconfig_write",
+ "pkey_alloc",
+ "pkey_free",
+ "pkey_mprotect",
+ "rseq",
+ "sgetmask",
+ "ssetmask",
+ "swapcontext",
+ "swapoff",
+ "swapon",
+ "sysfs",
+ "uselib",
+ "userfaultfd",
+ "ustat",
+ "vm86",
+ "vm86old",
+ "vmsplice"
+ ],
+ "action": "SCMP_ACT_ERRNO",
+ "args": [],
+ "comment": "",
+ "includes": {},
+ "excludes": {},
+ "errnoRet": 1
+ },
+ {
+ "names": [
"_llseek",
"_newselect",
"accept",
@@ -132,6 +180,7 @@
"ftruncate",
"ftruncate64",
"futex",
+ "futex_time64",
"futimesat",
"get_robust_list",
"get_thread_area",
@@ -216,7 +265,9 @@
"mq_notify",
"mq_open",
"mq_timedreceive",
+ "mq_timedreceive_time64",
"mq_timedsend",
+ "mq_timedsend_time64",
"mq_unlink",
"mremap",
"msgctl",
@@ -256,6 +307,7 @@
"pwritev2",
"read",
"readahead",
+ "readdir",
"readlink",
"readlinkat",
"readv",
@@ -263,6 +315,7 @@
"recv",
"recvfrom",
"recvmmsg",
+ "recvmmsg_time64",
"recvmsg",
"remap_file_pages",
"removexattr",
@@ -278,6 +331,7 @@
"rt_sigreturn",
"rt_sigsuspend",
"rt_sigtimedwait",
+ "rt_sigtimedwait_time64",
"rt_tgsigqueueinfo",
"sched_get_priority_max",
"sched_get_priority_min",
@@ -286,6 +340,7 @@
"sched_getparam",
"sched_getscheduler",
"sched_rr_get_interval",
+ "sched_rr_get_interval_time64",
"sched_setaffinity",
"sched_setattr",
"sched_setparam",
@@ -297,6 +352,7 @@
"semget",
"semop",
"semtimedop",
+ "semtimedop_time64",
"send",
"sendfile",
"sendfile64",
@@ -365,6 +421,7 @@
"timer_gettime",
"timer_gettime64",
"timer_settime",
+ "timer_settime64",
"timerfd_create",
"timerfd_gettime",
"timerfd_gettime64",
@@ -582,6 +639,21 @@
},
{
"names": [
+ "open_by_handle_at"
+ ],
+ "action": "SCMP_ACT_ERRNO",
+ "args": [],
+ "comment": "",
+ "includes": {},
+ "excludes": {
+ "caps": [
+ "CAP_DAC_READ_SEARCH"
+ ]
+ },
+ "errnoRet": 1
+ },
+ {
+ "names": [
"bpf",
"fanotify_init",
"lookup_dcookie",
@@ -603,6 +675,28 @@
},
{
"names": [
+ "bpf",
+ "fanotify_init",
+ "lookup_dcookie",
+ "perf_event_open",
+ "quotactl",
+ "setdomainname",
+ "sethostname",
+ "setns"
+ ],
+ "action": "SCMP_ACT_ERRNO",
+ "args": [],
+ "comment": "",
+ "includes": {},
+ "excludes": {
+ "caps": [
+ "CAP_SYS_ADMIN"
+ ]
+ },
+ "errnoRet": 1
+ },
+ {
+ "names": [
"chroot"
],
"action": "SCMP_ACT_ALLOW",
@@ -617,6 +711,21 @@
},
{
"names": [
+ "chroot"
+ ],
+ "action": "SCMP_ACT_ERRNO",
+ "args": [],
+ "comment": "",
+ "includes": {},
+ "excludes": {
+ "caps": [
+ "CAP_SYS_CHROOT"
+ ]
+ },
+ "errnoRet": 1
+ },
+ {
+ "names": [
"delete_module",
"init_module",
"finit_module",
@@ -634,6 +743,24 @@
},
{
"names": [
+ "delete_module",
+ "init_module",
+ "finit_module",
+ "query_module"
+ ],
+ "action": "SCMP_ACT_ERRNO",
+ "args": [],
+ "comment": "",
+ "includes": {},
+ "excludes": {
+ "caps": [
+ "CAP_SYS_MODULE"
+ ]
+ },
+ "errnoRet": 1
+ },
+ {
+ "names": [
"get_mempolicy",
"mbind",
"set_mempolicy"
@@ -650,6 +777,23 @@
},
{
"names": [
+ "get_mempolicy",
+ "mbind",
+ "set_mempolicy"
+ ],
+ "action": "SCMP_ACT_ERRNO",
+ "args": [],
+ "comment": "",
+ "includes": {},
+ "excludes": {
+ "caps": [
+ "CAP_SYS_NICE"
+ ]
+ },
+ "errnoRet": 1
+ },
+ {
+ "names": [
"acct"
],
"action": "SCMP_ACT_ALLOW",
@@ -664,6 +808,21 @@
},
{
"names": [
+ "acct"
+ ],
+ "action": "SCMP_ACT_ERRNO",
+ "args": [],
+ "comment": "",
+ "includes": {},
+ "excludes": {
+ "caps": [
+ "CAP_SYS_PACCT"
+ ]
+ },
+ "errnoRet": 1
+ },
+ {
+ "names": [
"kcmp",
"process_madvise",
"process_vm_readv",
@@ -682,6 +841,25 @@
},
{
"names": [
+ "kcmp",
+ "process_madvise",
+ "process_vm_readv",
+ "process_vm_writev",
+ "ptrace"
+ ],
+ "action": "SCMP_ACT_ERRNO",
+ "args": [],
+ "comment": "",
+ "includes": {},
+ "excludes": {
+ "caps": [
+ "CAP_SYS_PTRACE"
+ ]
+ },
+ "errnoRet": 1
+ },
+ {
+ "names": [
"iopl",
"ioperm"
],
@@ -697,6 +875,22 @@
},
{
"names": [
+ "iopl",
+ "ioperm"
+ ],
+ "action": "SCMP_ACT_ERRNO",
+ "args": [],
+ "comment": "",
+ "includes": {},
+ "excludes": {
+ "caps": [
+ "CAP_SYS_RAWIO"
+ ]
+ },
+ "errnoRet": 1
+ },
+ {
+ "names": [
"settimeofday",
"stime",
"clock_settime",
@@ -714,6 +908,24 @@
},
{
"names": [
+ "settimeofday",
+ "stime",
+ "clock_settime",
+ "clock_settime64"
+ ],
+ "action": "SCMP_ACT_ERRNO",
+ "args": [],
+ "comment": "",
+ "includes": {},
+ "excludes": {
+ "caps": [
+ "CAP_SYS_TIME"
+ ]
+ },
+ "errnoRet": 1
+ },
+ {
+ "names": [
"vhangup"
],
"action": "SCMP_ACT_ALLOW",
@@ -728,6 +940,21 @@
},
{
"names": [
+ "vhangup"
+ ],
+ "action": "SCMP_ACT_ERRNO",
+ "args": [],
+ "comment": "",
+ "includes": {},
+ "excludes": {
+ "caps": [
+ "CAP_SYS_TTY_CONFIG"
+ ]
+ },
+ "errnoRet": 1
+ },
+ {
+ "names": [
"socket"
],
"action": "SCMP_ACT_ERRNO",
diff --git a/vendor/github.com/containers/common/pkg/seccomp/seccomp_linux.go b/vendor/github.com/containers/common/pkg/seccomp/seccomp_linux.go
index 19500cc97..af36b9990 100644
--- a/vendor/github.com/containers/common/pkg/seccomp/seccomp_linux.go
+++ b/vendor/github.com/containers/common/pkg/seccomp/seccomp_linux.go
@@ -111,6 +111,7 @@ func setupSeccomp(config *Seccomp, rs *specs.Spec) (*specs.LinuxSeccomp, error)
}
newConfig.DefaultAction = specs.LinuxSeccompAction(config.DefaultAction)
+ newConfig.DefaultErrnoRet = config.DefaultErrnoRet
Loop:
// Loop through all syscall blocks and convert them to libcontainer format after filtering them
diff --git a/vendor/github.com/containers/common/pkg/seccomp/types.go b/vendor/github.com/containers/common/pkg/seccomp/types.go
index 7b0436dfc..36712458a 100644
--- a/vendor/github.com/containers/common/pkg/seccomp/types.go
+++ b/vendor/github.com/containers/common/pkg/seccomp/types.go
@@ -6,7 +6,8 @@ package seccomp
// Seccomp represents the config for a seccomp profile for syscall restriction.
type Seccomp struct {
- DefaultAction Action `json:"defaultAction"`
+ DefaultAction Action `json:"defaultAction"`
+ DefaultErrnoRet *uint `json:"defaultErrnoRet"`
// Architectures is kept to maintain backward compatibility with the old
// seccomp profile.
Architectures []Arch `json:"architectures,omitempty"`
diff --git a/vendor/github.com/containers/common/pkg/secrets/passdriver/passdriver.go b/vendor/github.com/containers/common/pkg/secrets/passdriver/passdriver.go
new file mode 100644
index 000000000..6dc00b34c
--- /dev/null
+++ b/vendor/github.com/containers/common/pkg/secrets/passdriver/passdriver.go
@@ -0,0 +1,176 @@
+package passdriver
+
+import (
+ "bytes"
+ "context"
+ "io"
+ "io/ioutil"
+ "os"
+ "os/exec"
+ "path/filepath"
+ "sort"
+ "strings"
+
+ "github.com/pkg/errors"
+)
+
+var (
+ // errNoSecretData indicates that there is not data associated with an id
+ errNoSecretData = errors.New("no secret data with ID")
+
+ // errNoSecretData indicates that there is secret data already associated with an id
+ errSecretIDExists = errors.New("secret data with ID already exists")
+
+ // errInvalidKey indicates that something about your key is wrong
+ errInvalidKey = errors.New("invalid key")
+)
+
+type driverConfig struct {
+ // Root contains the root directory where the secrets are stored
+ Root string
+ // KeyID contains the key id that will be used for encryption (i.e. user@domain.tld)
+ KeyID string
+}
+
+func (cfg *driverConfig) ParseOpts(opts map[string]string) {
+ if val, ok := opts["root"]; ok {
+ cfg.Root = val
+ cfg.findGpgID() // try to find a .gpg-id in the parent directories of Root
+ }
+ if val, ok := opts["key"]; ok {
+ cfg.KeyID = val
+ }
+}
+
+func defaultDriverConfig() *driverConfig {
+ cfg := &driverConfig{}
+
+ if home, err := os.UserHomeDir(); err == nil {
+ defaultLocations := []string{
+ filepath.Join(home, ".password-store"),
+ filepath.Join(home, ".local/share/gopass/stores/root"),
+ }
+ for _, path := range defaultLocations {
+ if stat, err := os.Stat(path); err != nil || !stat.IsDir() {
+ continue
+ }
+ cfg.Root = path
+ bs, err := ioutil.ReadFile(filepath.Join(path, ".gpg-id"))
+ if err != nil {
+ continue
+ }
+ cfg.KeyID = string(bytes.Trim(bs, "\r\n"))
+ break
+ }
+ }
+
+ return cfg
+}
+
+func (cfg *driverConfig) findGpgID() {
+ path := cfg.Root
+ for len(path) > 1 {
+ if _, err := os.Stat(filepath.Join(path, ".gpg-id")); err == nil {
+ bs, err := ioutil.ReadFile(filepath.Join(path, ".gpg-id"))
+ if err != nil {
+ continue
+ }
+ cfg.KeyID = string(bytes.Trim(bs, "\r\n"))
+ break
+ }
+ path = filepath.Dir(path)
+ }
+}
+
+// Driver is the passdriver object
+type Driver struct {
+ driverConfig
+}
+
+// NewDriver creates a new secret driver.
+func NewDriver(opts map[string]string) (*Driver, error) {
+ cfg := defaultDriverConfig()
+ cfg.ParseOpts(opts)
+
+ driver := &Driver{
+ driverConfig: *cfg,
+ }
+
+ return driver, nil
+}
+
+// List returns all secret IDs
+func (d *Driver) List() (secrets []string, err error) {
+ files, err := ioutil.ReadDir(d.Root)
+ if err != nil {
+ return nil, errors.Wrap(err, "failed to read secret directory")
+ }
+ for _, f := range files {
+ fileName := f.Name()
+ withoutSuffix := fileName[:len(fileName)-len(".gpg")]
+ secrets = append(secrets, withoutSuffix)
+ }
+ sort.Strings(secrets)
+ return secrets, nil
+}
+
+// Lookup returns the bytes associated with a secret ID
+func (d *Driver) Lookup(id string) ([]byte, error) {
+ out := &bytes.Buffer{}
+ key, err := d.getPath(id)
+ if err != nil {
+ return nil, err
+ }
+ if err := d.gpg(context.TODO(), nil, out, "--decrypt", key); err != nil {
+ return nil, errors.Wrapf(errNoSecretData, id)
+ }
+ if out.Len() == 0 {
+ return nil, errors.Wrapf(errNoSecretData, id)
+ }
+ return out.Bytes(), nil
+}
+
+// Store saves the bytes associated with an ID. An error is returned if the ID already exists
+func (d *Driver) Store(id string, data []byte) error {
+ if _, err := d.Lookup(id); err == nil {
+ return errors.Wrap(errSecretIDExists, id)
+ }
+ in := bytes.NewReader(data)
+ key, err := d.getPath(id)
+ if err != nil {
+ return err
+ }
+ return d.gpg(context.TODO(), in, nil, "--encrypt", "-r", d.KeyID, "-o", key)
+}
+
+// Delete removes the secret associated with the specified ID. An error is returned if no matching secret is found.
+func (d *Driver) Delete(id string) error {
+ key, err := d.getPath(id)
+ if err != nil {
+ return err
+ }
+ if err := os.Remove(key); err != nil {
+ return errors.Wrap(errNoSecretData, id)
+ }
+ return nil
+}
+
+func (d *Driver) gpg(ctx context.Context, in io.Reader, out io.Writer, args ...string) error {
+ cmd := exec.CommandContext(ctx, "gpg", args...)
+ cmd.Env = os.Environ()
+ cmd.Stdin = in
+ cmd.Stdout = out
+ cmd.Stderr = ioutil.Discard
+ return cmd.Run()
+}
+
+func (d *Driver) getPath(id string) (string, error) {
+ path, err := filepath.Abs(filepath.Join(d.Root, id))
+ if err != nil {
+ return "", errInvalidKey
+ }
+ if !strings.HasPrefix(path, d.Root) {
+ return "", errInvalidKey
+ }
+ return path + ".gpg", nil
+}
diff --git a/vendor/github.com/containers/common/pkg/secrets/secrets.go b/vendor/github.com/containers/common/pkg/secrets/secrets.go
index d27bb7472..2573b80e2 100644
--- a/vendor/github.com/containers/common/pkg/secrets/secrets.go
+++ b/vendor/github.com/containers/common/pkg/secrets/secrets.go
@@ -8,6 +8,7 @@ import (
"time"
"github.com/containers/common/pkg/secrets/filedriver"
+ "github.com/containers/common/pkg/secrets/passdriver"
"github.com/containers/storage/pkg/lockfile"
"github.com/containers/storage/pkg/stringid"
"github.com/pkg/errors"
@@ -271,12 +272,15 @@ func validateSecretName(name string) error {
// getDriver creates a new driver.
func getDriver(name string, opts map[string]string) (SecretsDriver, error) {
- if name == "file" {
+ switch name {
+ case "file":
if path, ok := opts["path"]; ok {
return filedriver.NewDriver(path)
} else {
return nil, errors.Wrap(errInvalidDriverOpt, "need path for filedriver")
}
+ case "pass":
+ return passdriver.NewDriver(opts)
}
return nil, errInvalidDriver
}
diff --git a/vendor/github.com/containers/common/version/version.go b/vendor/github.com/containers/common/version/version.go
index ff3bf9a32..e8e3d72fe 100644
--- a/vendor/github.com/containers/common/version/version.go
+++ b/vendor/github.com/containers/common/version/version.go
@@ -1,4 +1,4 @@
package version
// Version is the version of the build.
-const Version = "0.39.1-dev"
+const Version = "0.40.0"
diff --git a/vendor/github.com/containers/image/v5/copy/copy.go b/vendor/github.com/containers/image/v5/copy/copy.go
index ed76283f9..62f47c013 100644
--- a/vendor/github.com/containers/image/v5/copy/copy.go
+++ b/vendor/github.com/containers/image/v5/copy/copy.go
@@ -29,10 +29,10 @@ import (
imgspecv1 "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
- "github.com/vbauerster/mpb/v6"
- "github.com/vbauerster/mpb/v6/decor"
- "golang.org/x/crypto/ssh/terminal"
+ "github.com/vbauerster/mpb/v7"
+ "github.com/vbauerster/mpb/v7/decor"
"golang.org/x/sync/semaphore"
+ "golang.org/x/term"
)
type digestingReader struct {
@@ -43,10 +43,6 @@ type digestingReader struct {
validationSucceeded bool
}
-// FIXME: disable early layer commits temporarily until a solid solution to
-// address #1205 has been found.
-const enableEarlyCommit = false
-
var (
// ErrDecryptParamsMissing is returned if there is missing decryption parameters
ErrDecryptParamsMissing = errors.New("Necessary DecryptParameters not present")
@@ -864,7 +860,7 @@ func (ic *imageCopier) noPendingManifestUpdates() bool {
// isTTY returns true if the io.Writer is a file and a tty.
func isTTY(w io.Writer) bool {
if f, ok := w.(*os.File); ok {
- return terminal.IsTerminal(int(f.Fd()))
+ return term.IsTerminal(int(f.Fd()))
}
return false
}
@@ -893,6 +889,18 @@ func (ic *imageCopier) copyLayers(ctx context.Context) error {
err error
}
+ // The manifest is used to extract the information whether a given
+ // layer is empty.
+ manifestBlob, manifestType, err := ic.src.Manifest(ctx)
+ if err != nil {
+ return err
+ }
+ man, err := manifest.FromBlob(manifestBlob, manifestType)
+ if err != nil {
+ return err
+ }
+ manifestLayerInfos := man.LayerInfos()
+
// copyGroup is used to determine if all layers are copied
copyGroup := sync.WaitGroup{}
@@ -925,7 +933,7 @@ func (ic *imageCopier) copyLayers(ctx context.Context) error {
logrus.Debugf("Skipping foreign layer %q copy to %s", cld.destInfo.Digest, ic.c.dest.Reference().Transport().Name())
}
} else {
- cld.destInfo, cld.diffID, cld.err = ic.copyLayer(ctx, srcLayer, toEncrypt, pool, index, srcRef)
+ cld.destInfo, cld.diffID, cld.err = ic.copyLayer(ctx, srcLayer, toEncrypt, pool, index, srcRef, manifestLayerInfos[index].EmptyLayer)
}
data[index] = cld
}
@@ -1094,8 +1102,9 @@ func (c *copier) createProgressBar(pool *mpb.Progress, info types.BlobInfo, kind
),
)
} else {
+ sstyle := mpb.SpinnerStyle(".", "..", "...", "....", "").PositionLeft()
bar = pool.Add(0,
- mpb.NewSpinnerFiller([]string{".", "..", "...", "....", ""}, mpb.SpinnerOnLeft),
+ sstyle.Build(),
mpb.BarFillerClearOnComplete(),
mpb.PrependDecorators(
decor.OnComplete(decor.Name(prefix), onComplete),
@@ -1121,7 +1130,7 @@ func (c *copier) copyConfig(ctx context.Context, src types.Image) error {
progressPool, progressCleanup := c.newProgressPool(ctx)
defer progressCleanup()
bar := c.createProgressBar(progressPool, srcInfo, "config", "done")
- destInfo, err := c.copyBlobFromStream(ctx, bytes.NewReader(configBlob), srcInfo, nil, false, true, false, bar, -1)
+ destInfo, err := c.copyBlobFromStream(ctx, bytes.NewReader(configBlob), srcInfo, nil, false, true, false, bar, -1, false)
if err != nil {
return types.BlobInfo{}, err
}
@@ -1148,7 +1157,7 @@ type diffIDResult struct {
// copyLayer copies a layer with srcInfo (with known Digest and Annotations and possibly known Size) in src to dest, perhaps (de/re/)compressing it,
// and returns a complete blobInfo of the copied layer, and a value for LayerDiffIDs if diffIDIsNeeded
// srcRef can be used as an additional hint to the destination during checking whehter a layer can be reused but srcRef can be nil.
-func (ic *imageCopier) copyLayer(ctx context.Context, srcInfo types.BlobInfo, toEncrypt bool, pool *mpb.Progress, layerIndex int, srcRef reference.Named) (types.BlobInfo, digest.Digest, error) {
+func (ic *imageCopier) copyLayer(ctx context.Context, srcInfo types.BlobInfo, toEncrypt bool, pool *mpb.Progress, layerIndex int, srcRef reference.Named, emptyLayer bool) (types.BlobInfo, digest.Digest, error) {
// If the srcInfo doesn't contain compression information, try to compute it from the
// MediaType, which was either read from a manifest by way of LayerInfos() or constructed
// by LayerInfosForCopy(), if it was supplied at all. If we succeed in copying the blob,
@@ -1195,10 +1204,9 @@ func (ic *imageCopier) copyLayer(ctx context.Context, srcInfo types.BlobInfo, to
Cache: ic.c.blobInfoCache,
CanSubstitute: ic.canSubstituteBlobs,
SrcRef: srcRef,
+ EmptyLayer: emptyLayer,
}
- if enableEarlyCommit {
- options.LayerIndex = &layerIndex
- }
+ options.LayerIndex = &layerIndex
reused, blobInfo, err = dest.TryReusingBlobWithOptions(ctx, srcInfo, options)
} else {
reused, blobInfo, err = ic.c.dest.TryReusingBlob(ctx, srcInfo, ic.c.blobInfoCache, ic.canSubstituteBlobs)
@@ -1245,7 +1253,7 @@ func (ic *imageCopier) copyLayer(ctx context.Context, srcInfo types.BlobInfo, to
bar := ic.c.createProgressBar(pool, srcInfo, "blob", "done")
- blobInfo, diffIDChan, err := ic.copyLayerFromStream(ctx, srcStream, types.BlobInfo{Digest: srcInfo.Digest, Size: srcBlobSize, MediaType: srcInfo.MediaType, Annotations: srcInfo.Annotations}, diffIDIsNeeded, toEncrypt, bar, layerIndex)
+ blobInfo, diffIDChan, err := ic.copyLayerFromStream(ctx, srcStream, types.BlobInfo{Digest: srcInfo.Digest, Size: srcBlobSize, MediaType: srcInfo.MediaType, Annotations: srcInfo.Annotations}, diffIDIsNeeded, toEncrypt, bar, layerIndex, emptyLayer)
if err != nil {
return types.BlobInfo{}, "", err
}
@@ -1276,7 +1284,7 @@ func (ic *imageCopier) copyLayer(ctx context.Context, srcInfo types.BlobInfo, to
// perhaps (de/re/)compressing the stream,
// and returns a complete blobInfo of the copied blob and perhaps a <-chan diffIDResult if diffIDIsNeeded, to be read by the caller.
func (ic *imageCopier) copyLayerFromStream(ctx context.Context, srcStream io.Reader, srcInfo types.BlobInfo,
- diffIDIsNeeded bool, toEncrypt bool, bar *mpb.Bar, layerIndex int) (types.BlobInfo, <-chan diffIDResult, error) {
+ diffIDIsNeeded bool, toEncrypt bool, bar *mpb.Bar, layerIndex int, emptyLayer bool) (types.BlobInfo, <-chan diffIDResult, error) {
var getDiffIDRecorder func(compression.DecompressorFunc) io.Writer // = nil
var diffIDChan chan diffIDResult
@@ -1301,7 +1309,7 @@ func (ic *imageCopier) copyLayerFromStream(ctx context.Context, srcStream io.Rea
}
}
- blobInfo, err := ic.c.copyBlobFromStream(ctx, srcStream, srcInfo, getDiffIDRecorder, ic.canModifyManifest, false, toEncrypt, bar, layerIndex) // Sets err to nil on success
+ blobInfo, err := ic.c.copyBlobFromStream(ctx, srcStream, srcInfo, getDiffIDRecorder, ic.canModifyManifest, false, toEncrypt, bar, layerIndex, emptyLayer) // Sets err to nil on success
return blobInfo, diffIDChan, err
// We need the defer … pipeWriter.CloseWithError() to happen HERE so that the caller can block on reading from diffIDChan
}
@@ -1353,7 +1361,7 @@ func (r errorAnnotationReader) Read(b []byte) (n int, err error) {
// and returns a complete blobInfo of the copied blob.
func (c *copier) copyBlobFromStream(ctx context.Context, srcStream io.Reader, srcInfo types.BlobInfo,
getOriginalLayerCopyWriter func(decompressor compression.DecompressorFunc) io.Writer,
- canModifyBlob bool, isConfig bool, toEncrypt bool, bar *mpb.Bar, layerIndex int) (types.BlobInfo, error) {
+ canModifyBlob bool, isConfig bool, toEncrypt bool, bar *mpb.Bar, layerIndex int, emptyLayer bool) (types.BlobInfo, error) {
if isConfig { // This is guaranteed by the caller, but set it here to be explicit.
canModifyBlob = false
}
@@ -1556,10 +1564,11 @@ func (c *copier) copyBlobFromStream(ctx context.Context, srcStream io.Reader, sr
dest, ok := c.dest.(internalTypes.ImageDestinationWithOptions)
if ok {
options := internalTypes.PutBlobOptions{
- Cache: c.blobInfoCache,
- IsConfig: isConfig,
+ Cache: c.blobInfoCache,
+ IsConfig: isConfig,
+ EmptyLayer: emptyLayer,
}
- if !isConfig && enableEarlyCommit {
+ if !isConfig {
options.LayerIndex = &layerIndex
}
uploadedInfo, err = dest.PutBlobWithOptions(ctx, &errorAnnotationReader{destStream}, inputInfo, options)
diff --git a/vendor/github.com/containers/image/v5/internal/pkg/platform/platform_matcher.go b/vendor/github.com/containers/image/v5/internal/pkg/platform/platform_matcher.go
index 3e81e06c0..3bda6af29 100644
--- a/vendor/github.com/containers/image/v5/internal/pkg/platform/platform_matcher.go
+++ b/vendor/github.com/containers/image/v5/internal/pkg/platform/platform_matcher.go
@@ -9,7 +9,7 @@ package platform
// 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
+// https://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.
diff --git a/vendor/github.com/containers/image/v5/internal/types/types.go b/vendor/github.com/containers/image/v5/internal/types/types.go
index bf89a69b8..4a863ba34 100644
--- a/vendor/github.com/containers/image/v5/internal/types/types.go
+++ b/vendor/github.com/containers/image/v5/internal/types/types.go
@@ -39,6 +39,8 @@ type PutBlobOptions struct {
Cache publicTypes.BlobInfoCache
// Denotes whether the blob is a config or not.
IsConfig bool
+ // Indicates an empty layer.
+ EmptyLayer bool
// The corresponding index in the layer slice.
LayerIndex *int
}
@@ -49,6 +51,8 @@ type TryReusingBlobOptions struct {
Cache publicTypes.BlobInfoCache
// Use an equivalent of the desired blob.
CanSubstitute bool
+ // Indicates an empty layer.
+ EmptyLayer bool
// The corresponding index in the layer slice.
LayerIndex *int
// The reference of the image that contains the target blob.
diff --git a/vendor/github.com/containers/image/v5/pkg/docker/config/config.go b/vendor/github.com/containers/image/v5/pkg/docker/config/config.go
index b84aac6e4..ec7c2fcc3 100644
--- a/vendor/github.com/containers/image/v5/pkg/docker/config/config.go
+++ b/vendor/github.com/containers/image/v5/pkg/docker/config/config.go
@@ -51,21 +51,26 @@ var (
ErrNotSupported = errors.New("not supported")
)
-// SetAuthentication stores the username and password in the credential helper or file
-func SetAuthentication(sys *types.SystemContext, registry, username, password string) error {
+// SetCredentials stores the username and password in the credential helper or file
+// and returns path to file or helper name in format (helper:%s).
+// Returns a human-redable description of the location that was updated.
+// NOTE: The return value is only intended to be read by humans; its form is not an API,
+// it may change (or new forms can be added) any time.
+func SetCredentials(sys *types.SystemContext, registry, username, password string) (string, error) {
helpers, err := sysregistriesv2.CredentialHelpers(sys)
if err != nil {
- return err
+ return "", err
}
// Make sure to collect all errors.
var multiErr error
for _, helper := range helpers {
+ var desc string
var err error
switch helper {
// Special-case the built-in helpers for auth files.
case sysregistriesv2.AuthenticationFileHelper:
- err = modifyJSON(sys, func(auths *dockerConfigFile) (bool, error) {
+ desc, err = modifyJSON(sys, func(auths *dockerConfigFile) (bool, error) {
if ch, exists := auths.CredHelpers[registry]; exists {
return false, setAuthToCredHelper(ch, registry, username, password)
}
@@ -76,6 +81,7 @@ func SetAuthentication(sys *types.SystemContext, registry, username, password st
})
// External helpers.
default:
+ desc = fmt.Sprintf("credential helper: %s", helper)
err = setAuthToCredHelper(helper, registry, username, password)
}
if err != nil {
@@ -84,9 +90,15 @@ func SetAuthentication(sys *types.SystemContext, registry, username, password st
continue
}
logrus.Debugf("Stored credentials for %s in credential helper %s", registry, helper)
- return nil
+ return desc, nil
}
- return multiErr
+ return "", multiErr
+}
+
+// SetAuthentication stores the username and password in the credential helper or file
+func SetAuthentication(sys *types.SystemContext, registry, username, password string) error {
+ _, err := SetCredentials(sys, registry, username, password)
+ return err
}
// GetAllCredentials returns the registry credentials for all registries stored
@@ -322,7 +334,7 @@ func RemoveAuthentication(sys *types.SystemContext, registry string) error {
switch helper {
// Special-case the built-in helper for auth files.
case sysregistriesv2.AuthenticationFileHelper:
- err = modifyJSON(sys, func(auths *dockerConfigFile) (bool, error) {
+ _, err = modifyJSON(sys, func(auths *dockerConfigFile) (bool, error) {
if innerHelper, exists := auths.CredHelpers[registry]; exists {
removeFromCredHelper(innerHelper)
}
@@ -368,7 +380,7 @@ func RemoveAllAuthentication(sys *types.SystemContext) error {
switch helper {
// Special-case the built-in helper for auth files.
case sysregistriesv2.AuthenticationFileHelper:
- err = modifyJSON(sys, func(auths *dockerConfigFile) (bool, error) {
+ _, err = modifyJSON(sys, func(auths *dockerConfigFile) (bool, error) {
for registry, helper := range auths.CredHelpers {
// Helpers in auth files are expected
// to exist, so no special treatment
@@ -493,42 +505,44 @@ func readJSONFile(path string, legacyFormat bool) (dockerConfigFile, error) {
return auths, nil
}
-// modifyJSON writes to auth.json if the dockerConfigFile has been updated
-func modifyJSON(sys *types.SystemContext, editor func(auths *dockerConfigFile) (bool, error)) error {
+// modifyJSON finds an auth.json file, calls editor on the contents, and
+// writes it back if editor returns true.
+// Returns a human-redable description of the file, to be returned by SetCredentials.
+func modifyJSON(sys *types.SystemContext, editor func(auths *dockerConfigFile) (bool, error)) (string, error) {
path, legacyFormat, err := getPathToAuth(sys)
if err != nil {
- return err
+ return "", err
}
if legacyFormat {
- return fmt.Errorf("writes to %s using legacy format are not supported", path)
+ return "", fmt.Errorf("writes to %s using legacy format are not supported", path)
}
dir := filepath.Dir(path)
if err = os.MkdirAll(dir, 0700); err != nil {
- return err
+ return "", err
}
auths, err := readJSONFile(path, false)
if err != nil {
- return errors.Wrapf(err, "error reading JSON file %q", path)
+ return "", errors.Wrapf(err, "error reading JSON file %q", path)
}
updated, err := editor(&auths)
if err != nil {
- return errors.Wrapf(err, "error updating %q", path)
+ return "", errors.Wrapf(err, "error updating %q", path)
}
if updated {
newData, err := json.MarshalIndent(auths, "", "\t")
if err != nil {
- return errors.Wrapf(err, "error marshaling JSON %q", path)
+ return "", errors.Wrapf(err, "error marshaling JSON %q", path)
}
if err = ioutil.WriteFile(path, newData, 0600); err != nil {
- return errors.Wrapf(err, "error writing to file %q", path)
+ return "", errors.Wrapf(err, "error writing to file %q", path)
}
}
- return nil
+ return path, nil
}
func getAuthFromCredHelper(credHelper, registry string) (types.DockerAuthConfig, error) {
diff --git a/vendor/github.com/containers/image/v5/pkg/docker/config/config_linux.go b/vendor/github.com/containers/image/v5/pkg/docker/config/config_linux.go
index 5bbfb450f..93c75b944 100644
--- a/vendor/github.com/containers/image/v5/pkg/docker/config/config_linux.go
+++ b/vendor/github.com/containers/image/v5/pkg/docker/config/config_linux.go
@@ -13,9 +13,9 @@ import (
// reenable keyring support, we should introduce a similar built-in credential
// helpers as for `sysregistriesv2.AuthenticationFileHelper`.
-const keyDescribePrefix = "container-registry-login:" // nolint
+const keyDescribePrefix = "container-registry-login:" //nolint:deadcode,unused
-func getAuthFromKernelKeyring(registry string) (string, string, error) { // nolint
+func getAuthFromKernelKeyring(registry string) (string, string, error) { //nolint:deadcode,unused
userkeyring, err := keyctl.UserKeyring()
if err != nil {
return "", "", err
@@ -35,7 +35,7 @@ func getAuthFromKernelKeyring(registry string) (string, string, error) { // noli
return parts[0], parts[1], nil
}
-func deleteAuthFromKernelKeyring(registry string) error { // nolint
+func deleteAuthFromKernelKeyring(registry string) error { //nolint:deadcode,unused
userkeyring, err := keyctl.UserKeyring()
if err != nil {
@@ -48,7 +48,7 @@ func deleteAuthFromKernelKeyring(registry string) error { // nolint
return key.Unlink()
}
-func removeAllAuthFromKernelKeyring() error { // nolint
+func removeAllAuthFromKernelKeyring() error { //nolint:deadcode,unused
keys, err := keyctl.ReadUserKeyring()
if err != nil {
return err
@@ -81,7 +81,7 @@ func removeAllAuthFromKernelKeyring() error { // nolint
return nil
}
-func setAuthToKernelKeyring(registry, username, password string) error { // nolint
+func setAuthToKernelKeyring(registry, username, password string) error { //nolint:deadcode,unused
keyring, err := keyctl.SessionKeyring()
if err != nil {
return err
@@ -114,6 +114,6 @@ func setAuthToKernelKeyring(registry, username, password string) error { // noli
return nil
}
-func genDescription(registry string) string { // nolint
+func genDescription(registry string) string { //nolint:deadcode,unused
return fmt.Sprintf("%s%s", keyDescribePrefix, registry)
}
diff --git a/vendor/github.com/containers/image/v5/pkg/docker/config/config_unsupported.go b/vendor/github.com/containers/image/v5/pkg/docker/config/config_unsupported.go
index 9b0e8bee2..65e580410 100644
--- a/vendor/github.com/containers/image/v5/pkg/docker/config/config_unsupported.go
+++ b/vendor/github.com/containers/image/v5/pkg/docker/config/config_unsupported.go
@@ -3,18 +3,18 @@
package config
-func getAuthFromKernelKeyring(registry string) (string, string, error) {
+func getAuthFromKernelKeyring(registry string) (string, string, error) { //nolint:deadcode,unused
return "", "", ErrNotSupported
}
-func deleteAuthFromKernelKeyring(registry string) error {
+func deleteAuthFromKernelKeyring(registry string) error { //nolint:deadcode,unused
return ErrNotSupported
}
-func setAuthToKernelKeyring(registry, username, password string) error {
+func setAuthToKernelKeyring(registry, username, password string) error { //nolint:deadcode,unused
return ErrNotSupported
}
-func removeAllAuthFromKernelKeyring() error {
+func removeAllAuthFromKernelKeyring() error { //nolint:deadcode,unused
return ErrNotSupported
}
diff --git a/vendor/github.com/containers/image/v5/pkg/shortnames/shortnames.go b/vendor/github.com/containers/image/v5/pkg/shortnames/shortnames.go
index b64f44674..ab1eee8f3 100644
--- a/vendor/github.com/containers/image/v5/pkg/shortnames/shortnames.go
+++ b/vendor/github.com/containers/image/v5/pkg/shortnames/shortnames.go
@@ -11,7 +11,7 @@ import (
"github.com/manifoldco/promptui"
"github.com/opencontainers/go-digest"
"github.com/pkg/errors"
- "golang.org/x/crypto/ssh/terminal"
+ "golang.org/x/term"
)
// IsShortName returns true if the specified input is a "short name". A "short
@@ -343,7 +343,7 @@ func Resolve(ctx *types.SystemContext, name string) (*Resolved, error) {
}
// If we don't have a TTY, act according to the mode.
- if !terminal.IsTerminal(int(os.Stdout.Fd())) || !terminal.IsTerminal(int(os.Stdin.Fd())) {
+ if !term.IsTerminal(int(os.Stdout.Fd())) || !term.IsTerminal(int(os.Stdin.Fd())) {
switch mode {
case types.ShortNameModePermissive:
// Permissive falls back to using all candidates.
diff --git a/vendor/github.com/containers/image/v5/storage/storage_image.go b/vendor/github.com/containers/image/v5/storage/storage_image.go
index f4747357c..7072d6860 100644
--- a/vendor/github.com/containers/image/v5/storage/storage_image.go
+++ b/vendor/github.com/containers/image/v5/storage/storage_image.go
@@ -76,12 +76,12 @@ type storageImageDestination struct {
indexToStorageID map[int]*string
// All accesses to below data are protected by `lock` which is made
// *explicit* in the code.
- blobDiffIDs map[digest.Digest]digest.Digest // Mapping from layer blobsums to their corresponding DiffIDs
- fileSizes map[digest.Digest]int64 // Mapping from layer blobsums to their sizes
- filenames map[digest.Digest]string // Mapping from layer blobsums to names of files we used to hold them
- currentIndex int // The index of the layer to be committed (i.e., lower indices have already been committed)
- indexToPulledBlob map[int]*types.BlobInfo // Mapping from layer (by index) to pulled down blob
- blobAdditionalLayer map[digest.Digest]storage.AdditionalLayer // Mapping from layer blobsums to their corresponding additional layer
+ blobDiffIDs map[digest.Digest]digest.Digest // Mapping from layer blobsums to their corresponding DiffIDs
+ fileSizes map[digest.Digest]int64 // Mapping from layer blobsums to their sizes
+ filenames map[digest.Digest]string // Mapping from layer blobsums to names of files we used to hold them
+ currentIndex int // The index of the layer to be committed (i.e., lower indices have already been committed)
+ indexToPulledLayerInfo map[int]*manifest.LayerInfo // Mapping from layer (by index) to pulled down blob
+ blobAdditionalLayer map[digest.Digest]storage.AdditionalLayer // Mapping from layer blobsums to their corresponding additional layer
}
type storageImageCloser struct {
@@ -392,17 +392,17 @@ func newImageDestination(sys *types.SystemContext, imageRef storageReference) (*
return nil, errors.Wrapf(err, "error creating a temporary directory")
}
image := &storageImageDestination{
- imageRef: imageRef,
- directory: directory,
- signatureses: make(map[digest.Digest][]byte),
- blobDiffIDs: make(map[digest.Digest]digest.Digest),
- blobAdditionalLayer: make(map[digest.Digest]storage.AdditionalLayer),
- fileSizes: make(map[digest.Digest]int64),
- filenames: make(map[digest.Digest]string),
- SignatureSizes: []int{},
- SignaturesSizes: make(map[digest.Digest][]int),
- indexToStorageID: make(map[int]*string),
- indexToPulledBlob: make(map[int]*types.BlobInfo),
+ imageRef: imageRef,
+ directory: directory,
+ signatureses: make(map[digest.Digest][]byte),
+ blobDiffIDs: make(map[digest.Digest]digest.Digest),
+ blobAdditionalLayer: make(map[digest.Digest]storage.AdditionalLayer),
+ fileSizes: make(map[digest.Digest]int64),
+ filenames: make(map[digest.Digest]string),
+ SignatureSizes: []int{},
+ SignaturesSizes: make(map[digest.Digest][]int),
+ indexToStorageID: make(map[int]*string),
+ indexToPulledLayerInfo: make(map[int]*manifest.LayerInfo),
}
return image, nil
}
@@ -449,7 +449,7 @@ func (s *storageImageDestination) PutBlobWithOptions(ctx context.Context, stream
return info, nil
}
- return info, s.queueOrCommit(ctx, info, *options.LayerIndex)
+ return info, s.queueOrCommit(ctx, info, *options.LayerIndex, options.EmptyLayer)
}
// HasThreadSafePutBlob indicates whether PutBlob can be executed concurrently.
@@ -542,7 +542,7 @@ func (s *storageImageDestination) TryReusingBlobWithOptions(ctx context.Context,
return reused, info, err
}
- return reused, info, s.queueOrCommit(ctx, info, *options.LayerIndex)
+ return reused, info, s.queueOrCommit(ctx, info, *options.LayerIndex, options.EmptyLayer)
}
// tryReusingBlobWithSrcRef is a wrapper around TryReusingBlob.
@@ -731,7 +731,7 @@ func (s *storageImageDestination) getConfigBlob(info types.BlobInfo) ([]byte, er
// queueOrCommit queues in the specified blob to be committed to the storage.
// If no other goroutine is already committing layers, the layer and all
// subsequent layers (if already queued) will be committed to the storage.
-func (s *storageImageDestination) queueOrCommit(ctx context.Context, blob types.BlobInfo, index int) error {
+func (s *storageImageDestination) queueOrCommit(ctx context.Context, blob types.BlobInfo, index int, emptyLayer bool) error {
// NOTE: whenever the code below is touched, make sure that all code
// paths unlock the lock and to unlock it exactly once.
//
@@ -751,7 +751,10 @@ func (s *storageImageDestination) queueOrCommit(ctx context.Context, blob types.
// caller is the "worker" routine comitting layers. All other routines
// can continue pulling and queuing in layers.
s.lock.Lock()
- s.indexToPulledBlob[index] = &blob
+ s.indexToPulledLayerInfo[index] = &manifest.LayerInfo{
+ BlobInfo: blob,
+ EmptyLayer: emptyLayer,
+ }
// We're still waiting for at least one previous/parent layer to be
// committed, so there's nothing to do.
@@ -760,14 +763,10 @@ func (s *storageImageDestination) queueOrCommit(ctx context.Context, blob types.
return nil
}
- for info := s.indexToPulledBlob[index]; info != nil; info = s.indexToPulledBlob[index] {
+ for info := s.indexToPulledLayerInfo[index]; info != nil; info = s.indexToPulledLayerInfo[index] {
s.lock.Unlock()
- layerInfo := manifest.LayerInfo{
- BlobInfo: *info,
- EmptyLayer: info.Digest == image.GzippedEmptyLayerDigest,
- }
// Note: commitLayer locks on-demand.
- if err := s.commitLayer(ctx, layerInfo, index); err != nil {
+ if err := s.commitLayer(ctx, *info, index); err != nil {
return err
}
s.lock.Lock()
@@ -1034,25 +1033,6 @@ func (s *storageImageDestination) Commit(ctx context.Context, unparsedToplevel t
return errors.Wrapf(err, "error saving big data %q for image %q", blob.String(), img.ID)
}
}
- // Set the reference's name on the image. We don't need to worry about avoiding duplicate
- // values because SetNames() will deduplicate the list that we pass to it.
- if name := s.imageRef.DockerReference(); len(oldNames) > 0 || name != nil {
- names := []string{}
- if name != nil {
- names = append(names, name.String())
- }
- if len(oldNames) > 0 {
- names = append(names, oldNames...)
- }
- if err := s.imageRef.transport.store.SetNames(img.ID, names); err != nil {
- if _, err2 := s.imageRef.transport.store.DeleteImage(img.ID, true); err2 != nil {
- logrus.Debugf("error deleting incomplete image %q: %v", img.ID, err2)
- }
- logrus.Debugf("error setting names %v on image %q: %v", names, img.ID, err)
- return errors.Wrapf(err, "error setting names %v on image %q", names, img.ID)
- }
- logrus.Debugf("set names of image %q to %v", img.ID, names)
- }
// Save the unparsedToplevel's manifest.
if len(toplevelManifest) != 0 {
manifestDigest, err := manifest.Digest(toplevelManifest)
@@ -1130,6 +1110,25 @@ func (s *storageImageDestination) Commit(ctx context.Context, unparsedToplevel t
}
logrus.Debugf("saved image metadata %q", string(metadata))
}
+ // Set the reference's name on the image. We don't need to worry about avoiding duplicate
+ // values because SetNames() will deduplicate the list that we pass to it.
+ if name := s.imageRef.DockerReference(); len(oldNames) > 0 || name != nil {
+ names := []string{}
+ if name != nil {
+ names = append(names, name.String())
+ }
+ if len(oldNames) > 0 {
+ names = append(names, oldNames...)
+ }
+ if err := s.imageRef.transport.store.SetNames(img.ID, names); err != nil {
+ if _, err2 := s.imageRef.transport.store.DeleteImage(img.ID, true); err2 != nil {
+ logrus.Debugf("error deleting incomplete image %q: %v", img.ID, err2)
+ }
+ logrus.Debugf("error setting names %v on image %q: %v", names, img.ID, err)
+ return errors.Wrapf(err, "error setting names %v on image %q", names, img.ID)
+ }
+ logrus.Debugf("set names of image %q to %v", img.ID, names)
+ }
return nil
}
diff --git a/vendor/github.com/containers/image/v5/version/version.go b/vendor/github.com/containers/image/v5/version/version.go
index 4afb3b90b..edf4681de 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 = 12
+ VersionMinor = 13
// VersionPatch is for backwards-compatible bug fixes
- VersionPatch = 0
+ VersionPatch = 2
// VersionDev indicates development branch. Releases will be empty string.
VersionDev = ""
diff --git a/vendor/github.com/docker/docker-credential-helpers/client/command.go b/vendor/github.com/docker/docker-credential-helpers/client/command.go
index 8da334306..0183c0639 100644
--- a/vendor/github.com/docker/docker-credential-helpers/client/command.go
+++ b/vendor/github.com/docker/docker-credential-helpers/client/command.go
@@ -4,7 +4,8 @@ import (
"fmt"
"io"
"os"
- "os/exec"
+
+ exec "golang.org/x/sys/execabs"
)
// Program is an interface to execute external programs.
diff --git a/vendor/github.com/docker/docker-credential-helpers/credentials/version.go b/vendor/github.com/docker/docker-credential-helpers/credentials/version.go
index c2cc3e2e0..185e36796 100644
--- a/vendor/github.com/docker/docker-credential-helpers/credentials/version.go
+++ b/vendor/github.com/docker/docker-credential-helpers/credentials/version.go
@@ -1,4 +1,4 @@
package credentials
// Version holds a string describing the current version
-const Version = "0.6.3"
+const Version = "0.6.4"
diff --git a/vendor/github.com/imdario/mergo/.travis.yml b/vendor/github.com/imdario/mergo/.travis.yml
index dad29725f..d324c43ba 100644
--- a/vendor/github.com/imdario/mergo/.travis.yml
+++ b/vendor/github.com/imdario/mergo/.travis.yml
@@ -1,4 +1,7 @@
language: go
+arch:
+ - amd64
+ - ppc64le
install:
- go get -t
- go get golang.org/x/tools/cmd/cover
diff --git a/vendor/github.com/imdario/mergo/README.md b/vendor/github.com/imdario/mergo/README.md
index 876abb500..aa8cbd7ce 100644
--- a/vendor/github.com/imdario/mergo/README.md
+++ b/vendor/github.com/imdario/mergo/README.md
@@ -97,7 +97,7 @@ If Mergo is useful to you, consider buying me a coffee, a beer, or making a mont
- [mantasmatelis/whooplist-server](https://github.com/mantasmatelis/whooplist-server)
- [jnuthong/item_search](https://github.com/jnuthong/item_search)
- [bukalapak/snowboard](https://github.com/bukalapak/snowboard)
-- [janoszen/containerssh](https://github.com/janoszen/containerssh)
+- [containerssh/containerssh](https://github.com/containerssh/containerssh)
## Install
diff --git a/vendor/github.com/imdario/mergo/merge.go b/vendor/github.com/imdario/mergo/merge.go
index afa84a1e2..8c2a8fcd9 100644
--- a/vendor/github.com/imdario/mergo/merge.go
+++ b/vendor/github.com/imdario/mergo/merge.go
@@ -95,13 +95,18 @@ func deepMerge(dst, src reflect.Value, visited map[uintptr]*visit, depth int, co
}
}
} else {
- if (isReflectNil(dst) || overwrite) && (!isEmptyValue(src) || overwriteWithEmptySrc) {
+ if dst.CanSet() && (isReflectNil(dst) || overwrite) && (!isEmptyValue(src) || overwriteWithEmptySrc) {
dst.Set(src)
}
}
case reflect.Map:
if dst.IsNil() && !src.IsNil() {
- dst.Set(reflect.MakeMap(dst.Type()))
+ if dst.CanSet() {
+ dst.Set(reflect.MakeMap(dst.Type()))
+ } else {
+ dst = src
+ return
+ }
}
if src.Kind() != reflect.Map {
diff --git a/vendor/github.com/jinzhu/copier/README.md b/vendor/github.com/jinzhu/copier/README.md
index cff72405c..ec04b4be0 100644
--- a/vendor/github.com/jinzhu/copier/README.md
+++ b/vendor/github.com/jinzhu/copier/README.md
@@ -27,9 +27,10 @@ import (
)
type User struct {
- Name string
- Role string
- Age int32
+ Name string
+ Role string
+ Age int32
+ EmployeCode int64 `copier:"EmployeNum"` // specify field name
// Explicitly ignored in the destination struct.
Salary int
@@ -52,7 +53,7 @@ type Employee struct {
Salary int `copier:"-"`
DoubleAge int32
- EmployeId int64
+ EmployeId int64 `copier:"EmployeNum"` // specify field name
SuperRole string
}
diff --git a/vendor/github.com/jinzhu/copier/copier.go b/vendor/github.com/jinzhu/copier/copier.go
index 72bf65c78..412ff5497 100644
--- a/vendor/github.com/jinzhu/copier/copier.go
+++ b/vendor/github.com/jinzhu/copier/copier.go
@@ -3,9 +3,11 @@ package copier
import (
"database/sql"
"database/sql/driver"
+ "errors"
"fmt"
"reflect"
"strings"
+ "unicode"
)
// These flags define options for tag handling
@@ -32,6 +34,19 @@ type Option struct {
DeepCopy bool
}
+// Tag Flags
+type flags struct {
+ BitFlags map[string]uint8
+ SrcNames tagNameMapping
+ DestNames tagNameMapping
+}
+
+// Field Tag name mapping
+type tagNameMapping struct {
+ FieldNameToTag map[string]string
+ TagToFieldName map[string]string
+}
+
// Copy copy things
func Copy(toValue interface{}, fromValue interface{}) (err error) {
return copier(toValue, fromValue, Option{})
@@ -134,7 +149,8 @@ func copier(toValue interface{}, fromValue interface{}, opt Option) (err error)
}
if !set(to.Index(i), from.Index(i), opt.DeepCopy) {
- err = CopyWithOption(to.Index(i).Addr().Interface(), from.Index(i).Interface(), opt)
+ // ignore error while copy slice element
+ err = copier(to.Index(i).Addr().Interface(), from.Index(i).Interface(), opt)
if err != nil {
continue
}
@@ -148,7 +164,7 @@ func copier(toValue interface{}, fromValue interface{}, opt Option) (err error)
return
}
- if to.Kind() == reflect.Slice {
+ if from.Kind() == reflect.Slice || to.Kind() == reflect.Slice {
isSlice = true
if from.Kind() == reflect.Slice {
amount = from.Len()
@@ -180,9 +196,9 @@ func copier(toValue interface{}, fromValue interface{}, opt Option) (err error)
}
// Get tag options
- tagBitFlags := map[string]uint8{}
- if dest.IsValid() {
- tagBitFlags = getBitFlags(toType)
+ flgs, err := getFlags(dest, source, toType, fromType)
+ if err != nil {
+ return err
}
// check source
@@ -193,17 +209,18 @@ func copier(toValue interface{}, fromValue interface{}, opt Option) (err error)
name := field.Name
// Get bit flags for field
- fieldFlags, _ := tagBitFlags[name]
+ fieldFlags, _ := flgs.BitFlags[name]
// Check if we should ignore copying
if (fieldFlags & tagIgnore) != 0 {
continue
}
- if fromField := source.FieldByName(name); fromField.IsValid() && !shouldIgnore(fromField, opt.IgnoreEmpty) {
+ srcFieldName, destFieldName := getFieldName(name, flgs)
+ if fromField := source.FieldByName(srcFieldName); fromField.IsValid() && !shouldIgnore(fromField, opt.IgnoreEmpty) {
// process for nested anonymous field
destFieldNotSet := false
- if f, ok := dest.Type().FieldByName(name); ok {
+ if f, ok := dest.Type().FieldByName(destFieldName); ok {
for idx := range f.Index {
destField := dest.FieldByIndex(f.Index[:idx+1])
@@ -229,7 +246,7 @@ func copier(toValue interface{}, fromValue interface{}, opt Option) (err error)
break
}
- toField := dest.FieldByName(name)
+ toField := dest.FieldByName(destFieldName)
if toField.IsValid() {
if toField.CanSet() {
if !set(toField, fromField, opt.DeepCopy) {
@@ -239,16 +256,16 @@ func copier(toValue interface{}, fromValue interface{}, opt Option) (err error)
}
if fieldFlags != 0 {
// Note that a copy was made
- tagBitFlags[name] = fieldFlags | hasCopied
+ flgs.BitFlags[name] = fieldFlags | hasCopied
}
}
} else {
// try to set to method
var toMethod reflect.Value
if dest.CanAddr() {
- toMethod = dest.Addr().MethodByName(name)
+ toMethod = dest.Addr().MethodByName(destFieldName)
} else {
- toMethod = dest.MethodByName(name)
+ toMethod = dest.MethodByName(destFieldName)
}
if toMethod.IsValid() && toMethod.Type().NumIn() == 1 && fromField.Type().AssignableTo(toMethod.Type().In(0)) {
@@ -261,16 +278,17 @@ func copier(toValue interface{}, fromValue interface{}, opt Option) (err error)
// Copy from from method to dest field
for _, field := range deepFields(toType) {
name := field.Name
+ srcFieldName, destFieldName := getFieldName(name, flgs)
var fromMethod reflect.Value
if source.CanAddr() {
- fromMethod = source.Addr().MethodByName(name)
+ fromMethod = source.Addr().MethodByName(srcFieldName)
} else {
- fromMethod = source.MethodByName(name)
+ fromMethod = source.MethodByName(srcFieldName)
}
if fromMethod.IsValid() && fromMethod.Type().NumIn() == 0 && fromMethod.Type().NumOut() == 1 && !shouldIgnore(fromMethod, opt.IgnoreEmpty) {
- if toField := dest.FieldByName(name); toField.IsValid() && toField.CanSet() {
+ if toField := dest.FieldByName(destFieldName); toField.IsValid() && toField.CanSet() {
values := fromMethod.Call([]reflect.Value{})
if len(values) >= 1 {
set(toField, values[0], opt.DeepCopy)
@@ -280,25 +298,37 @@ func copier(toValue interface{}, fromValue interface{}, opt Option) (err error)
}
}
- if isSlice {
+ if isSlice && to.Kind() == reflect.Slice {
if dest.Addr().Type().AssignableTo(to.Type().Elem()) {
if to.Len() < i+1 {
to.Set(reflect.Append(to, dest.Addr()))
} else {
- set(to.Index(i), dest.Addr(), opt.DeepCopy)
+ if !set(to.Index(i), dest.Addr(), opt.DeepCopy) {
+ // ignore error while copy slice element
+ err = copier(to.Index(i).Addr().Interface(), dest.Addr().Interface(), opt)
+ if err != nil {
+ continue
+ }
+ }
}
} else if dest.Type().AssignableTo(to.Type().Elem()) {
if to.Len() < i+1 {
to.Set(reflect.Append(to, dest))
} else {
- set(to.Index(i), dest, opt.DeepCopy)
+ if !set(to.Index(i), dest, opt.DeepCopy) {
+ // ignore error while copy slice element
+ err = copier(to.Index(i).Addr().Interface(), dest.Interface(), opt)
+ if err != nil {
+ continue
+ }
+ }
}
}
} else if initDest {
to.Set(dest)
}
- err = checkBitFlags(tagBitFlags)
+ err = checkBitFlags(flgs.BitFlags)
}
return
@@ -432,46 +462,90 @@ func set(to, from reflect.Value, deepCopy bool) bool {
}
// parseTags Parses struct tags and returns uint8 bit flags.
-func parseTags(tag string) (flags uint8) {
+func parseTags(tag string) (flg uint8, name string, err error) {
for _, t := range strings.Split(tag, ",") {
switch t {
case "-":
- flags = tagIgnore
+ flg = tagIgnore
return
case "must":
- flags = flags | tagMust
+ flg = flg | tagMust
case "nopanic":
- flags = flags | tagNoPanic
+ flg = flg | tagNoPanic
+ default:
+ if unicode.IsUpper([]rune(t)[0]) {
+ name = strings.TrimSpace(t)
+ } else {
+ err = errors.New("copier field name tag must be start upper case")
+ }
}
}
return
}
-// getBitFlags Parses struct tags for bit flags.
-func getBitFlags(toType reflect.Type) map[string]uint8 {
- flags := map[string]uint8{}
- toTypeFields := deepFields(toType)
+// getTagFlags Parses struct tags for bit flags, field name.
+func getFlags(dest, src reflect.Value, toType, fromType reflect.Type) (flags, error) {
+ flgs := flags{
+ BitFlags: map[string]uint8{},
+ SrcNames: tagNameMapping{
+ FieldNameToTag: map[string]string{},
+ TagToFieldName: map[string]string{},
+ },
+ DestNames: tagNameMapping{
+ FieldNameToTag: map[string]string{},
+ TagToFieldName: map[string]string{},
+ },
+ }
+ var toTypeFields, fromTypeFields []reflect.StructField
+ if dest.IsValid() {
+ toTypeFields = deepFields(toType)
+ }
+ if src.IsValid() {
+ fromTypeFields = deepFields(fromType)
+ }
// Get a list dest of tags
for _, field := range toTypeFields {
tags := field.Tag.Get("copier")
if tags != "" {
- flags[field.Name] = parseTags(tags)
+ var name string
+ var err error
+ if flgs.BitFlags[field.Name], name, err = parseTags(tags); err != nil {
+ return flags{}, err
+ } else if name != "" {
+ flgs.DestNames.FieldNameToTag[field.Name] = name
+ flgs.DestNames.TagToFieldName[name] = field.Name
+ }
+ }
+ }
+
+ // Get a list source of tags
+ for _, field := range fromTypeFields {
+ tags := field.Tag.Get("copier")
+ if tags != "" {
+ var name string
+ var err error
+ if _, name, err = parseTags(tags); err != nil {
+ return flags{}, err
+ } else if name != "" {
+ flgs.SrcNames.FieldNameToTag[field.Name] = name
+ flgs.SrcNames.TagToFieldName[name] = field.Name
+ }
}
}
- return flags
+ return flgs, nil
}
// checkBitFlags Checks flags for error or panic conditions.
func checkBitFlags(flagsList map[string]uint8) (err error) {
// Check flag conditions were met
- for name, flags := range flagsList {
- if flags&hasCopied == 0 {
+ for name, flgs := range flagsList {
+ if flgs&hasCopied == 0 {
switch {
- case flags&tagMust != 0 && flags&tagNoPanic != 0:
+ case flgs&tagMust != 0 && flgs&tagNoPanic != 0:
err = fmt.Errorf("field %s has must tag but was not copied", name)
return
- case flags&(tagMust) != 0:
+ case flgs&(tagMust) != 0:
panic(fmt.Sprintf("Field %s has must tag but was not copied", name))
}
}
@@ -479,6 +553,40 @@ func checkBitFlags(flagsList map[string]uint8) (err error) {
return
}
+func getFieldName(fieldName string, flgs flags) (srcFieldName string, destFieldName string) {
+ // get dest field name
+ if srcTagName, ok := flgs.SrcNames.FieldNameToTag[fieldName]; ok {
+ destFieldName = srcTagName
+ if destTagName, ok := flgs.DestNames.TagToFieldName[srcTagName]; ok {
+ destFieldName = destTagName
+ }
+ } else {
+ if destTagName, ok := flgs.DestNames.TagToFieldName[fieldName]; ok {
+ destFieldName = destTagName
+ }
+ }
+ if destFieldName == "" {
+ destFieldName = fieldName
+ }
+
+ // get source field name
+ if destTagName, ok := flgs.DestNames.FieldNameToTag[fieldName]; ok {
+ srcFieldName = destTagName
+ if srcField, ok := flgs.SrcNames.TagToFieldName[destTagName]; ok {
+ srcFieldName = srcField
+ }
+ } else {
+ if srcField, ok := flgs.SrcNames.TagToFieldName[fieldName]; ok {
+ srcFieldName = srcField
+ }
+ }
+
+ if srcFieldName == "" {
+ srcFieldName = fieldName
+ }
+ return
+}
+
func driverValuer(v reflect.Value) (i driver.Valuer, ok bool) {
if !v.CanAddr() {
diff --git a/vendor/github.com/klauspost/compress/zstd/blockdec.go b/vendor/github.com/klauspost/compress/zstd/blockdec.go
index e30af505c..8a98c4562 100644
--- a/vendor/github.com/klauspost/compress/zstd/blockdec.go
+++ b/vendor/github.com/klauspost/compress/zstd/blockdec.go
@@ -168,10 +168,10 @@ func (b *blockDec) reset(br byteBuffer, windowSize uint64) error {
// Read block data.
if cap(b.dataStorage) < cSize {
- if b.lowMem {
+ if b.lowMem || cSize > maxCompressedBlockSize {
b.dataStorage = make([]byte, 0, cSize)
} else {
- b.dataStorage = make([]byte, 0, maxBlockSize)
+ b.dataStorage = make([]byte, 0, maxCompressedBlockSize)
}
}
if cap(b.dst) <= maxSize {
diff --git a/vendor/github.com/klauspost/compress/zstd/decoder_options.go b/vendor/github.com/klauspost/compress/zstd/decoder_options.go
index c0fd058c2..95cc9b8b8 100644
--- a/vendor/github.com/klauspost/compress/zstd/decoder_options.go
+++ b/vendor/github.com/klauspost/compress/zstd/decoder_options.go
@@ -17,14 +17,16 @@ type decoderOptions struct {
lowMem bool
concurrent int
maxDecodedSize uint64
+ maxWindowSize uint64
dicts []dict
}
func (o *decoderOptions) setDefault() {
*o = decoderOptions{
// use less ram: true for now, but may change.
- lowMem: true,
- concurrent: runtime.GOMAXPROCS(0),
+ lowMem: true,
+ concurrent: runtime.GOMAXPROCS(0),
+ maxWindowSize: MaxWindowSize,
}
o.maxDecodedSize = 1 << 63
}
@@ -52,7 +54,6 @@ func WithDecoderConcurrency(n int) DOption {
// WithDecoderMaxMemory allows to set a maximum decoded size for in-memory
// non-streaming operations or maximum window size for streaming operations.
// This can be used to control memory usage of potentially hostile content.
-// For streaming operations, the maximum window size is capped at 1<<30 bytes.
// Maximum and default is 1 << 63 bytes.
func WithDecoderMaxMemory(n uint64) DOption {
return func(o *decoderOptions) error {
@@ -81,3 +82,21 @@ func WithDecoderDicts(dicts ...[]byte) DOption {
return nil
}
}
+
+// WithDecoderMaxWindow allows to set a maximum window size for decodes.
+// This allows rejecting packets that will cause big memory usage.
+// The Decoder will likely allocate more memory based on the WithDecoderLowmem setting.
+// If WithDecoderMaxMemory is set to a lower value, that will be used.
+// Default is 512MB, Maximum is ~3.75 TB as per zstandard spec.
+func WithDecoderMaxWindow(size uint64) DOption {
+ return func(o *decoderOptions) error {
+ if size < MinWindowSize {
+ return errors.New("WithMaxWindowSize must be at least 1KB, 1024 bytes")
+ }
+ if size > (1<<41)+7*(1<<38) {
+ return errors.New("WithMaxWindowSize must be less than (1<<41) + 7*(1<<38) ~ 3.75TB")
+ }
+ o.maxWindowSize = size
+ return nil
+ }
+}
diff --git a/vendor/github.com/klauspost/compress/zstd/framedec.go b/vendor/github.com/klauspost/compress/zstd/framedec.go
index e8cc9a2c2..989c79f8c 100644
--- a/vendor/github.com/klauspost/compress/zstd/framedec.go
+++ b/vendor/github.com/klauspost/compress/zstd/framedec.go
@@ -22,10 +22,6 @@ type frameDec struct {
WindowSize uint64
- // maxWindowSize is the maximum windows size to support.
- // should never be bigger than max-int.
- maxWindowSize uint64
-
// In order queue of blocks being decoded.
decoding chan *blockDec
@@ -50,8 +46,11 @@ type frameDec struct {
}
const (
- // The minimum Window_Size is 1 KB.
+ // MinWindowSize is the minimum Window Size, which is 1 KB.
MinWindowSize = 1 << 10
+
+ // MaxWindowSize is the maximum encoder window size
+ // and the default decoder maximum window size.
MaxWindowSize = 1 << 29
)
@@ -61,12 +60,11 @@ var (
)
func newFrameDec(o decoderOptions) *frameDec {
- d := frameDec{
- o: o,
- maxWindowSize: MaxWindowSize,
+ if o.maxWindowSize > o.maxDecodedSize {
+ o.maxWindowSize = o.maxDecodedSize
}
- if d.maxWindowSize > o.maxDecodedSize {
- d.maxWindowSize = o.maxDecodedSize
+ d := frameDec{
+ o: o,
}
return &d
}
@@ -251,13 +249,17 @@ func (d *frameDec) reset(br byteBuffer) error {
}
}
- if d.WindowSize > d.maxWindowSize {
- printf("window size %d > max %d\n", d.WindowSize, d.maxWindowSize)
+ if d.WindowSize > uint64(d.o.maxWindowSize) {
+ if debugDecoder {
+ printf("window size %d > max %d\n", d.WindowSize, d.o.maxWindowSize)
+ }
return ErrWindowSizeExceeded
}
// The minimum Window_Size is 1 KB.
if d.WindowSize < MinWindowSize {
- println("got window size: ", d.WindowSize)
+ if debugDecoder {
+ println("got window size: ", d.WindowSize)
+ }
return ErrWindowSizeTooSmall
}
d.history.windowSize = int(d.WindowSize)
@@ -352,8 +354,8 @@ func (d *frameDec) checkCRC() error {
func (d *frameDec) initAsync() {
if !d.o.lowMem && !d.SingleSegment {
- // set max extra size history to 10MB.
- d.history.maxSize = d.history.windowSize + maxBlockSize*5
+ // set max extra size history to 2MB.
+ d.history.maxSize = d.history.windowSize + maxBlockSize
}
// re-alloc if more than one extra block size.
if d.o.lowMem && cap(d.history.b) > d.history.maxSize+maxBlockSize {
diff --git a/vendor/github.com/mattn/go-runewidth/go.mod b/vendor/github.com/mattn/go-runewidth/go.mod
index 8a9d524ec..62dba1bfc 100644
--- a/vendor/github.com/mattn/go-runewidth/go.mod
+++ b/vendor/github.com/mattn/go-runewidth/go.mod
@@ -2,4 +2,4 @@ module github.com/mattn/go-runewidth
go 1.9
-require github.com/rivo/uniseg v0.1.0
+require github.com/rivo/uniseg v0.2.0
diff --git a/vendor/github.com/mattn/go-runewidth/go.sum b/vendor/github.com/mattn/go-runewidth/go.sum
index 02135660b..03f902d56 100644
--- a/vendor/github.com/mattn/go-runewidth/go.sum
+++ b/vendor/github.com/mattn/go-runewidth/go.sum
@@ -1,2 +1,2 @@
-github.com/rivo/uniseg v0.1.0 h1:+2KBaVoUmb9XzDsrx/Ct0W/EYOSFf/nWTauy++DprtY=
-github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
+github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
+github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
diff --git a/vendor/github.com/vbauerster/mpb/v7/.gitignore b/vendor/github.com/vbauerster/mpb/v7/.gitignore
new file mode 100644
index 000000000..63bd91672
--- /dev/null
+++ b/vendor/github.com/vbauerster/mpb/v7/.gitignore
@@ -0,0 +1,5 @@
+# Test binary, build with `go test -c`
+*.test
+
+# Output of the go coverage tool, specifically when used with LiteIDE
+*.out
diff --git a/vendor/github.com/vbauerster/mpb/v7/.travis.yml b/vendor/github.com/vbauerster/mpb/v7/.travis.yml
new file mode 100644
index 000000000..9a203a67d
--- /dev/null
+++ b/vendor/github.com/vbauerster/mpb/v7/.travis.yml
@@ -0,0 +1,11 @@
+language: go
+arch:
+ - amd64
+ - ppc64le
+
+go:
+ - 1.14.x
+
+script:
+ - go test -race ./...
+ - for i in _examples/*/; do go build $i/*.go || exit 1; done
diff --git a/vendor/github.com/vbauerster/mpb/v7/README.md b/vendor/github.com/vbauerster/mpb/v7/README.md
new file mode 100644
index 000000000..d0560d799
--- /dev/null
+++ b/vendor/github.com/vbauerster/mpb/v7/README.md
@@ -0,0 +1,121 @@
+# Multi Progress Bar
+
+[![GoDoc](https://pkg.go.dev/badge/github.com/vbauerster/mpb)](https://pkg.go.dev/github.com/vbauerster/mpb/v7)
+[![Build Status](https://travis-ci.org/vbauerster/mpb.svg?branch=master)](https://travis-ci.org/vbauerster/mpb)
+[![Go Report Card](https://goreportcard.com/badge/github.com/vbauerster/mpb)](https://goreportcard.com/report/github.com/vbauerster/mpb)
+[![Donate with PayPal](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://www.paypal.me/vbauerster)
+
+**mpb** is a Go lib for rendering progress bars in terminal applications.
+
+## Features
+
+- **Multiple Bars**: Multiple progress bars are supported
+- **Dynamic Total**: Set total while bar is running
+- **Dynamic Add/Remove**: Dynamically add or remove bars
+- **Cancellation**: Cancel whole rendering process
+- **Predefined Decorators**: Elapsed time, [ewma](https://github.com/VividCortex/ewma) based ETA, Percentage, Bytes counter
+- **Decorator's width sync**: Synchronized decorator's width among multiple bars
+
+## Usage
+
+#### [Rendering single bar](_examples/singleBar/main.go)
+
+```go
+package main
+
+import (
+ "math/rand"
+ "time"
+
+ "github.com/vbauerster/mpb/v7"
+ "github.com/vbauerster/mpb/v7/decor"
+)
+
+func main() {
+ // initialize progress container, with custom width
+ p := mpb.New(mpb.WithWidth(64))
+
+ total := 100
+ name := "Single Bar:"
+ // adding a single bar, which will inherit container's width
+ bar := p.Add(int64(total),
+ // progress bar filler with customized style
+ mpb.NewBarFiller(mpb.BarStyle().Lbound("╢").Filler("▌").Tip("▌").Padding("░").Rbound("╟")),
+ mpb.PrependDecorators(
+ // display our name with one space on the right
+ decor.Name(name, decor.WC{W: len(name) + 1, C: decor.DidentRight}),
+ // replace ETA decorator with "done" message, OnComplete event
+ decor.OnComplete(
+ decor.AverageETA(decor.ET_STYLE_GO, decor.WC{W: 4}), "done",
+ ),
+ ),
+ mpb.AppendDecorators(decor.Percentage()),
+ )
+ // simulating some work
+ max := 100 * time.Millisecond
+ for i := 0; i < total; i++ {
+ time.Sleep(time.Duration(rand.Intn(10)+1) * max / 10)
+ bar.Increment()
+ }
+ // wait for our bar to complete and flush
+ p.Wait()
+}
+```
+
+#### [Rendering multiple bars](_examples/multiBars/main.go)
+
+```go
+ var wg sync.WaitGroup
+ // passed &wg will be accounted at p.Wait() call
+ p := mpb.New(mpb.WithWaitGroup(&wg))
+ total, numBars := 100, 3
+ wg.Add(numBars)
+
+ for i := 0; i < numBars; i++ {
+ name := fmt.Sprintf("Bar#%d:", i)
+ bar := p.AddBar(int64(total),
+ mpb.PrependDecorators(
+ // simple name decorator
+ decor.Name(name),
+ // decor.DSyncWidth bit enables column width synchronization
+ decor.Percentage(decor.WCSyncSpace),
+ ),
+ mpb.AppendDecorators(
+ // replace ETA decorator with "done" message, OnComplete event
+ decor.OnComplete(
+ // ETA decorator with ewma age of 60
+ decor.EwmaETA(decor.ET_STYLE_GO, 60), "done",
+ ),
+ ),
+ )
+ // simulating some work
+ go func() {
+ defer wg.Done()
+ rng := rand.New(rand.NewSource(time.Now().UnixNano()))
+ max := 100 * time.Millisecond
+ for i := 0; i < total; i++ {
+ // start variable is solely for EWMA calculation
+ // EWMA's unit of measure is an iteration's duration
+ start := time.Now()
+ time.Sleep(time.Duration(rng.Intn(10)+1) * max / 10)
+ bar.Increment()
+ // we need to call DecoratorEwmaUpdate to fulfill ewma decorator's contract
+ bar.DecoratorEwmaUpdate(time.Since(start))
+ }
+ }()
+ }
+ // Waiting for passed &wg and for all bars to complete and flush
+ p.Wait()
+```
+
+#### [Dynamic total](_examples/dynTotal/main.go)
+
+![dynamic total](_svg/godEMrCZmJkHYH1X9dN4Nm0U7.svg)
+
+#### [Complex example](_examples/complex/main.go)
+
+![complex](_svg/wHzf1M7sd7B3zVa2scBMnjqRf.svg)
+
+#### [Bytes counters](_examples/io/main.go)
+
+![byte counters](_svg/hIpTa3A5rQz65ssiVuRJu87X6.svg)
diff --git a/vendor/github.com/vbauerster/mpb/v7/UNLICENSE b/vendor/github.com/vbauerster/mpb/v7/UNLICENSE
new file mode 100644
index 000000000..68a49daad
--- /dev/null
+++ b/vendor/github.com/vbauerster/mpb/v7/UNLICENSE
@@ -0,0 +1,24 @@
+This is free and unencumbered software released into the public domain.
+
+Anyone is free to copy, modify, publish, use, compile, sell, or
+distribute this software, either in source code form or as a compiled
+binary, for any purpose, commercial or non-commercial, and by any
+means.
+
+In jurisdictions that recognize copyright laws, the author or authors
+of this software dedicate any and all copyright interest in the
+software to the public domain. We make this dedication for the benefit
+of the public at large and to the detriment of our heirs and
+successors. We intend this dedication to be an overt act of
+relinquishment in perpetuity of all present and future rights to this
+software under copyright law.
+
+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 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.
+
+For more information, please refer to <http://unlicense.org/>
diff --git a/vendor/github.com/vbauerster/mpb/v7/bar.go b/vendor/github.com/vbauerster/mpb/v7/bar.go
new file mode 100644
index 000000000..ed6c73eda
--- /dev/null
+++ b/vendor/github.com/vbauerster/mpb/v7/bar.go
@@ -0,0 +1,492 @@
+package mpb
+
+import (
+ "bytes"
+ "context"
+ "fmt"
+ "io"
+ "log"
+ "runtime/debug"
+ "strings"
+ "time"
+
+ "github.com/acarl005/stripansi"
+ "github.com/mattn/go-runewidth"
+ "github.com/vbauerster/mpb/v7/decor"
+)
+
+// Bar represents a progress bar.
+type Bar struct {
+ priority int // used by heap
+ index int // used by heap
+
+ extendedLines int
+ toShutdown bool
+ toDrop bool
+ noPop bool
+ hasEwmaDecorators bool
+ operateState chan func(*bState)
+ frameCh chan io.Reader
+ syncTableCh chan [][]chan int
+ completed chan bool
+
+ // cancel is called either by user or on complete event
+ cancel func()
+ // done is closed after cacheState is assigned
+ done chan struct{}
+ // cacheState is populated, right after close(shutdown)
+ cacheState *bState
+
+ container *Progress
+ dlogger *log.Logger
+ recoveredPanic interface{}
+}
+
+type extenderFunc func(in io.Reader, reqWidth int, st decor.Statistics) (out io.Reader, lines int)
+
+// bState is actual bar state. It gets passed to *Bar.serve(...) monitor
+// goroutine.
+type bState struct {
+ id int
+ priority int
+ reqWidth int
+ total int64
+ current int64
+ refill int64
+ lastN int64
+ iterated bool
+ trimSpace bool
+ completed bool
+ completeFlushed bool
+ triggerComplete bool
+ dropOnComplete bool
+ noPop bool
+ aDecorators []decor.Decorator
+ pDecorators []decor.Decorator
+ averageDecorators []decor.AverageDecorator
+ ewmaDecorators []decor.EwmaDecorator
+ shutdownListeners []decor.ShutdownListener
+ bufP, bufB, bufA *bytes.Buffer
+ filler BarFiller
+ middleware func(BarFiller) BarFiller
+ extender extenderFunc
+
+ // runningBar is a key for *pState.parkedBars
+ runningBar *Bar
+
+ debugOut io.Writer
+}
+
+func newBar(container *Progress, bs *bState) *Bar {
+ logPrefix := fmt.Sprintf("%sbar#%02d ", container.dlogger.Prefix(), bs.id)
+ ctx, cancel := context.WithCancel(container.ctx)
+
+ bar := &Bar{
+ container: container,
+ priority: bs.priority,
+ toDrop: bs.dropOnComplete,
+ noPop: bs.noPop,
+ operateState: make(chan func(*bState)),
+ frameCh: make(chan io.Reader, 1),
+ syncTableCh: make(chan [][]chan int, 1),
+ completed: make(chan bool, 1),
+ done: make(chan struct{}),
+ cancel: cancel,
+ dlogger: log.New(bs.debugOut, logPrefix, log.Lshortfile),
+ }
+
+ go bar.serve(ctx, bs)
+ return bar
+}
+
+// ProxyReader wraps r with metrics required for progress tracking.
+// Panics if r is nil.
+func (b *Bar) ProxyReader(r io.Reader) io.ReadCloser {
+ if r == nil {
+ panic("expected non nil io.Reader")
+ }
+ return newProxyReader(r, b)
+}
+
+// ID returs id of the bar.
+func (b *Bar) ID() int {
+ result := make(chan int)
+ select {
+ case b.operateState <- func(s *bState) { result <- s.id }:
+ return <-result
+ case <-b.done:
+ return b.cacheState.id
+ }
+}
+
+// Current returns bar's current number, in other words sum of all increments.
+func (b *Bar) Current() int64 {
+ result := make(chan int64)
+ select {
+ case b.operateState <- func(s *bState) { result <- s.current }:
+ return <-result
+ case <-b.done:
+ return b.cacheState.current
+ }
+}
+
+// SetRefill sets refill flag with specified amount.
+// The underlying BarFiller will change its visual representation, to
+// indicate refill event. Refill event may be referred to some retry
+// operation for example.
+func (b *Bar) SetRefill(amount int64) {
+ select {
+ case b.operateState <- func(s *bState) {
+ s.refill = amount
+ }:
+ case <-b.done:
+ }
+}
+
+// TraverseDecorators traverses all available decorators and calls cb func on each.
+func (b *Bar) TraverseDecorators(cb func(decor.Decorator)) {
+ select {
+ case b.operateState <- func(s *bState) {
+ for _, decorators := range [...][]decor.Decorator{
+ s.pDecorators,
+ s.aDecorators,
+ } {
+ for _, d := range decorators {
+ cb(extractBaseDecorator(d))
+ }
+ }
+ }:
+ case <-b.done:
+ }
+}
+
+// SetTotal sets total dynamically.
+// If total is less than or equal to zero it takes progress' current value.
+func (b *Bar) SetTotal(total int64, triggerComplete bool) {
+ select {
+ case b.operateState <- func(s *bState) {
+ s.triggerComplete = triggerComplete
+ if total <= 0 {
+ s.total = s.current
+ } else {
+ s.total = total
+ }
+ if s.triggerComplete && !s.completed {
+ s.current = s.total
+ s.completed = true
+ go b.refreshTillShutdown()
+ }
+ }:
+ case <-b.done:
+ }
+}
+
+// SetCurrent sets progress' current to an arbitrary value.
+// Setting a negative value will cause a panic.
+func (b *Bar) SetCurrent(current int64) {
+ select {
+ case b.operateState <- func(s *bState) {
+ s.iterated = true
+ s.lastN = current - s.current
+ s.current = current
+ if s.triggerComplete && s.current >= s.total {
+ s.current = s.total
+ s.completed = true
+ go b.refreshTillShutdown()
+ }
+ }:
+ case <-b.done:
+ }
+}
+
+// Increment is a shorthand for b.IncrInt64(1).
+func (b *Bar) Increment() {
+ b.IncrInt64(1)
+}
+
+// IncrBy is a shorthand for b.IncrInt64(int64(n)).
+func (b *Bar) IncrBy(n int) {
+ b.IncrInt64(int64(n))
+}
+
+// IncrInt64 increments progress by amount of n.
+func (b *Bar) IncrInt64(n int64) {
+ select {
+ case b.operateState <- func(s *bState) {
+ s.iterated = true
+ s.lastN = n
+ s.current += n
+ if s.triggerComplete && s.current >= s.total {
+ s.current = s.total
+ s.completed = true
+ go b.refreshTillShutdown()
+ }
+ }:
+ case <-b.done:
+ }
+}
+
+// DecoratorEwmaUpdate updates all EWMA based decorators. Should be
+// called on each iteration, because EWMA's unit of measure is an
+// iteration's duration. Panics if called before *Bar.Incr... family
+// methods.
+func (b *Bar) DecoratorEwmaUpdate(dur time.Duration) {
+ select {
+ case b.operateState <- func(s *bState) {
+ ewmaIterationUpdate(false, s, dur)
+ }:
+ case <-b.done:
+ ewmaIterationUpdate(true, b.cacheState, dur)
+ }
+}
+
+// DecoratorAverageAdjust adjusts all average based decorators. Call
+// if you need to adjust start time of all average based decorators
+// or after progress resume.
+func (b *Bar) DecoratorAverageAdjust(start time.Time) {
+ select {
+ case b.operateState <- func(s *bState) {
+ for _, d := range s.averageDecorators {
+ d.AverageAdjust(start)
+ }
+ }:
+ case <-b.done:
+ }
+}
+
+// SetPriority changes bar's order among multiple bars. Zero is highest
+// priority, i.e. bar will be on top. If you don't need to set priority
+// dynamically, better use BarPriority option.
+func (b *Bar) SetPriority(priority int) {
+ select {
+ case <-b.done:
+ default:
+ b.container.setBarPriority(b, priority)
+ }
+}
+
+// Abort interrupts bar's running goroutine. Call this, if you'd like
+// to stop/remove bar before completion event. It has no effect after
+// completion event. If drop is true bar will be removed as well.
+func (b *Bar) Abort(drop bool) {
+ select {
+ case <-b.done:
+ default:
+ if drop {
+ b.container.dropBar(b)
+ }
+ b.cancel()
+ }
+}
+
+// Completed reports whether the bar is in completed state.
+func (b *Bar) Completed() bool {
+ select {
+ case b.operateState <- func(s *bState) { b.completed <- s.completed }:
+ return <-b.completed
+ case <-b.done:
+ return true
+ }
+}
+
+func (b *Bar) serve(ctx context.Context, s *bState) {
+ defer b.container.bwg.Done()
+ for {
+ select {
+ case op := <-b.operateState:
+ op(s)
+ case <-ctx.Done():
+ b.cacheState = s
+ close(b.done)
+ // Notifying decorators about shutdown event
+ for _, sl := range s.shutdownListeners {
+ sl.Shutdown()
+ }
+ return
+ }
+ }
+}
+
+func (b *Bar) render(tw int) {
+ select {
+ case b.operateState <- func(s *bState) {
+ stat := newStatistics(tw, s)
+ defer func() {
+ // recovering if user defined decorator panics for example
+ if p := recover(); p != nil {
+ if b.recoveredPanic == nil {
+ s.extender = makePanicExtender(p)
+ b.toShutdown = !b.toShutdown
+ b.recoveredPanic = p
+ }
+ frame, lines := s.extender(nil, s.reqWidth, stat)
+ b.extendedLines = lines
+ b.frameCh <- frame
+ b.dlogger.Println(p)
+ }
+ s.completeFlushed = s.completed
+ }()
+ frame, lines := s.extender(s.draw(stat), s.reqWidth, stat)
+ b.extendedLines = lines
+ b.toShutdown = s.completed && !s.completeFlushed
+ b.frameCh <- frame
+ }:
+ case <-b.done:
+ s := b.cacheState
+ stat := newStatistics(tw, s)
+ var r io.Reader
+ if b.recoveredPanic == nil {
+ r = s.draw(stat)
+ }
+ frame, lines := s.extender(r, s.reqWidth, stat)
+ b.extendedLines = lines
+ b.frameCh <- frame
+ }
+}
+
+func (b *Bar) subscribeDecorators() {
+ var averageDecorators []decor.AverageDecorator
+ var ewmaDecorators []decor.EwmaDecorator
+ var shutdownListeners []decor.ShutdownListener
+ b.TraverseDecorators(func(d decor.Decorator) {
+ if d, ok := d.(decor.AverageDecorator); ok {
+ averageDecorators = append(averageDecorators, d)
+ }
+ if d, ok := d.(decor.EwmaDecorator); ok {
+ ewmaDecorators = append(ewmaDecorators, d)
+ }
+ if d, ok := d.(decor.ShutdownListener); ok {
+ shutdownListeners = append(shutdownListeners, d)
+ }
+ })
+ select {
+ case b.operateState <- func(s *bState) {
+ s.averageDecorators = averageDecorators
+ s.ewmaDecorators = ewmaDecorators
+ s.shutdownListeners = shutdownListeners
+ }:
+ b.hasEwmaDecorators = len(ewmaDecorators) != 0
+ case <-b.done:
+ }
+}
+
+func (b *Bar) refreshTillShutdown() {
+ for {
+ select {
+ case b.container.refreshCh <- time.Now():
+ case <-b.done:
+ return
+ }
+ }
+}
+
+func (b *Bar) wSyncTable() [][]chan int {
+ select {
+ case b.operateState <- func(s *bState) { b.syncTableCh <- s.wSyncTable() }:
+ return <-b.syncTableCh
+ case <-b.done:
+ return b.cacheState.wSyncTable()
+ }
+}
+
+func (s *bState) draw(stat decor.Statistics) io.Reader {
+ nlr := strings.NewReader("\n")
+ tw := stat.AvailableWidth
+ for _, d := range s.pDecorators {
+ str := d.Decor(stat)
+ stat.AvailableWidth -= runewidth.StringWidth(stripansi.Strip(str))
+ s.bufP.WriteString(str)
+ }
+ if stat.AvailableWidth < 1 {
+ trunc := strings.NewReader(runewidth.Truncate(stripansi.Strip(s.bufP.String()), tw, "…"))
+ s.bufP.Reset()
+ return io.MultiReader(trunc, nlr)
+ }
+
+ if !s.trimSpace && stat.AvailableWidth > 1 {
+ stat.AvailableWidth -= 2
+ s.bufB.WriteByte(' ')
+ defer s.bufB.WriteByte(' ')
+ }
+
+ tw = stat.AvailableWidth
+ for _, d := range s.aDecorators {
+ str := d.Decor(stat)
+ stat.AvailableWidth -= runewidth.StringWidth(stripansi.Strip(str))
+ s.bufA.WriteString(str)
+ }
+ if stat.AvailableWidth < 1 {
+ trunc := strings.NewReader(runewidth.Truncate(stripansi.Strip(s.bufA.String()), tw, "…"))
+ s.bufA.Reset()
+ return io.MultiReader(s.bufP, s.bufB, trunc, nlr)
+ }
+
+ s.filler.Fill(s.bufB, s.reqWidth, stat)
+
+ return io.MultiReader(s.bufP, s.bufB, s.bufA, nlr)
+}
+
+func (s *bState) wSyncTable() [][]chan int {
+ columns := make([]chan int, 0, len(s.pDecorators)+len(s.aDecorators))
+ var pCount int
+ for _, d := range s.pDecorators {
+ if ch, ok := d.Sync(); ok {
+ columns = append(columns, ch)
+ pCount++
+ }
+ }
+ var aCount int
+ for _, d := range s.aDecorators {
+ if ch, ok := d.Sync(); ok {
+ columns = append(columns, ch)
+ aCount++
+ }
+ }
+ table := make([][]chan int, 2)
+ table[0] = columns[0:pCount]
+ table[1] = columns[pCount : pCount+aCount : pCount+aCount]
+ return table
+}
+
+func newStatistics(tw int, s *bState) decor.Statistics {
+ return decor.Statistics{
+ ID: s.id,
+ AvailableWidth: tw,
+ Total: s.total,
+ Current: s.current,
+ Refill: s.refill,
+ Completed: s.completeFlushed,
+ }
+}
+
+func extractBaseDecorator(d decor.Decorator) decor.Decorator {
+ if d, ok := d.(decor.Wrapper); ok {
+ return extractBaseDecorator(d.Base())
+ }
+ return d
+}
+
+func ewmaIterationUpdate(done bool, s *bState, dur time.Duration) {
+ if !done && !s.iterated {
+ panic("increment required before ewma iteration update")
+ } else {
+ s.iterated = false
+ }
+ for _, d := range s.ewmaDecorators {
+ d.EwmaUpdate(s.lastN, dur)
+ }
+}
+
+func makePanicExtender(p interface{}) extenderFunc {
+ pstr := fmt.Sprint(p)
+ stack := debug.Stack()
+ stackLines := bytes.Count(stack, []byte("\n"))
+ return func(_ io.Reader, _ int, st decor.Statistics) (io.Reader, int) {
+ mr := io.MultiReader(
+ strings.NewReader(runewidth.Truncate(pstr, st.AvailableWidth, "…")),
+ strings.NewReader(fmt.Sprintf("\n%#v\n", st)),
+ bytes.NewReader(stack),
+ )
+ return mr, stackLines + 1
+ }
+}
diff --git a/vendor/github.com/vbauerster/mpb/v7/bar_filler.go b/vendor/github.com/vbauerster/mpb/v7/bar_filler.go
new file mode 100644
index 000000000..a69087c47
--- /dev/null
+++ b/vendor/github.com/vbauerster/mpb/v7/bar_filler.go
@@ -0,0 +1,39 @@
+package mpb
+
+import (
+ "io"
+
+ "github.com/vbauerster/mpb/v7/decor"
+)
+
+// BarFiller interface.
+// Bar (without decorators) renders itself by calling BarFiller's Fill method.
+//
+// reqWidth is requested width, set by `func WithWidth(int) ContainerOption`.
+// If not set, it defaults to terminal width.
+//
+// Default implementations can be obtained via:
+//
+// func NewBarFiller(BarStyle()) BarFiller
+// func NewBarFiller(SpinnerStyle()) BarFiller
+//
+type BarFiller interface {
+ Fill(w io.Writer, reqWidth int, stat decor.Statistics)
+}
+
+// BarFillerBuilder interface.
+type BarFillerBuilder interface {
+ Build() BarFiller
+}
+
+// BarFillerFunc is function type adapter to convert function into BarFiller.
+type BarFillerFunc func(w io.Writer, reqWidth int, stat decor.Statistics)
+
+func (f BarFillerFunc) Fill(w io.Writer, reqWidth int, stat decor.Statistics) {
+ f(w, reqWidth, stat)
+}
+
+// NewBarFiller constructs a BarFiller from provided BarFillerBuilder.
+func NewBarFiller(b BarFillerBuilder) BarFiller {
+ return b.Build()
+}
diff --git a/vendor/github.com/vbauerster/mpb/v7/bar_filler_bar.go b/vendor/github.com/vbauerster/mpb/v7/bar_filler_bar.go
new file mode 100644
index 000000000..e30d4921c
--- /dev/null
+++ b/vendor/github.com/vbauerster/mpb/v7/bar_filler_bar.go
@@ -0,0 +1,219 @@
+package mpb
+
+import (
+ "io"
+
+ "github.com/acarl005/stripansi"
+ "github.com/mattn/go-runewidth"
+ "github.com/vbauerster/mpb/v7/decor"
+ "github.com/vbauerster/mpb/v7/internal"
+)
+
+const (
+ iLbound = iota
+ iRbound
+ iFiller
+ iRefiller
+ iPadding
+ components
+)
+
+// BarStyleComposer interface.
+type BarStyleComposer interface {
+ BarFillerBuilder
+ Lbound(string) BarStyleComposer
+ Rbound(string) BarStyleComposer
+ Filler(string) BarStyleComposer
+ Refiller(string) BarStyleComposer
+ Padding(string) BarStyleComposer
+ Tip(...string) BarStyleComposer
+ Reverse() BarStyleComposer
+}
+
+type bFiller struct {
+ components [components]*component
+ tip struct {
+ count uint
+ frames []*component
+ }
+ flush func(dst io.Writer, filling, padding [][]byte)
+}
+
+type component struct {
+ width int
+ bytes []byte
+}
+
+type barStyle struct {
+ lbound string
+ rbound string
+ filler string
+ refiller string
+ padding string
+ tip []string
+ rev bool
+}
+
+// BarStyle constructs default bar style which can be altered via
+// BarStyleComposer interface.
+func BarStyle() BarStyleComposer {
+ return &barStyle{
+ lbound: "[",
+ rbound: "]",
+ filler: "=",
+ refiller: "+",
+ padding: "-",
+ tip: []string{">"},
+ }
+}
+
+func (s *barStyle) Lbound(bound string) BarStyleComposer {
+ s.lbound = bound
+ return s
+}
+
+func (s *barStyle) Rbound(bound string) BarStyleComposer {
+ s.rbound = bound
+ return s
+}
+
+func (s *barStyle) Filler(filler string) BarStyleComposer {
+ s.filler = filler
+ return s
+}
+
+func (s *barStyle) Refiller(refiller string) BarStyleComposer {
+ s.refiller = refiller
+ return s
+}
+
+func (s *barStyle) Padding(padding string) BarStyleComposer {
+ s.padding = padding
+ return s
+}
+
+func (s *barStyle) Tip(tip ...string) BarStyleComposer {
+ if len(tip) != 0 {
+ s.tip = append(s.tip[:0], tip...)
+ }
+ return s
+}
+
+func (s *barStyle) Reverse() BarStyleComposer {
+ s.rev = true
+ return s
+}
+
+func (s *barStyle) Build() BarFiller {
+ bf := new(bFiller)
+ if s.rev {
+ bf.flush = func(dst io.Writer, filling, padding [][]byte) {
+ flush(dst, padding, filling)
+ }
+ } else {
+ bf.flush = flush
+ }
+ bf.components[iLbound] = &component{
+ width: runewidth.StringWidth(stripansi.Strip(s.lbound)),
+ bytes: []byte(s.lbound),
+ }
+ bf.components[iRbound] = &component{
+ width: runewidth.StringWidth(stripansi.Strip(s.rbound)),
+ bytes: []byte(s.rbound),
+ }
+ bf.components[iFiller] = &component{
+ width: runewidth.StringWidth(stripansi.Strip(s.filler)),
+ bytes: []byte(s.filler),
+ }
+ bf.components[iRefiller] = &component{
+ width: runewidth.StringWidth(stripansi.Strip(s.refiller)),
+ bytes: []byte(s.refiller),
+ }
+ bf.components[iPadding] = &component{
+ width: runewidth.StringWidth(stripansi.Strip(s.padding)),
+ bytes: []byte(s.padding),
+ }
+ bf.tip.frames = make([]*component, len(s.tip))
+ for i, t := range s.tip {
+ bf.tip.frames[i] = &component{
+ width: runewidth.StringWidth(stripansi.Strip(t)),
+ bytes: []byte(t),
+ }
+ }
+ return bf
+}
+
+func (s *bFiller) Fill(w io.Writer, width int, stat decor.Statistics) {
+ width = internal.CheckRequestedWidth(width, stat.AvailableWidth)
+ brackets := s.components[iLbound].width + s.components[iRbound].width
+ if width < brackets {
+ return
+ }
+ // don't count brackets as progress
+ width -= brackets
+
+ w.Write(s.components[iLbound].bytes)
+ defer w.Write(s.components[iRbound].bytes)
+
+ curWidth := int(internal.PercentageRound(stat.Total, stat.Current, width))
+ refWidth, filled := 0, curWidth
+ filling := make([][]byte, 0, curWidth)
+
+ if curWidth > 0 && curWidth != width {
+ tipFrame := s.tip.frames[s.tip.count%uint(len(s.tip.frames))]
+ filling = append(filling, tipFrame.bytes)
+ curWidth -= tipFrame.width
+ s.tip.count++
+ }
+
+ if stat.Refill > 0 && curWidth > 0 {
+ refWidth = int(internal.PercentageRound(stat.Total, int64(stat.Refill), width))
+ if refWidth > curWidth {
+ refWidth = curWidth
+ }
+ curWidth -= refWidth
+ }
+
+ for curWidth > 0 && curWidth >= s.components[iFiller].width {
+ filling = append(filling, s.components[iFiller].bytes)
+ curWidth -= s.components[iFiller].width
+ if s.components[iFiller].width == 0 {
+ break
+ }
+ }
+
+ for refWidth > 0 && refWidth >= s.components[iRefiller].width {
+ filling = append(filling, s.components[iRefiller].bytes)
+ refWidth -= s.components[iRefiller].width
+ if s.components[iRefiller].width == 0 {
+ break
+ }
+ }
+
+ filled -= curWidth + refWidth
+ padWidth := width - filled
+ padding := make([][]byte, 0, padWidth)
+ for padWidth > 0 && padWidth >= s.components[iPadding].width {
+ padding = append(padding, s.components[iPadding].bytes)
+ padWidth -= s.components[iPadding].width
+ if s.components[iPadding].width == 0 {
+ break
+ }
+ }
+
+ for padWidth > 0 {
+ padding = append(padding, []byte("…"))
+ padWidth--
+ }
+
+ s.flush(w, filling, padding)
+}
+
+func flush(dst io.Writer, filling, padding [][]byte) {
+ for i := len(filling) - 1; i >= 0; i-- {
+ dst.Write(filling[i])
+ }
+ for i := 0; i < len(padding); i++ {
+ dst.Write(padding[i])
+ }
+}
diff --git a/vendor/github.com/vbauerster/mpb/v7/bar_filler_spinner.go b/vendor/github.com/vbauerster/mpb/v7/bar_filler_spinner.go
new file mode 100644
index 000000000..58ae1c532
--- /dev/null
+++ b/vendor/github.com/vbauerster/mpb/v7/bar_filler_spinner.go
@@ -0,0 +1,87 @@
+package mpb
+
+import (
+ "io"
+ "strings"
+
+ "github.com/acarl005/stripansi"
+ "github.com/mattn/go-runewidth"
+ "github.com/vbauerster/mpb/v7/decor"
+ "github.com/vbauerster/mpb/v7/internal"
+)
+
+const (
+ positionLeft = 1 + iota
+ positionRight
+)
+
+// SpinnerStyleComposer interface.
+type SpinnerStyleComposer interface {
+ BarFillerBuilder
+ PositionLeft() SpinnerStyleComposer
+ PositionRight() SpinnerStyleComposer
+}
+
+type sFiller struct {
+ count uint
+ position uint
+ frames []string
+}
+
+type spinnerStyle struct {
+ position uint
+ frames []string
+}
+
+// SpinnerStyle constructs default spinner style which can be altered via
+// SpinnerStyleComposer interface.
+func SpinnerStyle(frames ...string) SpinnerStyleComposer {
+ ss := new(spinnerStyle)
+ if len(frames) != 0 {
+ ss.frames = append(ss.frames, frames...)
+ } else {
+ ss.frames = []string{"⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"}
+ }
+ return ss
+}
+
+func (s *spinnerStyle) PositionLeft() SpinnerStyleComposer {
+ s.position = positionLeft
+ return s
+}
+
+func (s *spinnerStyle) PositionRight() SpinnerStyleComposer {
+ s.position = positionRight
+ return s
+}
+
+func (s *spinnerStyle) Build() BarFiller {
+ sf := &sFiller{
+ position: s.position,
+ frames: s.frames,
+ }
+ return sf
+}
+
+func (s *sFiller) Fill(w io.Writer, width int, stat decor.Statistics) {
+ width = internal.CheckRequestedWidth(width, stat.AvailableWidth)
+
+ frame := s.frames[s.count%uint(len(s.frames))]
+ frameWidth := runewidth.StringWidth(stripansi.Strip(frame))
+
+ if width < frameWidth {
+ return
+ }
+
+ rest := width - frameWidth
+ switch s.position {
+ case positionLeft:
+ io.WriteString(w, frame+strings.Repeat(" ", rest))
+ case positionRight:
+ io.WriteString(w, strings.Repeat(" ", rest)+frame)
+ default:
+ str := strings.Repeat(" ", rest/2) + frame + strings.Repeat(" ", rest/2+rest%2)
+ io.WriteString(w, str)
+ }
+ s.count++
+}
diff --git a/vendor/github.com/vbauerster/mpb/v7/bar_option.go b/vendor/github.com/vbauerster/mpb/v7/bar_option.go
new file mode 100644
index 000000000..46b7de0bf
--- /dev/null
+++ b/vendor/github.com/vbauerster/mpb/v7/bar_option.go
@@ -0,0 +1,153 @@
+package mpb
+
+import (
+ "bytes"
+ "io"
+
+ "github.com/vbauerster/mpb/v7/decor"
+ "github.com/vbauerster/mpb/v7/internal"
+)
+
+// BarOption is a func option to alter default behavior of a bar.
+type BarOption func(*bState)
+
+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()...)
+ }
+ *dest = append(*dest, decorator)
+ }
+}
+
+// AppendDecorators let you inject decorators to the bar's right side.
+func AppendDecorators(decorators ...decor.Decorator) BarOption {
+ return func(s *bState) {
+ s.addDecorators(&s.aDecorators, decorators...)
+ }
+}
+
+// PrependDecorators let you inject decorators to the bar's left side.
+func PrependDecorators(decorators ...decor.Decorator) BarOption {
+ return func(s *bState) {
+ s.addDecorators(&s.pDecorators, decorators...)
+ }
+}
+
+// BarID sets bar id.
+func BarID(id int) BarOption {
+ return func(s *bState) {
+ s.id = id
+ }
+}
+
+// BarWidth sets bar width independent of the container.
+func BarWidth(width int) BarOption {
+ return func(s *bState) {
+ s.reqWidth = width
+ }
+}
+
+// BarQueueAfter queues this (being constructed) bar to relplace
+// runningBar after it has been completed.
+func BarQueueAfter(runningBar *Bar) BarOption {
+ if runningBar == nil {
+ return nil
+ }
+ return func(s *bState) {
+ s.runningBar = runningBar
+ }
+}
+
+// BarRemoveOnComplete removes both bar's filler and its decorators
+// on complete event.
+func BarRemoveOnComplete() BarOption {
+ return func(s *bState) {
+ s.dropOnComplete = true
+ }
+}
+
+// BarFillerClearOnComplete clears bar's filler on complete event.
+// It's shortcut for BarFillerOnComplete("").
+func BarFillerClearOnComplete() BarOption {
+ return BarFillerOnComplete("")
+}
+
+// BarFillerOnComplete replaces bar's filler with message, on complete event.
+func BarFillerOnComplete(message string) BarOption {
+ return BarFillerMiddleware(func(base BarFiller) BarFiller {
+ return BarFillerFunc(func(w io.Writer, reqWidth int, st decor.Statistics) {
+ if st.Completed {
+ io.WriteString(w, message)
+ } else {
+ base.Fill(w, reqWidth, st)
+ }
+ })
+ })
+}
+
+// BarFillerMiddleware provides a way to augment the underlying BarFiller.
+func BarFillerMiddleware(middle func(BarFiller) BarFiller) BarOption {
+ return func(s *bState) {
+ s.middleware = middle
+ }
+}
+
+// BarPriority sets bar's priority. Zero is highest priority, i.e. bar
+// will be on top. If `BarReplaceOnComplete` option is supplied, this
+// option is ignored.
+func BarPriority(priority int) BarOption {
+ return func(s *bState) {
+ s.priority = priority
+ }
+}
+
+// BarExtender provides a way to extend bar to the next new line.
+func BarExtender(filler BarFiller) BarOption {
+ if filler == nil {
+ return nil
+ }
+ return func(s *bState) {
+ s.extender = makeExtenderFunc(filler)
+ }
+}
+
+func makeExtenderFunc(filler BarFiller) extenderFunc {
+ buf := new(bytes.Buffer)
+ return func(r io.Reader, reqWidth int, st decor.Statistics) (io.Reader, int) {
+ filler.Fill(buf, reqWidth, st)
+ return io.MultiReader(r, buf), bytes.Count(buf.Bytes(), []byte("\n"))
+ }
+}
+
+// BarFillerTrim removes leading and trailing space around the underlying BarFiller.
+func BarFillerTrim() BarOption {
+ return func(s *bState) {
+ s.trimSpace = true
+ }
+}
+
+// BarNoPop disables bar pop out of container. Effective when
+// PopCompletedMode of container is enabled.
+func BarNoPop() BarOption {
+ return func(s *bState) {
+ s.noPop = true
+ }
+}
+
+// BarOptional will invoke provided option only when pick is true.
+func BarOptional(option BarOption, pick bool) BarOption {
+ return BarOptOn(option, internal.Predicate(pick))
+}
+
+// BarOptOn will invoke provided option only when higher order predicate
+// evaluates to true.
+func BarOptOn(option BarOption, predicate func() bool) BarOption {
+ if predicate() {
+ return option
+ }
+ return nil
+}
diff --git a/vendor/github.com/vbauerster/mpb/v7/container_option.go b/vendor/github.com/vbauerster/mpb/v7/container_option.go
new file mode 100644
index 000000000..e4254f662
--- /dev/null
+++ b/vendor/github.com/vbauerster/mpb/v7/container_option.go
@@ -0,0 +1,112 @@
+package mpb
+
+import (
+ "io"
+ "io/ioutil"
+ "sync"
+ "time"
+
+ "github.com/vbauerster/mpb/v7/internal"
+)
+
+// ContainerOption is a func option to alter default behavior of a bar
+// container. Container term refers to a Progress struct which can
+// hold one or more Bars.
+type ContainerOption func(*pState)
+
+// WithWaitGroup provides means to have a single joint point. If
+// *sync.WaitGroup is provided, you can safely call just p.Wait()
+// without calling Wait() on provided *sync.WaitGroup. Makes sense
+// when there are more than one bar to render.
+func WithWaitGroup(wg *sync.WaitGroup) ContainerOption {
+ return func(s *pState) {
+ s.uwg = wg
+ }
+}
+
+// WithWidth sets container width. If not set it defaults to terminal
+// width. A bar added to the container will inherit its width, unless
+// overridden by `func BarWidth(int) BarOption`.
+func WithWidth(width int) ContainerOption {
+ return func(s *pState) {
+ s.reqWidth = width
+ }
+}
+
+// WithRefreshRate overrides default 120ms refresh rate.
+func WithRefreshRate(d time.Duration) ContainerOption {
+ return func(s *pState) {
+ s.rr = d
+ }
+}
+
+// WithManualRefresh disables internal auto refresh time.Ticker.
+// Refresh will occur upon receive value from provided ch.
+func WithManualRefresh(ch <-chan interface{}) ContainerOption {
+ return func(s *pState) {
+ s.externalRefresh = ch
+ }
+}
+
+// WithRenderDelay delays rendering. By default rendering starts as
+// soon as bar is added, with this option it's possible to delay
+// rendering process by keeping provided chan unclosed. In other words
+// rendering will start as soon as provided chan is closed.
+func WithRenderDelay(ch <-chan struct{}) ContainerOption {
+ return func(s *pState) {
+ s.renderDelay = ch
+ }
+}
+
+// WithShutdownNotifier provided chanel will be closed, after all bars
+// have been rendered.
+func WithShutdownNotifier(ch chan struct{}) ContainerOption {
+ return func(s *pState) {
+ s.shutdownNotifier = ch
+ }
+}
+
+// WithOutput overrides default os.Stdout output. Setting it to nil
+// will effectively disable auto refresh rate and discard any output,
+// useful if you want to disable progress bars with little overhead.
+func WithOutput(w io.Writer) ContainerOption {
+ return func(s *pState) {
+ if w == nil {
+ s.output = ioutil.Discard
+ s.outputDiscarded = true
+ return
+ }
+ s.output = w
+ }
+}
+
+// WithDebugOutput sets debug output.
+func WithDebugOutput(w io.Writer) ContainerOption {
+ if w == nil {
+ return nil
+ }
+ return func(s *pState) {
+ s.debugOut = w
+ }
+}
+
+// PopCompletedMode will pop and stop rendering completed bars.
+func PopCompletedMode() ContainerOption {
+ return func(s *pState) {
+ s.popCompleted = true
+ }
+}
+
+// ContainerOptional will invoke provided option only when pick is true.
+func ContainerOptional(option ContainerOption, pick bool) ContainerOption {
+ return ContainerOptOn(option, internal.Predicate(pick))
+}
+
+// ContainerOptOn will invoke provided option only when higher order
+// predicate evaluates to true.
+func ContainerOptOn(option ContainerOption, predicate func() bool) ContainerOption {
+ if predicate() {
+ return option
+ }
+ return nil
+}
diff --git a/vendor/github.com/vbauerster/mpb/v7/cwriter/doc.go b/vendor/github.com/vbauerster/mpb/v7/cwriter/doc.go
new file mode 100644
index 000000000..93c8f8268
--- /dev/null
+++ b/vendor/github.com/vbauerster/mpb/v7/cwriter/doc.go
@@ -0,0 +1,2 @@
+// Package cwriter is a console writer abstraction for the underlying OS.
+package cwriter
diff --git a/vendor/github.com/vbauerster/mpb/v7/cwriter/util_bsd.go b/vendor/github.com/vbauerster/mpb/v7/cwriter/util_bsd.go
new file mode 100644
index 000000000..4e3564ece
--- /dev/null
+++ b/vendor/github.com/vbauerster/mpb/v7/cwriter/util_bsd.go
@@ -0,0 +1,7 @@
+// +build darwin dragonfly freebsd netbsd openbsd
+
+package cwriter
+
+import "golang.org/x/sys/unix"
+
+const ioctlReadTermios = unix.TIOCGETA
diff --git a/vendor/github.com/vbauerster/mpb/v7/cwriter/util_linux.go b/vendor/github.com/vbauerster/mpb/v7/cwriter/util_linux.go
new file mode 100644
index 000000000..253f12dd2
--- /dev/null
+++ b/vendor/github.com/vbauerster/mpb/v7/cwriter/util_linux.go
@@ -0,0 +1,7 @@
+// +build aix linux
+
+package cwriter
+
+import "golang.org/x/sys/unix"
+
+const ioctlReadTermios = unix.TCGETS
diff --git a/vendor/github.com/vbauerster/mpb/v7/cwriter/util_solaris.go b/vendor/github.com/vbauerster/mpb/v7/cwriter/util_solaris.go
new file mode 100644
index 000000000..4b29ff5c0
--- /dev/null
+++ b/vendor/github.com/vbauerster/mpb/v7/cwriter/util_solaris.go
@@ -0,0 +1,7 @@
+// +build solaris
+
+package cwriter
+
+import "golang.org/x/sys/unix"
+
+const ioctlReadTermios = unix.TCGETA
diff --git a/vendor/github.com/vbauerster/mpb/v7/cwriter/writer.go b/vendor/github.com/vbauerster/mpb/v7/cwriter/writer.go
new file mode 100644
index 000000000..1ade54761
--- /dev/null
+++ b/vendor/github.com/vbauerster/mpb/v7/cwriter/writer.go
@@ -0,0 +1,84 @@
+package cwriter
+
+import (
+ "bytes"
+ "errors"
+ "io"
+ "os"
+ "strconv"
+)
+
+// ErrNotTTY not a TeleTYpewriter error.
+var ErrNotTTY = errors.New("not a terminal")
+
+// http://ascii-table.com/ansi-escape-sequences.php
+const (
+ escOpen = "\x1b["
+ cuuAndEd = "A\x1b[J"
+)
+
+// Writer is a buffered the writer that updates the terminal. The
+// contents of writer will be flushed when Flush is called.
+type Writer struct {
+ out io.Writer
+ buf bytes.Buffer
+ lineCount int
+ fd int
+ isTerminal bool
+}
+
+// New returns a new Writer with defaults.
+func New(out io.Writer) *Writer {
+ w := &Writer{out: out}
+ if f, ok := out.(*os.File); ok {
+ w.fd = int(f.Fd())
+ w.isTerminal = IsTerminal(w.fd)
+ }
+ return w
+}
+
+// Flush flushes the underlying buffer.
+func (w *Writer) Flush(lineCount int) (err error) {
+ // some terminals interpret 'cursor up 0' as 'cursor up 1'
+ if w.lineCount > 0 {
+ err = w.clearLines()
+ if err != nil {
+ return
+ }
+ }
+ w.lineCount = lineCount
+ _, err = w.buf.WriteTo(w.out)
+ return
+}
+
+// Write appends the contents of p to the underlying buffer.
+func (w *Writer) Write(p []byte) (n int, err error) {
+ return w.buf.Write(p)
+}
+
+// WriteString writes string to the underlying buffer.
+func (w *Writer) WriteString(s string) (n int, err error) {
+ return w.buf.WriteString(s)
+}
+
+// ReadFrom reads from the provided io.Reader and writes to the
+// underlying buffer.
+func (w *Writer) ReadFrom(r io.Reader) (n int64, err error) {
+ return w.buf.ReadFrom(r)
+}
+
+// GetWidth returns width of underlying terminal.
+func (w *Writer) GetWidth() (int, error) {
+ if !w.isTerminal {
+ return -1, ErrNotTTY
+ }
+ tw, _, err := GetSize(w.fd)
+ return tw, err
+}
+
+func (w *Writer) ansiCuuAndEd() (err error) {
+ buf := make([]byte, 8)
+ buf = strconv.AppendInt(buf[:copy(buf, escOpen)], int64(w.lineCount), 10)
+ _, err = w.out.Write(append(buf, cuuAndEd...))
+ return
+}
diff --git a/vendor/github.com/vbauerster/mpb/v7/cwriter/writer_posix.go b/vendor/github.com/vbauerster/mpb/v7/cwriter/writer_posix.go
new file mode 100644
index 000000000..f54a5d06b
--- /dev/null
+++ b/vendor/github.com/vbauerster/mpb/v7/cwriter/writer_posix.go
@@ -0,0 +1,26 @@
+// +build !windows
+
+package cwriter
+
+import (
+ "golang.org/x/sys/unix"
+)
+
+func (w *Writer) clearLines() error {
+ return w.ansiCuuAndEd()
+}
+
+// GetSize returns the dimensions of the given terminal.
+func GetSize(fd int) (width, height int, err error) {
+ ws, err := unix.IoctlGetWinsize(fd, unix.TIOCGWINSZ)
+ if err != nil {
+ return -1, -1, err
+ }
+ return int(ws.Col), int(ws.Row), nil
+}
+
+// IsTerminal returns whether the given file descriptor is a terminal.
+func IsTerminal(fd int) bool {
+ _, err := unix.IoctlGetTermios(fd, ioctlReadTermios)
+ return err == nil
+}
diff --git a/vendor/github.com/vbauerster/mpb/v7/cwriter/writer_windows.go b/vendor/github.com/vbauerster/mpb/v7/cwriter/writer_windows.go
new file mode 100644
index 000000000..1a69c81ac
--- /dev/null
+++ b/vendor/github.com/vbauerster/mpb/v7/cwriter/writer_windows.go
@@ -0,0 +1,73 @@
+// +build windows
+
+package cwriter
+
+import (
+ "unsafe"
+
+ "golang.org/x/sys/windows"
+)
+
+var kernel32 = windows.NewLazySystemDLL("kernel32.dll")
+
+var (
+ procSetConsoleCursorPosition = kernel32.NewProc("SetConsoleCursorPosition")
+ procFillConsoleOutputCharacter = kernel32.NewProc("FillConsoleOutputCharacterW")
+)
+
+func (w *Writer) clearLines() error {
+ if !w.isTerminal {
+ // hope it's cygwin or similar
+ return w.ansiCuuAndEd()
+ }
+
+ var info windows.ConsoleScreenBufferInfo
+ if err := windows.GetConsoleScreenBufferInfo(windows.Handle(w.fd), &info); err != nil {
+ return err
+ }
+
+ info.CursorPosition.Y -= int16(w.lineCount)
+ if info.CursorPosition.Y < 0 {
+ info.CursorPosition.Y = 0
+ }
+ _, _, _ = procSetConsoleCursorPosition.Call(
+ uintptr(w.fd),
+ uintptr(uint32(uint16(info.CursorPosition.Y))<<16|uint32(uint16(info.CursorPosition.X))),
+ )
+
+ // clear the lines
+ cursor := &windows.Coord{
+ X: info.Window.Left,
+ Y: info.CursorPosition.Y,
+ }
+ count := uint32(info.Size.X) * uint32(w.lineCount)
+ _, _, _ = procFillConsoleOutputCharacter.Call(
+ uintptr(w.fd),
+ uintptr(' '),
+ uintptr(count),
+ *(*uintptr)(unsafe.Pointer(cursor)),
+ uintptr(unsafe.Pointer(new(uint32))),
+ )
+ return nil
+}
+
+// GetSize returns the visible dimensions of the given terminal.
+//
+// These dimensions don't include any scrollback buffer height.
+func GetSize(fd int) (width, height int, err error) {
+ var info windows.ConsoleScreenBufferInfo
+ if err := windows.GetConsoleScreenBufferInfo(windows.Handle(fd), &info); err != nil {
+ return 0, 0, err
+ }
+ // terminal.GetSize from crypto/ssh adds "+ 1" to both width and height:
+ // https://go.googlesource.com/crypto/+/refs/heads/release-branch.go1.14/ssh/terminal/util_windows.go#75
+ // but looks like this is a root cause of issue #66, so removing both "+ 1" have fixed it.
+ return int(info.Window.Right - info.Window.Left), int(info.Window.Bottom - info.Window.Top), nil
+}
+
+// IsTerminal returns whether the given file descriptor is a terminal.
+func IsTerminal(fd int) bool {
+ var st uint32
+ err := windows.GetConsoleMode(windows.Handle(fd), &st)
+ return err == nil
+}
diff --git a/vendor/github.com/vbauerster/mpb/v7/decor/any.go b/vendor/github.com/vbauerster/mpb/v7/decor/any.go
new file mode 100644
index 000000000..39518f594
--- /dev/null
+++ b/vendor/github.com/vbauerster/mpb/v7/decor/any.go
@@ -0,0 +1,21 @@
+package decor
+
+// Any decorator displays text, that can be changed during decorator's
+// lifetime via provided DecorFunc.
+//
+// `fn` DecorFunc callback
+//
+// `wcc` optional WC config
+//
+func Any(fn DecorFunc, wcc ...WC) Decorator {
+ return &any{initWC(wcc...), fn}
+}
+
+type any struct {
+ WC
+ fn DecorFunc
+}
+
+func (d *any) Decor(s Statistics) string {
+ return d.FormatMsg(d.fn(s))
+}
diff --git a/vendor/github.com/vbauerster/mpb/v7/decor/counters.go b/vendor/github.com/vbauerster/mpb/v7/decor/counters.go
new file mode 100644
index 000000000..4a5343d41
--- /dev/null
+++ b/vendor/github.com/vbauerster/mpb/v7/decor/counters.go
@@ -0,0 +1,243 @@
+package decor
+
+import (
+ "fmt"
+ "strings"
+)
+
+const (
+ _ = iota
+ UnitKiB
+ UnitKB
+)
+
+// CountersNoUnit is a wrapper around Counters with no unit param.
+func CountersNoUnit(pairFmt string, wcc ...WC) Decorator {
+ return Counters(0, pairFmt, wcc...)
+}
+
+// CountersKibiByte is a wrapper around Counters with predefined unit
+// UnitKiB (bytes/1024).
+func CountersKibiByte(pairFmt string, wcc ...WC) Decorator {
+ return Counters(UnitKiB, pairFmt, wcc...)
+}
+
+// CountersKiloByte is a wrapper around Counters with predefined unit
+// UnitKB (bytes/1000).
+func CountersKiloByte(pairFmt string, wcc ...WC) Decorator {
+ return Counters(UnitKB, pairFmt, wcc...)
+}
+
+// Counters decorator with dynamic unit measure adjustment.
+//
+// `unit` one of [0|UnitKiB|UnitKB] zero for no unit
+//
+// `pairFmt` printf compatible verbs for current and total pair
+//
+// `wcc` optional WC config
+//
+// pairFmt example if unit=UnitKB:
+//
+// pairFmt="%.1f / %.1f" output: "1.0MB / 12.0MB"
+// pairFmt="% .1f / % .1f" output: "1.0 MB / 12.0 MB"
+// pairFmt="%d / %d" output: "1MB / 12MB"
+// pairFmt="% d / % d" output: "1 MB / 12 MB"
+//
+func Counters(unit int, pairFmt string, wcc ...WC) Decorator {
+ producer := func(unit int, pairFmt string) DecorFunc {
+ if pairFmt == "" {
+ pairFmt = "%d / %d"
+ } else if strings.Count(pairFmt, "%") != 2 {
+ panic("expected pairFmt with exactly 2 verbs")
+ }
+ switch unit {
+ case UnitKiB:
+ return func(s Statistics) string {
+ return fmt.Sprintf(pairFmt, SizeB1024(s.Current), SizeB1024(s.Total))
+ }
+ case UnitKB:
+ return func(s Statistics) string {
+ return fmt.Sprintf(pairFmt, SizeB1000(s.Current), SizeB1000(s.Total))
+ }
+ default:
+ return func(s Statistics) string {
+ return fmt.Sprintf(pairFmt, s.Current, s.Total)
+ }
+ }
+ }
+ return Any(producer(unit, pairFmt), wcc...)
+}
+
+// TotalNoUnit is a wrapper around Total with no unit param.
+func TotalNoUnit(format string, wcc ...WC) Decorator {
+ return Total(0, format, wcc...)
+}
+
+// TotalKibiByte is a wrapper around Total with predefined unit
+// UnitKiB (bytes/1024).
+func TotalKibiByte(format string, wcc ...WC) Decorator {
+ return Total(UnitKiB, format, wcc...)
+}
+
+// TotalKiloByte is a wrapper around Total with predefined unit
+// UnitKB (bytes/1000).
+func TotalKiloByte(format string, wcc ...WC) Decorator {
+ return Total(UnitKB, format, wcc...)
+}
+
+// Total decorator with dynamic unit measure adjustment.
+//
+// `unit` one of [0|UnitKiB|UnitKB] zero for no unit
+//
+// `format` printf compatible verb for Total
+//
+// `wcc` optional WC config
+//
+// format example if unit=UnitKiB:
+//
+// format="%.1f" output: "12.0MiB"
+// format="% .1f" output: "12.0 MiB"
+// format="%d" output: "12MiB"
+// format="% d" output: "12 MiB"
+//
+func Total(unit int, format string, wcc ...WC) Decorator {
+ producer := func(unit int, format string) DecorFunc {
+ if format == "" {
+ format = "%d"
+ } else if strings.Count(format, "%") != 1 {
+ panic("expected format with exactly 1 verb")
+ }
+
+ switch unit {
+ case UnitKiB:
+ return func(s Statistics) string {
+ return fmt.Sprintf(format, SizeB1024(s.Total))
+ }
+ case UnitKB:
+ return func(s Statistics) string {
+ return fmt.Sprintf(format, SizeB1000(s.Total))
+ }
+ default:
+ return func(s Statistics) string {
+ return fmt.Sprintf(format, s.Total)
+ }
+ }
+ }
+ return Any(producer(unit, format), wcc...)
+}
+
+// CurrentNoUnit is a wrapper around Current with no unit param.
+func CurrentNoUnit(format string, wcc ...WC) Decorator {
+ return Current(0, format, wcc...)
+}
+
+// CurrentKibiByte is a wrapper around Current with predefined unit
+// UnitKiB (bytes/1024).
+func CurrentKibiByte(format string, wcc ...WC) Decorator {
+ return Current(UnitKiB, format, wcc...)
+}
+
+// CurrentKiloByte is a wrapper around Current with predefined unit
+// UnitKB (bytes/1000).
+func CurrentKiloByte(format string, wcc ...WC) Decorator {
+ return Current(UnitKB, format, wcc...)
+}
+
+// Current decorator with dynamic unit measure adjustment.
+//
+// `unit` one of [0|UnitKiB|UnitKB] zero for no unit
+//
+// `format` printf compatible verb for Current
+//
+// `wcc` optional WC config
+//
+// format example if unit=UnitKiB:
+//
+// format="%.1f" output: "12.0MiB"
+// format="% .1f" output: "12.0 MiB"
+// format="%d" output: "12MiB"
+// format="% d" output: "12 MiB"
+//
+func Current(unit int, format string, wcc ...WC) Decorator {
+ producer := func(unit int, format string) DecorFunc {
+ if format == "" {
+ format = "%d"
+ } else if strings.Count(format, "%") != 1 {
+ panic("expected format with exactly 1 verb")
+ }
+
+ switch unit {
+ case UnitKiB:
+ return func(s Statistics) string {
+ return fmt.Sprintf(format, SizeB1024(s.Current))
+ }
+ case UnitKB:
+ return func(s Statistics) string {
+ return fmt.Sprintf(format, SizeB1000(s.Current))
+ }
+ default:
+ return func(s Statistics) string {
+ return fmt.Sprintf(format, s.Current)
+ }
+ }
+ }
+ return Any(producer(unit, format), wcc...)
+}
+
+// InvertedCurrentNoUnit is a wrapper around InvertedCurrent with no unit param.
+func InvertedCurrentNoUnit(format string, wcc ...WC) Decorator {
+ return InvertedCurrent(0, format, wcc...)
+}
+
+// InvertedCurrentKibiByte is a wrapper around InvertedCurrent with predefined unit
+// UnitKiB (bytes/1024).
+func InvertedCurrentKibiByte(format string, wcc ...WC) Decorator {
+ return InvertedCurrent(UnitKiB, format, wcc...)
+}
+
+// InvertedCurrentKiloByte is a wrapper around InvertedCurrent with predefined unit
+// UnitKB (bytes/1000).
+func InvertedCurrentKiloByte(format string, wcc ...WC) Decorator {
+ return InvertedCurrent(UnitKB, format, wcc...)
+}
+
+// InvertedCurrent decorator with dynamic unit measure adjustment.
+//
+// `unit` one of [0|UnitKiB|UnitKB] zero for no unit
+//
+// `format` printf compatible verb for InvertedCurrent
+//
+// `wcc` optional WC config
+//
+// format example if unit=UnitKiB:
+//
+// format="%.1f" output: "12.0MiB"
+// format="% .1f" output: "12.0 MiB"
+// format="%d" output: "12MiB"
+// format="% d" output: "12 MiB"
+//
+func InvertedCurrent(unit int, format string, wcc ...WC) Decorator {
+ producer := func(unit int, format string) DecorFunc {
+ if format == "" {
+ format = "%d"
+ } else if strings.Count(format, "%") != 1 {
+ panic("expected format with exactly 1 verb")
+ }
+
+ switch unit {
+ case UnitKiB:
+ return func(s Statistics) string {
+ return fmt.Sprintf(format, SizeB1024(s.Total-s.Current))
+ }
+ case UnitKB:
+ return func(s Statistics) string {
+ return fmt.Sprintf(format, SizeB1000(s.Total-s.Current))
+ }
+ default:
+ return func(s Statistics) string {
+ return fmt.Sprintf(format, s.Total-s.Current)
+ }
+ }
+ }
+ return Any(producer(unit, format), wcc...)
+}
diff --git a/vendor/github.com/vbauerster/mpb/v7/decor/decorator.go b/vendor/github.com/vbauerster/mpb/v7/decor/decorator.go
new file mode 100644
index 000000000..e81fae367
--- /dev/null
+++ b/vendor/github.com/vbauerster/mpb/v7/decor/decorator.go
@@ -0,0 +1,191 @@
+package decor
+
+import (
+ "fmt"
+ "time"
+
+ "github.com/acarl005/stripansi"
+ "github.com/mattn/go-runewidth"
+)
+
+const (
+ // DidentRight bit specifies identation direction.
+ // |foo |b | With DidentRight
+ // | foo| b| Without DidentRight
+ DidentRight = 1 << iota
+
+ // DextraSpace bit adds extra space, makes sense with DSyncWidth only.
+ // When DidentRight bit set, the space will be added to the right,
+ // otherwise to the left.
+ DextraSpace
+
+ // DSyncWidth bit enables same column width synchronization.
+ // Effective with multiple bars only.
+ DSyncWidth
+
+ // DSyncWidthR is shortcut for DSyncWidth|DidentRight
+ DSyncWidthR = DSyncWidth | DidentRight
+
+ // DSyncSpace is shortcut for DSyncWidth|DextraSpace
+ DSyncSpace = DSyncWidth | DextraSpace
+
+ // DSyncSpaceR is shortcut for DSyncWidth|DextraSpace|DidentRight
+ DSyncSpaceR = DSyncWidth | DextraSpace | DidentRight
+)
+
+// TimeStyle enum.
+type TimeStyle int
+
+// TimeStyle kinds.
+const (
+ ET_STYLE_GO TimeStyle = iota
+ ET_STYLE_HHMMSS
+ ET_STYLE_HHMM
+ ET_STYLE_MMSS
+)
+
+// Statistics consists of progress related statistics, that Decorator
+// may need.
+type Statistics struct {
+ ID int
+ AvailableWidth int
+ Total int64
+ Current int64
+ Refill int64
+ Completed bool
+}
+
+// Decorator interface.
+// Most of the time there is no need to implement this interface
+// manually, as decor package already provides a wide range of decorators
+// which implement this interface. If however built-in decorators don't
+// meet your needs, you're free to implement your own one by implementing
+// this particular interface. The easy way to go is to convert a
+// `DecorFunc` into a `Decorator` interface by using provided
+// `func Any(DecorFunc, ...WC) Decorator`.
+type Decorator interface {
+ Configurator
+ Synchronizer
+ Decor(Statistics) string
+}
+
+// DecorFunc func type.
+// To be used with `func Any`(DecorFunc, ...WC) Decorator`.
+type DecorFunc func(Statistics) string
+
+// Synchronizer interface.
+// All decorators implement this interface implicitly. Its Sync
+// method exposes width sync channel, if DSyncWidth bit is set.
+type Synchronizer interface {
+ Sync() (chan int, bool)
+}
+
+// Configurator interface.
+type Configurator interface {
+ GetConf() WC
+ SetConf(WC)
+}
+
+// Wrapper interface.
+// If you're implementing custom Decorator by wrapping a built-in one,
+// it is necessary to implement this interface to retain functionality
+// of built-in Decorator.
+type Wrapper interface {
+ Base() Decorator
+}
+
+// EwmaDecorator interface.
+// EWMA based decorators should implement this one.
+type EwmaDecorator interface {
+ EwmaUpdate(int64, time.Duration)
+}
+
+// AverageDecorator interface.
+// Average decorators should implement this interface to provide start
+// time adjustment facility, for resume-able tasks.
+type AverageDecorator interface {
+ AverageAdjust(time.Time)
+}
+
+// ShutdownListener interface.
+// If decorator needs to be notified once upon bar shutdown event, so
+// this is the right interface to implement.
+type ShutdownListener interface {
+ Shutdown()
+}
+
+// Global convenience instances of WC with sync width bit set.
+// To be used with multiple bars only, i.e. not effective for single bar usage.
+var (
+ WCSyncWidth = WC{C: DSyncWidth}
+ WCSyncWidthR = WC{C: DSyncWidthR}
+ WCSyncSpace = WC{C: DSyncSpace}
+ WCSyncSpaceR = WC{C: DSyncSpaceR}
+)
+
+// WC is a struct with two public fields W and C, both of int type.
+// 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
+ fill func(s string, w int) 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 {
+ pureWidth := runewidth.StringWidth(msg)
+ stripWidth := runewidth.StringWidth(stripansi.Strip(msg))
+ maxCell := wc.W
+ if (wc.C & DSyncWidth) != 0 {
+ cellCount := stripWidth
+ if (wc.C & DextraSpace) != 0 {
+ cellCount++
+ }
+ wc.wsync <- cellCount
+ maxCell = <-wc.wsync
+ }
+ return wc.fill(msg, maxCell+(pureWidth-stripWidth))
+}
+
+// Init initializes width related config.
+func (wc *WC) Init() WC {
+ wc.fill = runewidth.FillLeft
+ if (wc.C & DidentRight) != 0 {
+ wc.fill = runewidth.FillRight
+ }
+ if (wc.C & DSyncWidth) != 0 {
+ // it's deliberate choice to override wsync on each Init() call,
+ // this way globals like WCSyncSpace can be reused
+ wc.wsync = make(chan int)
+ }
+ return *wc
+}
+
+// Sync is implementation of Synchronizer interface.
+func (wc *WC) Sync() (chan int, bool) {
+ if (wc.C&DSyncWidth) != 0 && wc.wsync == nil {
+ panic(fmt.Sprintf("%T is not initialized", wc))
+ }
+ return wc.wsync, (wc.C & DSyncWidth) != 0
+}
+
+// GetConf is implementation of Configurator interface.
+func (wc *WC) GetConf() WC {
+ return *wc
+}
+
+// SetConf is implementation of Configurator interface.
+func (wc *WC) SetConf(conf WC) {
+ *wc = conf.Init()
+}
+
+func initWC(wcc ...WC) WC {
+ var wc WC
+ for _, nwc := range wcc {
+ wc = nwc
+ }
+ return wc.Init()
+}
diff --git a/vendor/github.com/vbauerster/mpb/v7/decor/doc.go b/vendor/github.com/vbauerster/mpb/v7/decor/doc.go
new file mode 100644
index 000000000..4e4299307
--- /dev/null
+++ b/vendor/github.com/vbauerster/mpb/v7/decor/doc.go
@@ -0,0 +1,19 @@
+// Package decor provides common decorators for "github.com/vbauerster/mpb/v7" module.
+//
+// Some decorators returned by this package might have a closure state. It is ok to use
+// decorators concurrently, unless you share the same decorator among multiple
+// *mpb.Bar instances. To avoid data races, create new decorator per *mpb.Bar instance.
+//
+// Don't:
+//
+// p := mpb.New()
+// name := decor.Name("bar")
+// p.AddBar(100, mpb.AppendDecorators(name))
+// p.AddBar(100, mpb.AppendDecorators(name))
+//
+// Do:
+//
+// p := mpb.New()
+// p.AddBar(100, mpb.AppendDecorators(decor.Name("bar1")))
+// p.AddBar(100, mpb.AppendDecorators(decor.Name("bar2")))
+package decor
diff --git a/vendor/github.com/vbauerster/mpb/v7/decor/elapsed.go b/vendor/github.com/vbauerster/mpb/v7/decor/elapsed.go
new file mode 100644
index 000000000..e389f1581
--- /dev/null
+++ b/vendor/github.com/vbauerster/mpb/v7/decor/elapsed.go
@@ -0,0 +1,35 @@
+package decor
+
+import (
+ "time"
+)
+
+// Elapsed decorator. It's wrapper of NewElapsed.
+//
+// `style` one of [ET_STYLE_GO|ET_STYLE_HHMMSS|ET_STYLE_HHMM|ET_STYLE_MMSS]
+//
+// `wcc` optional WC config
+//
+func Elapsed(style TimeStyle, wcc ...WC) Decorator {
+ return NewElapsed(style, time.Now(), wcc...)
+}
+
+// NewElapsed returns elapsed time decorator.
+//
+// `style` one of [ET_STYLE_GO|ET_STYLE_HHMMSS|ET_STYLE_HHMM|ET_STYLE_MMSS]
+//
+// `startTime` start time
+//
+// `wcc` optional WC config
+//
+func NewElapsed(style TimeStyle, startTime time.Time, wcc ...WC) Decorator {
+ var msg string
+ producer := chooseTimeProducer(style)
+ fn := func(s Statistics) string {
+ if !s.Completed {
+ msg = producer(time.Since(startTime))
+ }
+ return msg
+ }
+ return Any(fn, wcc...)
+}
diff --git a/vendor/github.com/vbauerster/mpb/v7/decor/eta.go b/vendor/github.com/vbauerster/mpb/v7/decor/eta.go
new file mode 100644
index 000000000..d03caa735
--- /dev/null
+++ b/vendor/github.com/vbauerster/mpb/v7/decor/eta.go
@@ -0,0 +1,203 @@
+package decor
+
+import (
+ "fmt"
+ "math"
+ "time"
+
+ "github.com/VividCortex/ewma"
+)
+
+// TimeNormalizer interface. Implementors could be passed into
+// MovingAverageETA, in order to affect i.e. normalize its output.
+type TimeNormalizer interface {
+ Normalize(time.Duration) time.Duration
+}
+
+// TimeNormalizerFunc is function type adapter to convert function
+// into TimeNormalizer.
+type TimeNormalizerFunc func(time.Duration) time.Duration
+
+func (f TimeNormalizerFunc) Normalize(src time.Duration) time.Duration {
+ return f(src)
+}
+
+// EwmaETA exponential-weighted-moving-average based ETA decorator.
+// For this decorator to work correctly you have to measure each
+// iteration's duration and pass it to the
+// *Bar.DecoratorEwmaUpdate(time.Duration) method after each increment.
+func EwmaETA(style TimeStyle, age float64, wcc ...WC) Decorator {
+ var average ewma.MovingAverage
+ if age == 0 {
+ average = ewma.NewMovingAverage()
+ } else {
+ average = ewma.NewMovingAverage(age)
+ }
+ return MovingAverageETA(style, NewThreadSafeMovingAverage(average), nil, wcc...)
+}
+
+// MovingAverageETA decorator relies on MovingAverage implementation to calculate its average.
+//
+// `style` one of [ET_STYLE_GO|ET_STYLE_HHMMSS|ET_STYLE_HHMM|ET_STYLE_MMSS]
+//
+// `average` implementation of MovingAverage interface
+//
+// `normalizer` available implementations are [FixedIntervalTimeNormalizer|MaxTolerateTimeNormalizer]
+//
+// `wcc` optional WC config
+//
+func MovingAverageETA(style TimeStyle, average ewma.MovingAverage, normalizer TimeNormalizer, wcc ...WC) Decorator {
+ d := &movingAverageETA{
+ WC: initWC(wcc...),
+ average: average,
+ normalizer: normalizer,
+ producer: chooseTimeProducer(style),
+ }
+ return d
+}
+
+type movingAverageETA struct {
+ WC
+ average ewma.MovingAverage
+ normalizer TimeNormalizer
+ producer func(time.Duration) string
+}
+
+func (d *movingAverageETA) Decor(s Statistics) string {
+ v := math.Round(d.average.Value())
+ remaining := time.Duration((s.Total - s.Current) * int64(v))
+ if d.normalizer != nil {
+ remaining = d.normalizer.Normalize(remaining)
+ }
+ return d.FormatMsg(d.producer(remaining))
+}
+
+func (d *movingAverageETA) EwmaUpdate(n int64, dur time.Duration) {
+ durPerItem := float64(dur) / float64(n)
+ if math.IsInf(durPerItem, 0) || math.IsNaN(durPerItem) {
+ return
+ }
+ d.average.Add(durPerItem)
+}
+
+// AverageETA decorator. It's wrapper of NewAverageETA.
+//
+// `style` one of [ET_STYLE_GO|ET_STYLE_HHMMSS|ET_STYLE_HHMM|ET_STYLE_MMSS]
+//
+// `wcc` optional WC config
+//
+func AverageETA(style TimeStyle, wcc ...WC) Decorator {
+ return NewAverageETA(style, time.Now(), nil, wcc...)
+}
+
+// NewAverageETA decorator with user provided start time.
+//
+// `style` one of [ET_STYLE_GO|ET_STYLE_HHMMSS|ET_STYLE_HHMM|ET_STYLE_MMSS]
+//
+// `startTime` start time
+//
+// `normalizer` available implementations are [FixedIntervalTimeNormalizer|MaxTolerateTimeNormalizer]
+//
+// `wcc` optional WC config
+//
+func NewAverageETA(style TimeStyle, startTime time.Time, normalizer TimeNormalizer, wcc ...WC) Decorator {
+ d := &averageETA{
+ WC: initWC(wcc...),
+ startTime: startTime,
+ normalizer: normalizer,
+ producer: chooseTimeProducer(style),
+ }
+ return d
+}
+
+type averageETA struct {
+ WC
+ startTime time.Time
+ normalizer TimeNormalizer
+ producer func(time.Duration) string
+}
+
+func (d *averageETA) Decor(s Statistics) string {
+ var remaining time.Duration
+ if s.Current != 0 {
+ durPerItem := float64(time.Since(d.startTime)) / float64(s.Current)
+ durPerItem = math.Round(durPerItem)
+ remaining = time.Duration((s.Total - s.Current) * int64(durPerItem))
+ if d.normalizer != nil {
+ remaining = d.normalizer.Normalize(remaining)
+ }
+ }
+ return d.FormatMsg(d.producer(remaining))
+}
+
+func (d *averageETA) AverageAdjust(startTime time.Time) {
+ d.startTime = startTime
+}
+
+// MaxTolerateTimeNormalizer returns implementation of TimeNormalizer.
+func MaxTolerateTimeNormalizer(maxTolerate time.Duration) TimeNormalizer {
+ var normalized time.Duration
+ var lastCall time.Time
+ return TimeNormalizerFunc(func(remaining time.Duration) time.Duration {
+ if diff := normalized - remaining; diff <= 0 || diff > maxTolerate || remaining < time.Minute {
+ normalized = remaining
+ lastCall = time.Now()
+ return remaining
+ }
+ normalized -= time.Since(lastCall)
+ lastCall = time.Now()
+ return normalized
+ })
+}
+
+// FixedIntervalTimeNormalizer returns implementation of TimeNormalizer.
+func FixedIntervalTimeNormalizer(updInterval int) TimeNormalizer {
+ var normalized time.Duration
+ var lastCall time.Time
+ var count int
+ return TimeNormalizerFunc(func(remaining time.Duration) time.Duration {
+ if count == 0 || remaining < time.Minute {
+ count = updInterval
+ normalized = remaining
+ lastCall = time.Now()
+ return remaining
+ }
+ count--
+ normalized -= time.Since(lastCall)
+ lastCall = time.Now()
+ return normalized
+ })
+}
+
+func chooseTimeProducer(style TimeStyle) func(time.Duration) string {
+ switch style {
+ case ET_STYLE_HHMMSS:
+ return func(remaining time.Duration) string {
+ hours := int64(remaining/time.Hour) % 60
+ minutes := int64(remaining/time.Minute) % 60
+ seconds := int64(remaining/time.Second) % 60
+ return fmt.Sprintf("%02d:%02d:%02d", hours, minutes, seconds)
+ }
+ case ET_STYLE_HHMM:
+ return func(remaining time.Duration) string {
+ hours := int64(remaining/time.Hour) % 60
+ minutes := int64(remaining/time.Minute) % 60
+ return fmt.Sprintf("%02d:%02d", hours, minutes)
+ }
+ case ET_STYLE_MMSS:
+ return func(remaining time.Duration) string {
+ hours := int64(remaining/time.Hour) % 60
+ minutes := int64(remaining/time.Minute) % 60
+ seconds := int64(remaining/time.Second) % 60
+ if hours > 0 {
+ return fmt.Sprintf("%02d:%02d:%02d", hours, minutes, seconds)
+ }
+ return fmt.Sprintf("%02d:%02d", minutes, seconds)
+ }
+ default:
+ return func(remaining time.Duration) string {
+ // strip off nanoseconds
+ return ((remaining / time.Second) * time.Second).String()
+ }
+ }
+}
diff --git a/vendor/github.com/vbauerster/mpb/v7/decor/merge.go b/vendor/github.com/vbauerster/mpb/v7/decor/merge.go
new file mode 100644
index 000000000..e41406a64
--- /dev/null
+++ b/vendor/github.com/vbauerster/mpb/v7/decor/merge.go
@@ -0,0 +1,107 @@
+package decor
+
+import (
+ "strings"
+
+ "github.com/acarl005/stripansi"
+ "github.com/mattn/go-runewidth"
+)
+
+// Merge wraps its decorator argument with intention to sync width
+// with several decorators of another bar. Visual example:
+//
+// +----+--------+---------+--------+
+// | B1 | MERGE(D, P1, Pn) |
+// +----+--------+---------+--------+
+// | B2 | D0 | D1 | Dn |
+// +----+--------+---------+--------+
+//
+func Merge(decorator Decorator, placeholders ...WC) Decorator {
+ if _, ok := decorator.Sync(); !ok || len(placeholders) == 0 {
+ return decorator
+ }
+ md := &mergeDecorator{
+ Decorator: decorator,
+ wc: decorator.GetConf(),
+ placeHolders: make([]*placeHolderDecorator, len(placeholders)),
+ }
+ decorator.SetConf(WC{})
+ for i, wc := range placeholders {
+ if (wc.C & DSyncWidth) == 0 {
+ return decorator
+ }
+ md.placeHolders[i] = &placeHolderDecorator{wc.Init()}
+ }
+ return md
+}
+
+type mergeDecorator struct {
+ Decorator
+ wc WC
+ placeHolders []*placeHolderDecorator
+}
+
+func (d *mergeDecorator) GetConf() WC {
+ return d.wc
+}
+
+func (d *mergeDecorator) SetConf(conf WC) {
+ d.wc = conf.Init()
+}
+
+func (d *mergeDecorator) MergeUnwrap() []Decorator {
+ decorators := make([]Decorator, len(d.placeHolders))
+ for i, ph := range d.placeHolders {
+ decorators[i] = ph
+ }
+ return decorators
+}
+
+func (d *mergeDecorator) Sync() (chan int, bool) {
+ return d.wc.Sync()
+}
+
+func (d *mergeDecorator) Base() Decorator {
+ return d.Decorator
+}
+
+func (d *mergeDecorator) Decor(s Statistics) string {
+ msg := d.Decorator.Decor(s)
+ pureWidth := runewidth.StringWidth(msg)
+ stripWidth := runewidth.StringWidth(stripansi.Strip(msg))
+ cellCount := stripWidth
+ if (d.wc.C & DextraSpace) != 0 {
+ cellCount++
+ }
+
+ total := runewidth.StringWidth(d.placeHolders[0].FormatMsg(""))
+ pw := (cellCount - total) / len(d.placeHolders)
+ rem := (cellCount - total) % len(d.placeHolders)
+
+ 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 := runewidth.StringWidth(ph.FormatMsg(strings.Repeat(" ", width)))
+ total += max
+ diff = max - pw
+ }
+
+ d.wc.wsync <- pw + rem
+ max := <-d.wc.wsync
+ return d.wc.fill(msg, max+total+(pureWidth-stripWidth))
+}
+
+type placeHolderDecorator struct {
+ WC
+}
+
+func (d *placeHolderDecorator) Decor(Statistics) string {
+ return ""
+}
diff --git a/vendor/github.com/vbauerster/mpb/v7/decor/moving_average.go b/vendor/github.com/vbauerster/mpb/v7/decor/moving_average.go
new file mode 100644
index 000000000..50ac9c393
--- /dev/null
+++ b/vendor/github.com/vbauerster/mpb/v7/decor/moving_average.go
@@ -0,0 +1,68 @@
+package decor
+
+import (
+ "sort"
+ "sync"
+
+ "github.com/VividCortex/ewma"
+)
+
+type threadSafeMovingAverage struct {
+ ewma.MovingAverage
+ mu sync.Mutex
+}
+
+func (s *threadSafeMovingAverage) Add(value float64) {
+ s.mu.Lock()
+ s.MovingAverage.Add(value)
+ s.mu.Unlock()
+}
+
+func (s *threadSafeMovingAverage) Value() float64 {
+ s.mu.Lock()
+ defer s.mu.Unlock()
+ return s.MovingAverage.Value()
+}
+
+func (s *threadSafeMovingAverage) Set(value float64) {
+ s.mu.Lock()
+ s.MovingAverage.Set(value)
+ s.mu.Unlock()
+}
+
+// NewThreadSafeMovingAverage converts provided ewma.MovingAverage
+// into thread safe ewma.MovingAverage.
+func NewThreadSafeMovingAverage(average ewma.MovingAverage) ewma.MovingAverage {
+ if tsma, ok := average.(*threadSafeMovingAverage); ok {
+ return tsma
+ }
+ return &threadSafeMovingAverage{MovingAverage: average}
+}
+
+type medianWindow [3]float64
+
+func (s *medianWindow) Len() int { return len(s) }
+func (s *medianWindow) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
+func (s *medianWindow) Less(i, j int) bool { return s[i] < s[j] }
+
+func (s *medianWindow) Add(value float64) {
+ s[0], s[1] = s[1], s[2]
+ s[2] = value
+}
+
+func (s *medianWindow) Value() float64 {
+ tmp := *s
+ sort.Sort(&tmp)
+ return tmp[1]
+}
+
+func (s *medianWindow) Set(value float64) {
+ for i := 0; i < len(s); i++ {
+ s[i] = value
+ }
+}
+
+// NewMedian is fixed last 3 samples median MovingAverage.
+func NewMedian() ewma.MovingAverage {
+ return NewThreadSafeMovingAverage(new(medianWindow))
+}
diff --git a/vendor/github.com/vbauerster/mpb/v7/decor/name.go b/vendor/github.com/vbauerster/mpb/v7/decor/name.go
new file mode 100644
index 000000000..3af311254
--- /dev/null
+++ b/vendor/github.com/vbauerster/mpb/v7/decor/name.go
@@ -0,0 +1,12 @@
+package decor
+
+// Name decorator displays text that is set once and can't be changed
+// during decorator's lifetime.
+//
+// `str` string to display
+//
+// `wcc` optional WC config
+//
+func Name(str string, wcc ...WC) Decorator {
+ return Any(func(Statistics) string { return str }, wcc...)
+}
diff --git a/vendor/github.com/vbauerster/mpb/v7/decor/on_complete.go b/vendor/github.com/vbauerster/mpb/v7/decor/on_complete.go
new file mode 100644
index 000000000..f46b19aba
--- /dev/null
+++ b/vendor/github.com/vbauerster/mpb/v7/decor/on_complete.go
@@ -0,0 +1,37 @@
+package decor
+
+// OnComplete returns decorator, which wraps provided decorator, with
+// sole purpose to display provided message on complete event.
+//
+// `decorator` Decorator to wrap
+//
+// `message` message to display on complete event
+//
+func OnComplete(decorator Decorator, message string) Decorator {
+ d := &onCompleteWrapper{
+ Decorator: decorator,
+ msg: message,
+ }
+ if md, ok := decorator.(*mergeDecorator); ok {
+ d.Decorator, md.Decorator = md.Decorator, d
+ return md
+ }
+ return d
+}
+
+type onCompleteWrapper struct {
+ Decorator
+ msg string
+}
+
+func (d *onCompleteWrapper) Decor(s Statistics) string {
+ if s.Completed {
+ wc := d.GetConf()
+ return wc.FormatMsg(d.msg)
+ }
+ return d.Decorator.Decor(s)
+}
+
+func (d *onCompleteWrapper) Base() Decorator {
+ return d.Decorator
+}
diff --git a/vendor/github.com/vbauerster/mpb/v7/decor/percentage.go b/vendor/github.com/vbauerster/mpb/v7/decor/percentage.go
new file mode 100644
index 000000000..2b0a7a956
--- /dev/null
+++ b/vendor/github.com/vbauerster/mpb/v7/decor/percentage.go
@@ -0,0 +1,58 @@
+package decor
+
+import (
+ "fmt"
+ "io"
+ "strconv"
+
+ "github.com/vbauerster/mpb/v7/internal"
+)
+
+type percentageType float64
+
+func (s percentageType) Format(st fmt.State, verb rune) {
+ var prec int
+ switch verb {
+ case 'd':
+ case 's':
+ prec = -1
+ default:
+ if p, ok := st.Precision(); ok {
+ prec = p
+ } else {
+ prec = 6
+ }
+ }
+
+ io.WriteString(st, strconv.FormatFloat(float64(s), 'f', prec, 64))
+
+ if st.Flag(' ') {
+ io.WriteString(st, " ")
+ }
+ io.WriteString(st, "%")
+}
+
+// Percentage returns percentage decorator. It's a wrapper of NewPercentage.
+func Percentage(wcc ...WC) Decorator {
+ return NewPercentage("% d", wcc...)
+}
+
+// NewPercentage percentage decorator with custom format string.
+//
+// format examples:
+//
+// format="%.1f" output: "1.0%"
+// format="% .1f" output: "1.0 %"
+// format="%d" output: "1%"
+// format="% d" output: "1 %"
+//
+func NewPercentage(format string, wcc ...WC) Decorator {
+ if format == "" {
+ format = "% d"
+ }
+ f := func(s Statistics) string {
+ p := internal.Percentage(s.Total, s.Current, 100)
+ return fmt.Sprintf(format, percentageType(p))
+ }
+ return Any(f, wcc...)
+}
diff --git a/vendor/github.com/vbauerster/mpb/v7/decor/size_type.go b/vendor/github.com/vbauerster/mpb/v7/decor/size_type.go
new file mode 100644
index 000000000..e4b974058
--- /dev/null
+++ b/vendor/github.com/vbauerster/mpb/v7/decor/size_type.go
@@ -0,0 +1,109 @@
+package decor
+
+import (
+ "fmt"
+ "io"
+ "math"
+ "strconv"
+)
+
+//go:generate stringer -type=SizeB1024 -trimprefix=_i
+//go:generate stringer -type=SizeB1000 -trimprefix=_
+
+const (
+ _ib SizeB1024 = iota + 1
+ _iKiB SizeB1024 = 1 << (iota * 10)
+ _iMiB
+ _iGiB
+ _iTiB
+)
+
+// SizeB1024 named type, which implements fmt.Formatter interface. It
+// adjusts its value according to byte size multiple by 1024 and appends
+// appropriate size marker (KiB, MiB, GiB, TiB).
+type SizeB1024 int64
+
+func (self SizeB1024) Format(st fmt.State, verb rune) {
+ var prec int
+ switch verb {
+ case 'd':
+ case 's':
+ prec = -1
+ default:
+ if p, ok := st.Precision(); ok {
+ prec = p
+ } else {
+ prec = 6
+ }
+ }
+
+ var unit SizeB1024
+ switch {
+ case self < _iKiB:
+ unit = _ib
+ case self < _iMiB:
+ unit = _iKiB
+ case self < _iGiB:
+ unit = _iMiB
+ case self < _iTiB:
+ unit = _iGiB
+ case self <= math.MaxInt64:
+ unit = _iTiB
+ }
+
+ io.WriteString(st, strconv.FormatFloat(float64(self)/float64(unit), 'f', prec, 64))
+
+ if st.Flag(' ') {
+ io.WriteString(st, " ")
+ }
+ io.WriteString(st, unit.String())
+}
+
+const (
+ _b SizeB1000 = 1
+ _KB SizeB1000 = _b * 1000
+ _MB SizeB1000 = _KB * 1000
+ _GB SizeB1000 = _MB * 1000
+ _TB SizeB1000 = _GB * 1000
+)
+
+// SizeB1000 named type, which implements fmt.Formatter interface. It
+// adjusts its value according to byte size multiple by 1000 and appends
+// appropriate size marker (KB, MB, GB, TB).
+type SizeB1000 int64
+
+func (self SizeB1000) Format(st fmt.State, verb rune) {
+ var prec int
+ switch verb {
+ case 'd':
+ case 's':
+ prec = -1
+ default:
+ if p, ok := st.Precision(); ok {
+ prec = p
+ } else {
+ prec = 6
+ }
+ }
+
+ var unit SizeB1000
+ switch {
+ case self < _KB:
+ unit = _b
+ case self < _MB:
+ unit = _KB
+ case self < _GB:
+ unit = _MB
+ case self < _TB:
+ unit = _GB
+ case self <= math.MaxInt64:
+ unit = _TB
+ }
+
+ io.WriteString(st, strconv.FormatFloat(float64(self)/float64(unit), 'f', prec, 64))
+
+ if st.Flag(' ') {
+ io.WriteString(st, " ")
+ }
+ io.WriteString(st, unit.String())
+}
diff --git a/vendor/github.com/vbauerster/mpb/v7/decor/sizeb1000_string.go b/vendor/github.com/vbauerster/mpb/v7/decor/sizeb1000_string.go
new file mode 100644
index 000000000..3f32ef715
--- /dev/null
+++ b/vendor/github.com/vbauerster/mpb/v7/decor/sizeb1000_string.go
@@ -0,0 +1,41 @@
+// Code generated by "stringer -type=SizeB1000 -trimprefix=_"; DO NOT EDIT.
+
+package decor
+
+import "strconv"
+
+func _() {
+ // An "invalid array index" compiler error signifies that the constant values have changed.
+ // Re-run the stringer command to generate them again.
+ var x [1]struct{}
+ _ = x[_b-1]
+ _ = x[_KB-1000]
+ _ = x[_MB-1000000]
+ _ = x[_GB-1000000000]
+ _ = x[_TB-1000000000000]
+}
+
+const (
+ _SizeB1000_name_0 = "b"
+ _SizeB1000_name_1 = "KB"
+ _SizeB1000_name_2 = "MB"
+ _SizeB1000_name_3 = "GB"
+ _SizeB1000_name_4 = "TB"
+)
+
+func (i SizeB1000) String() string {
+ switch {
+ case i == 1:
+ return _SizeB1000_name_0
+ case i == 1000:
+ return _SizeB1000_name_1
+ case i == 1000000:
+ return _SizeB1000_name_2
+ case i == 1000000000:
+ return _SizeB1000_name_3
+ case i == 1000000000000:
+ return _SizeB1000_name_4
+ default:
+ return "SizeB1000(" + strconv.FormatInt(int64(i), 10) + ")"
+ }
+}
diff --git a/vendor/github.com/vbauerster/mpb/v7/decor/sizeb1024_string.go b/vendor/github.com/vbauerster/mpb/v7/decor/sizeb1024_string.go
new file mode 100644
index 000000000..9fca66cc7
--- /dev/null
+++ b/vendor/github.com/vbauerster/mpb/v7/decor/sizeb1024_string.go
@@ -0,0 +1,41 @@
+// Code generated by "stringer -type=SizeB1024 -trimprefix=_i"; DO NOT EDIT.
+
+package decor
+
+import "strconv"
+
+func _() {
+ // An "invalid array index" compiler error signifies that the constant values have changed.
+ // Re-run the stringer command to generate them again.
+ var x [1]struct{}
+ _ = x[_ib-1]
+ _ = x[_iKiB-1024]
+ _ = x[_iMiB-1048576]
+ _ = x[_iGiB-1073741824]
+ _ = x[_iTiB-1099511627776]
+}
+
+const (
+ _SizeB1024_name_0 = "b"
+ _SizeB1024_name_1 = "KiB"
+ _SizeB1024_name_2 = "MiB"
+ _SizeB1024_name_3 = "GiB"
+ _SizeB1024_name_4 = "TiB"
+)
+
+func (i SizeB1024) String() string {
+ switch {
+ case i == 1:
+ return _SizeB1024_name_0
+ case i == 1024:
+ return _SizeB1024_name_1
+ case i == 1048576:
+ return _SizeB1024_name_2
+ case i == 1073741824:
+ return _SizeB1024_name_3
+ case i == 1099511627776:
+ return _SizeB1024_name_4
+ default:
+ return "SizeB1024(" + strconv.FormatInt(int64(i), 10) + ")"
+ }
+}
diff --git a/vendor/github.com/vbauerster/mpb/v7/decor/speed.go b/vendor/github.com/vbauerster/mpb/v7/decor/speed.go
new file mode 100644
index 000000000..634edabfd
--- /dev/null
+++ b/vendor/github.com/vbauerster/mpb/v7/decor/speed.go
@@ -0,0 +1,171 @@
+package decor
+
+import (
+ "fmt"
+ "io"
+ "math"
+ "time"
+
+ "github.com/VividCortex/ewma"
+)
+
+// FmtAsSpeed adds "/s" to the end of the input formatter. To be
+// used with SizeB1000 or SizeB1024 types, for example:
+//
+// fmt.Printf("%.1f", FmtAsSpeed(SizeB1024(2048)))
+//
+func FmtAsSpeed(input fmt.Formatter) fmt.Formatter {
+ return &speedFormatter{input}
+}
+
+type speedFormatter struct {
+ fmt.Formatter
+}
+
+func (self *speedFormatter) Format(st fmt.State, verb rune) {
+ self.Formatter.Format(st, verb)
+ io.WriteString(st, "/s")
+}
+
+// EwmaSpeed exponential-weighted-moving-average based speed decorator.
+// For this decorator to work correctly you have to measure each
+// iteration's duration and pass it to the
+// *Bar.DecoratorEwmaUpdate(time.Duration) method after each increment.
+func EwmaSpeed(unit int, format string, age float64, wcc ...WC) Decorator {
+ var average ewma.MovingAverage
+ if age == 0 {
+ average = ewma.NewMovingAverage()
+ } else {
+ average = ewma.NewMovingAverage(age)
+ }
+ return MovingAverageSpeed(unit, format, NewThreadSafeMovingAverage(average), wcc...)
+}
+
+// MovingAverageSpeed decorator relies on MovingAverage implementation
+// to calculate its average.
+//
+// `unit` one of [0|UnitKiB|UnitKB] zero for no unit
+//
+// `format` printf compatible verb for value, like "%f" or "%d"
+//
+// `average` MovingAverage implementation
+//
+// `wcc` optional WC config
+//
+// format examples:
+//
+// unit=UnitKiB, format="%.1f" output: "1.0MiB/s"
+// unit=UnitKiB, format="% .1f" output: "1.0 MiB/s"
+// unit=UnitKB, format="%.1f" output: "1.0MB/s"
+// unit=UnitKB, format="% .1f" output: "1.0 MB/s"
+//
+func MovingAverageSpeed(unit int, format string, average ewma.MovingAverage, wcc ...WC) Decorator {
+ if format == "" {
+ format = "%.0f"
+ }
+ d := &movingAverageSpeed{
+ WC: initWC(wcc...),
+ average: average,
+ producer: chooseSpeedProducer(unit, format),
+ }
+ return d
+}
+
+type movingAverageSpeed struct {
+ WC
+ producer func(float64) string
+ average ewma.MovingAverage
+ msg string
+}
+
+func (d *movingAverageSpeed) Decor(s Statistics) string {
+ if !s.Completed {
+ var speed float64
+ if v := d.average.Value(); v > 0 {
+ speed = 1 / v
+ }
+ d.msg = d.producer(speed * 1e9)
+ }
+ return d.FormatMsg(d.msg)
+}
+
+func (d *movingAverageSpeed) EwmaUpdate(n int64, dur time.Duration) {
+ durPerByte := float64(dur) / float64(n)
+ if math.IsInf(durPerByte, 0) || math.IsNaN(durPerByte) {
+ return
+ }
+ d.average.Add(durPerByte)
+}
+
+// AverageSpeed decorator with dynamic unit measure adjustment. It's
+// a wrapper of NewAverageSpeed.
+func AverageSpeed(unit int, format string, wcc ...WC) Decorator {
+ return NewAverageSpeed(unit, format, time.Now(), wcc...)
+}
+
+// NewAverageSpeed decorator with dynamic unit measure adjustment and
+// user provided start time.
+//
+// `unit` one of [0|UnitKiB|UnitKB] zero for no unit
+//
+// `format` printf compatible verb for value, like "%f" or "%d"
+//
+// `startTime` start time
+//
+// `wcc` optional WC config
+//
+// format examples:
+//
+// unit=UnitKiB, format="%.1f" output: "1.0MiB/s"
+// unit=UnitKiB, format="% .1f" output: "1.0 MiB/s"
+// unit=UnitKB, format="%.1f" output: "1.0MB/s"
+// unit=UnitKB, format="% .1f" output: "1.0 MB/s"
+//
+func NewAverageSpeed(unit int, format string, startTime time.Time, wcc ...WC) Decorator {
+ if format == "" {
+ format = "%.0f"
+ }
+ d := &averageSpeed{
+ WC: initWC(wcc...),
+ startTime: startTime,
+ producer: chooseSpeedProducer(unit, format),
+ }
+ return d
+}
+
+type averageSpeed struct {
+ WC
+ startTime time.Time
+ producer func(float64) string
+ msg string
+}
+
+func (d *averageSpeed) Decor(s Statistics) string {
+ if !s.Completed {
+ speed := float64(s.Current) / float64(time.Since(d.startTime))
+ d.msg = d.producer(speed * 1e9)
+ }
+
+ return d.FormatMsg(d.msg)
+}
+
+func (d *averageSpeed) AverageAdjust(startTime time.Time) {
+ d.startTime = startTime
+}
+
+func chooseSpeedProducer(unit int, format string) func(float64) string {
+ switch unit {
+ case UnitKiB:
+ return func(speed float64) string {
+ return fmt.Sprintf(format, FmtAsSpeed(SizeB1024(math.Round(speed))))
+ }
+ case UnitKB:
+ return func(speed float64) string {
+ return fmt.Sprintf(format, FmtAsSpeed(SizeB1000(math.Round(speed))))
+ }
+ default:
+ return func(speed float64) string {
+ return fmt.Sprintf(format, speed)
+ }
+ }
+}
diff --git a/vendor/github.com/vbauerster/mpb/v7/decor/spinner.go b/vendor/github.com/vbauerster/mpb/v7/decor/spinner.go
new file mode 100644
index 000000000..6871639db
--- /dev/null
+++ b/vendor/github.com/vbauerster/mpb/v7/decor/spinner.go
@@ -0,0 +1,21 @@
+package decor
+
+var defaultSpinnerStyle = []string{"⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"}
+
+// Spinner returns spinner decorator.
+//
+// `frames` spinner frames, if nil or len==0, default is used
+//
+// `wcc` optional WC config
+func Spinner(frames []string, wcc ...WC) Decorator {
+ if len(frames) == 0 {
+ frames = defaultSpinnerStyle
+ }
+ var count uint
+ f := func(s Statistics) string {
+ frame := frames[count%uint(len(frames))]
+ count++
+ return frame
+ }
+ return Any(f, wcc...)
+}
diff --git a/vendor/github.com/vbauerster/mpb/v7/doc.go b/vendor/github.com/vbauerster/mpb/v7/doc.go
new file mode 100644
index 000000000..5ada71774
--- /dev/null
+++ b/vendor/github.com/vbauerster/mpb/v7/doc.go
@@ -0,0 +1,2 @@
+// Package mpb is a library for rendering progress bars in terminal applications.
+package mpb
diff --git a/vendor/github.com/vbauerster/mpb/v7/go.mod b/vendor/github.com/vbauerster/mpb/v7/go.mod
new file mode 100644
index 000000000..ea22e1eda
--- /dev/null
+++ b/vendor/github.com/vbauerster/mpb/v7/go.mod
@@ -0,0 +1,10 @@
+module github.com/vbauerster/mpb/v7
+
+require (
+ github.com/VividCortex/ewma v1.2.0
+ github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d
+ github.com/mattn/go-runewidth v0.0.13
+ golang.org/x/sys v0.0.0-20210603125802-9665404d3644
+)
+
+go 1.14
diff --git a/vendor/github.com/vbauerster/mpb/v7/go.sum b/vendor/github.com/vbauerster/mpb/v7/go.sum
new file mode 100644
index 000000000..0b609b223
--- /dev/null
+++ b/vendor/github.com/vbauerster/mpb/v7/go.sum
@@ -0,0 +1,10 @@
+github.com/VividCortex/ewma v1.2.0 h1:f58SaIzcDXrSy3kWaHNvuJgJ3Nmz59Zji6XoJR/q1ow=
+github.com/VividCortex/ewma v1.2.0/go.mod h1:nz4BbCtbLyFDeC9SUHbtcT5644juEuWfUAUnGx7j5l4=
+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/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU=
+github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
+github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
+github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
+golang.org/x/sys v0.0.0-20210603125802-9665404d3644 h1:CA1DEQ4NdKphKeL70tvsWNdT5oFh1lOjihRcEDROi0I=
+golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
diff --git a/vendor/github.com/vbauerster/mpb/v7/internal/percentage.go b/vendor/github.com/vbauerster/mpb/v7/internal/percentage.go
new file mode 100644
index 000000000..a8ef8be12
--- /dev/null
+++ b/vendor/github.com/vbauerster/mpb/v7/internal/percentage.go
@@ -0,0 +1,19 @@
+package internal
+
+import "math"
+
+// Percentage is a helper function, to calculate percentage.
+func Percentage(total, current int64, width int) float64 {
+ if total <= 0 {
+ return 0
+ }
+ if current >= total {
+ return float64(width)
+ }
+ return float64(int64(width)*current) / float64(total)
+}
+
+// PercentageRound same as Percentage but with math.Round.
+func PercentageRound(total, current int64, width int) float64 {
+ return math.Round(Percentage(total, current, width))
+}
diff --git a/vendor/github.com/vbauerster/mpb/v7/internal/predicate.go b/vendor/github.com/vbauerster/mpb/v7/internal/predicate.go
new file mode 100644
index 000000000..1e4dd24d9
--- /dev/null
+++ b/vendor/github.com/vbauerster/mpb/v7/internal/predicate.go
@@ -0,0 +1,6 @@
+package internal
+
+// Predicate helper for internal use.
+func Predicate(pick bool) func() bool {
+ return func() bool { return pick }
+}
diff --git a/vendor/github.com/vbauerster/mpb/v7/internal/width.go b/vendor/github.com/vbauerster/mpb/v7/internal/width.go
new file mode 100644
index 000000000..7677e404a
--- /dev/null
+++ b/vendor/github.com/vbauerster/mpb/v7/internal/width.go
@@ -0,0 +1,10 @@
+package internal
+
+// CheckRequestedWidth checks that requested width doesn't overflow
+// available width
+func CheckRequestedWidth(requested, available int) int {
+ if requested < 1 || requested >= available {
+ return available
+ }
+ return requested
+}
diff --git a/vendor/github.com/vbauerster/mpb/v7/priority_queue.go b/vendor/github.com/vbauerster/mpb/v7/priority_queue.go
new file mode 100644
index 000000000..29d9bd5a8
--- /dev/null
+++ b/vendor/github.com/vbauerster/mpb/v7/priority_queue.go
@@ -0,0 +1,32 @@
+package mpb
+
+// A priorityQueue implements heap.Interface
+type priorityQueue []*Bar
+
+func (pq priorityQueue) Len() int { return len(pq) }
+
+func (pq priorityQueue) Less(i, j int) bool {
+ return pq[i].priority < pq[j].priority
+}
+
+func (pq priorityQueue) Swap(i, j int) {
+ pq[i], pq[j] = pq[j], pq[i]
+ pq[i].index = i
+ pq[j].index = j
+}
+
+func (pq *priorityQueue) Push(x interface{}) {
+ s := *pq
+ bar := x.(*Bar)
+ bar.index = len(s)
+ s = append(s, bar)
+ *pq = s
+}
+
+func (pq *priorityQueue) Pop() interface{} {
+ s := *pq
+ *pq = s[0 : len(s)-1]
+ bar := s[len(s)-1]
+ bar.index = -1 // for safety
+ return bar
+}
diff --git a/vendor/github.com/vbauerster/mpb/v7/progress.go b/vendor/github.com/vbauerster/mpb/v7/progress.go
new file mode 100644
index 000000000..b2017f3f0
--- /dev/null
+++ b/vendor/github.com/vbauerster/mpb/v7/progress.go
@@ -0,0 +1,412 @@
+package mpb
+
+import (
+ "bytes"
+ "container/heap"
+ "context"
+ "fmt"
+ "io"
+ "io/ioutil"
+ "log"
+ "math"
+ "os"
+ "sync"
+ "time"
+
+ "github.com/vbauerster/mpb/v7/cwriter"
+ "github.com/vbauerster/mpb/v7/decor"
+)
+
+const (
+ // default RefreshRate
+ prr = 120 * time.Millisecond
+)
+
+// Progress represents a container that renders one or more progress
+// bars.
+type Progress struct {
+ ctx context.Context
+ uwg *sync.WaitGroup
+ cwg *sync.WaitGroup
+ bwg *sync.WaitGroup
+ operateState chan func(*pState)
+ done chan struct{}
+ refreshCh chan time.Time
+ once sync.Once
+ dlogger *log.Logger
+}
+
+// pState holds bars in its priorityQueue. It gets passed to
+// *Progress.serve(...) monitor goroutine.
+type pState struct {
+ bHeap priorityQueue
+ heapUpdated bool
+ pMatrix map[int][]chan int
+ aMatrix map[int][]chan int
+ barShutdownQueue []*Bar
+
+ // following are provided/overrided by user
+ idCount int
+ reqWidth int
+ popCompleted bool
+ outputDiscarded bool
+ rr time.Duration
+ uwg *sync.WaitGroup
+ externalRefresh <-chan interface{}
+ renderDelay <-chan struct{}
+ shutdownNotifier chan struct{}
+ parkedBars map[*Bar]*Bar
+ output io.Writer
+ debugOut io.Writer
+}
+
+// New creates new Progress container instance. It's not possible to
+// reuse instance after *Progress.Wait() method has been called.
+func New(options ...ContainerOption) *Progress {
+ return NewWithContext(context.Background(), options...)
+}
+
+// NewWithContext creates new Progress container instance with provided
+// context. It's not possible to reuse instance after *Progress.Wait()
+// method has been called.
+func NewWithContext(ctx context.Context, options ...ContainerOption) *Progress {
+ s := &pState{
+ bHeap: priorityQueue{},
+ rr: prr,
+ parkedBars: make(map[*Bar]*Bar),
+ output: os.Stdout,
+ debugOut: ioutil.Discard,
+ }
+
+ for _, opt := range options {
+ if opt != nil {
+ opt(s)
+ }
+ }
+
+ p := &Progress{
+ ctx: ctx,
+ uwg: s.uwg,
+ cwg: new(sync.WaitGroup),
+ bwg: new(sync.WaitGroup),
+ operateState: make(chan func(*pState)),
+ done: make(chan struct{}),
+ dlogger: log.New(s.debugOut, "[mpb] ", log.Lshortfile),
+ }
+
+ p.cwg.Add(1)
+ go p.serve(s, cwriter.New(s.output))
+ return p
+}
+
+// AddBar creates a bar with default bar filler. Different filler can
+// be chosen and applied via `*Progress.Add(...) *Bar` method.
+func (p *Progress) AddBar(total int64, options ...BarOption) *Bar {
+ return p.Add(total, NewBarFiller(BarStyle()), options...)
+}
+
+// AddSpinner creates a bar with default spinner filler. Different
+// filler can be chosen and applied via `*Progress.Add(...) *Bar`
+// method.
+func (p *Progress) AddSpinner(total int64, options ...BarOption) *Bar {
+ return p.Add(total, NewBarFiller(SpinnerStyle()), options...)
+}
+
+// Add creates a bar which renders itself by provided filler.
+// If `total <= 0` trigger complete event is disabled until reset with *bar.SetTotal(int64, bool).
+// Panics if *Progress instance is done, i.e. called after *Progress.Wait().
+func (p *Progress) Add(total int64, filler BarFiller, options ...BarOption) *Bar {
+ if filler == nil {
+ filler = BarFillerFunc(func(io.Writer, int, decor.Statistics) {})
+ }
+ p.bwg.Add(1)
+ result := make(chan *Bar)
+ select {
+ case p.operateState <- func(ps *pState) {
+ bs := ps.makeBarState(total, filler, options...)
+ bar := newBar(p, bs)
+ if bs.runningBar != nil {
+ bs.runningBar.noPop = true
+ ps.parkedBars[bs.runningBar] = bar
+ } else {
+ heap.Push(&ps.bHeap, bar)
+ ps.heapUpdated = true
+ }
+ ps.idCount++
+ result <- bar
+ }:
+ bar := <-result
+ bar.subscribeDecorators()
+ return bar
+ case <-p.done:
+ p.bwg.Done()
+ panic(fmt.Sprintf("%T instance can't be reused after it's done!", p))
+ }
+}
+
+func (p *Progress) dropBar(b *Bar) {
+ select {
+ case p.operateState <- func(s *pState) {
+ if b.index < 0 {
+ return
+ }
+ heap.Remove(&s.bHeap, b.index)
+ s.heapUpdated = true
+ }:
+ case <-p.done:
+ }
+}
+
+func (p *Progress) setBarPriority(b *Bar, priority int) {
+ select {
+ case p.operateState <- func(s *pState) {
+ if b.index < 0 {
+ return
+ }
+ b.priority = priority
+ heap.Fix(&s.bHeap, b.index)
+ }:
+ case <-p.done:
+ }
+}
+
+// UpdateBarPriority same as *Bar.SetPriority(int).
+func (p *Progress) UpdateBarPriority(b *Bar, priority int) {
+ p.setBarPriority(b, priority)
+}
+
+// BarCount returns bars count.
+func (p *Progress) BarCount() int {
+ result := make(chan int, 1)
+ select {
+ case p.operateState <- func(s *pState) { result <- s.bHeap.Len() }:
+ return <-result
+ case <-p.done:
+ return 0
+ }
+}
+
+// Wait waits for all bars to complete and finally shutdowns container.
+// After this method has been called, there is no way to reuse *Progress
+// instance.
+func (p *Progress) Wait() {
+ if p.uwg != nil {
+ // wait for user wg
+ p.uwg.Wait()
+ }
+
+ // wait for bars to quit, if any
+ p.bwg.Wait()
+
+ p.once.Do(p.shutdown)
+
+ // wait for container to quit
+ p.cwg.Wait()
+}
+
+func (p *Progress) shutdown() {
+ close(p.done)
+}
+
+func (p *Progress) serve(s *pState, cw *cwriter.Writer) {
+ defer p.cwg.Done()
+
+ p.refreshCh = s.newTicker(p.done)
+
+ for {
+ select {
+ case op := <-p.operateState:
+ op(s)
+ case <-p.refreshCh:
+ if err := s.render(cw); err != nil {
+ p.dlogger.Println(err)
+ }
+ case <-s.shutdownNotifier:
+ if s.heapUpdated {
+ if err := s.render(cw); err != nil {
+ p.dlogger.Println(err)
+ }
+ }
+ return
+ }
+ }
+}
+
+func (s *pState) newTicker(done <-chan struct{}) chan time.Time {
+ ch := make(chan time.Time)
+ if s.shutdownNotifier == nil {
+ s.shutdownNotifier = make(chan struct{})
+ }
+ go func() {
+ if s.renderDelay != nil {
+ <-s.renderDelay
+ }
+ var internalRefresh <-chan time.Time
+ if !s.outputDiscarded {
+ if s.externalRefresh == nil {
+ ticker := time.NewTicker(s.rr)
+ defer ticker.Stop()
+ internalRefresh = ticker.C
+ }
+ } else {
+ s.externalRefresh = nil
+ }
+ for {
+ select {
+ case t := <-internalRefresh:
+ ch <- t
+ case x := <-s.externalRefresh:
+ if t, ok := x.(time.Time); ok {
+ ch <- t
+ } else {
+ ch <- time.Now()
+ }
+ case <-done:
+ close(s.shutdownNotifier)
+ return
+ }
+ }
+ }()
+ return ch
+}
+
+func (s *pState) render(cw *cwriter.Writer) error {
+ if s.heapUpdated {
+ s.updateSyncMatrix()
+ s.heapUpdated = false
+ }
+ syncWidth(s.pMatrix)
+ syncWidth(s.aMatrix)
+
+ tw, err := cw.GetWidth()
+ if err != nil {
+ tw = s.reqWidth
+ }
+ for i := 0; i < s.bHeap.Len(); i++ {
+ bar := s.bHeap[i]
+ go bar.render(tw)
+ }
+
+ return s.flush(cw)
+}
+
+func (s *pState) flush(cw *cwriter.Writer) error {
+ var lineCount int
+ bm := make(map[*Bar]struct{}, s.bHeap.Len())
+ for s.bHeap.Len() > 0 {
+ b := heap.Pop(&s.bHeap).(*Bar)
+ cw.ReadFrom(<-b.frameCh)
+ if b.toShutdown {
+ if b.recoveredPanic != nil {
+ s.barShutdownQueue = append(s.barShutdownQueue, b)
+ b.toShutdown = false
+ } else {
+ // shutdown at next flush
+ // this ensures no bar ends up with less than 100% rendered
+ defer func() {
+ s.barShutdownQueue = append(s.barShutdownQueue, b)
+ }()
+ }
+ }
+ lineCount += b.extendedLines + 1
+ bm[b] = struct{}{}
+ }
+
+ for _, b := range s.barShutdownQueue {
+ if parkedBar := s.parkedBars[b]; parkedBar != nil {
+ parkedBar.priority = b.priority
+ heap.Push(&s.bHeap, parkedBar)
+ delete(s.parkedBars, b)
+ b.toDrop = true
+ }
+ if s.popCompleted && !b.noPop {
+ lineCount -= b.extendedLines + 1
+ b.toDrop = true
+ }
+ if b.toDrop {
+ delete(bm, b)
+ s.heapUpdated = true
+ }
+ b.cancel()
+ }
+ s.barShutdownQueue = s.barShutdownQueue[0:0]
+
+ for b := range bm {
+ heap.Push(&s.bHeap, b)
+ }
+
+ return cw.Flush(lineCount)
+}
+
+func (s *pState) updateSyncMatrix() {
+ s.pMatrix = make(map[int][]chan int)
+ s.aMatrix = make(map[int][]chan int)
+ for i := 0; i < s.bHeap.Len(); i++ {
+ bar := s.bHeap[i]
+ table := bar.wSyncTable()
+ pRow, aRow := table[0], table[1]
+
+ for i, ch := range pRow {
+ s.pMatrix[i] = append(s.pMatrix[i], ch)
+ }
+
+ for i, ch := range aRow {
+ s.aMatrix[i] = append(s.aMatrix[i], ch)
+ }
+ }
+}
+
+func (s *pState) makeBarState(total int64, filler BarFiller, options ...BarOption) *bState {
+ bs := &bState{
+ id: s.idCount,
+ priority: s.idCount,
+ reqWidth: s.reqWidth,
+ total: total,
+ filler: filler,
+ extender: func(r io.Reader, _ int, _ decor.Statistics) (io.Reader, int) { return r, 0 },
+ debugOut: s.debugOut,
+ }
+
+ if total > 0 {
+ bs.triggerComplete = true
+ }
+
+ for _, opt := range options {
+ if opt != nil {
+ opt(bs)
+ }
+ }
+
+ if bs.middleware != nil {
+ bs.filler = bs.middleware(filler)
+ bs.middleware = nil
+ }
+
+ if s.popCompleted && !bs.noPop {
+ bs.priority = -(math.MaxInt32 - s.idCount)
+ }
+
+ bs.bufP = bytes.NewBuffer(make([]byte, 0, 128))
+ bs.bufB = bytes.NewBuffer(make([]byte, 0, 256))
+ bs.bufA = bytes.NewBuffer(make([]byte, 0, 128))
+
+ return bs
+}
+
+func syncWidth(matrix map[int][]chan int) {
+ for _, column := range matrix {
+ go maxWidthDistributor(column)
+ }
+}
+
+var maxWidthDistributor = func(column []chan int) {
+ var maxWidth int
+ for _, ch := range column {
+ if w := <-ch; w > maxWidth {
+ maxWidth = w
+ }
+ }
+ for _, ch := range column {
+ ch <- maxWidth
+ }
+}
diff --git a/vendor/github.com/vbauerster/mpb/v7/proxyreader.go b/vendor/github.com/vbauerster/mpb/v7/proxyreader.go
new file mode 100644
index 000000000..316f438d7
--- /dev/null
+++ b/vendor/github.com/vbauerster/mpb/v7/proxyreader.go
@@ -0,0 +1,90 @@
+package mpb
+
+import (
+ "io"
+ "io/ioutil"
+ "time"
+)
+
+type proxyReader struct {
+ io.ReadCloser
+ bar *Bar
+}
+
+func (x *proxyReader) Read(p []byte) (int, error) {
+ n, err := x.ReadCloser.Read(p)
+ x.bar.IncrBy(n)
+ if err == io.EOF {
+ go x.bar.SetTotal(0, true)
+ }
+ return n, err
+}
+
+type proxyWriterTo struct {
+ io.ReadCloser // *proxyReader
+ wt io.WriterTo
+ bar *Bar
+}
+
+func (x *proxyWriterTo) WriteTo(w io.Writer) (int64, error) {
+ n, err := x.wt.WriteTo(w)
+ x.bar.IncrInt64(n)
+ if err == io.EOF {
+ go x.bar.SetTotal(0, true)
+ }
+ return n, err
+}
+
+type ewmaProxyReader struct {
+ io.ReadCloser // *proxyReader
+ bar *Bar
+ iT time.Time
+}
+
+func (x *ewmaProxyReader) Read(p []byte) (int, error) {
+ n, err := x.ReadCloser.Read(p)
+ if n > 0 {
+ x.bar.DecoratorEwmaUpdate(time.Since(x.iT))
+ x.iT = time.Now()
+ }
+ return n, err
+}
+
+type ewmaProxyWriterTo struct {
+ io.ReadCloser // *ewmaProxyReader
+ wt io.WriterTo // *proxyWriterTo
+ bar *Bar
+ iT time.Time
+}
+
+func (x *ewmaProxyWriterTo) WriteTo(w io.Writer) (int64, error) {
+ n, err := x.wt.WriteTo(w)
+ if n > 0 {
+ x.bar.DecoratorEwmaUpdate(time.Since(x.iT))
+ x.iT = time.Now()
+ }
+ return n, err
+}
+
+func newProxyReader(r io.Reader, bar *Bar) io.ReadCloser {
+ rc := toReadCloser(r)
+ rc = &proxyReader{rc, bar}
+
+ if wt, isWriterTo := r.(io.WriterTo); bar.hasEwmaDecorators {
+ now := time.Now()
+ rc = &ewmaProxyReader{rc, bar, now}
+ if isWriterTo {
+ rc = &ewmaProxyWriterTo{rc, wt, bar, now}
+ }
+ } else if isWriterTo {
+ rc = &proxyWriterTo{rc, wt, bar}
+ }
+ return rc
+}
+
+func toReadCloser(r io.Reader) io.ReadCloser {
+ if rc, ok := r.(io.ReadCloser); ok {
+ return rc
+ }
+ return ioutil.NopCloser(r)
+}