summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.cirrus.yml18
-rw-r--r--Makefile5
-rw-r--r--cmd/podman/generate/systemd.go71
-rw-r--r--cmd/podman/system/df.go8
-rw-r--r--contrib/podmanimage/README.md5
-rw-r--r--docs/source/markdown/podman-generate-systemd.1.md6
-rw-r--r--go.mod4
-rw-r--r--go.sum7
-rw-r--r--libpod/image/image.go13
-rw-r--r--libpod/image/layer_tree.go4
-rw-r--r--pkg/api/handlers/libpod/generate.go45
-rw-r--r--pkg/api/server/register_generate.go62
-rw-r--r--pkg/bindings/generate/generate.go27
-rw-r--r--pkg/domain/entities/generate.go7
-rw-r--r--pkg/domain/entities/system.go7
-rw-r--r--pkg/domain/infra/abi/containers.go6
-rw-r--r--pkg/domain/infra/abi/generate.go8
-rw-r--r--pkg/domain/infra/abi/system.go11
-rw-r--r--pkg/domain/infra/tunnel/generate.go3
-rw-r--r--pkg/specgen/generate/security.go2
-rw-r--r--pkg/systemd/generate/containers.go30
-rw-r--r--pkg/systemd/generate/containers_test.go27
-rw-r--r--pkg/systemd/generate/pods.go49
-rw-r--r--pkg/systemd/generate/pods_test.go9
-rw-r--r--test/e2e/generate_systemd_test.go15
-rw-r--r--test/e2e/run_apparmor_test.go13
-rw-r--r--test/system/helpers.bash2
-rw-r--r--troubleshooting.md25
-rw-r--r--vendor/github.com/containers/storage/VERSION2
-rw-r--r--vendor/github.com/containers/storage/go.mod3
-rw-r--r--vendor/github.com/containers/storage/go.sum4
-rw-r--r--vendor/github.com/containers/storage/layers.go2
-rw-r--r--vendor/github.com/containers/storage/pkg/mount/mount.go29
-rw-r--r--vendor/github.com/containers/storage/pkg/mount/mountinfo.go49
-rw-r--r--vendor/github.com/containers/storage/pkg/mount/mountinfo_linux.go119
-rw-r--r--vendor/github.com/containers/storage/pkg/mount/mountinfo_unsupported.go12
-rw-r--r--vendor/github.com/klauspost/pgzip/.travis.yml17
-rw-r--r--vendor/github.com/klauspost/pgzip/gunzip.go11
-rw-r--r--vendor/github.com/moby/sys/mountinfo/LICENSE202
-rw-r--r--vendor/github.com/moby/sys/mountinfo/go.mod3
-rw-r--r--vendor/github.com/moby/sys/mountinfo/mountinfo.go67
-rw-r--r--vendor/github.com/moby/sys/mountinfo/mountinfo_filters.go58
-rw-r--r--vendor/github.com/moby/sys/mountinfo/mountinfo_freebsd.go (renamed from vendor/github.com/containers/storage/pkg/mount/mountinfo_freebsd.go)22
-rw-r--r--vendor/github.com/moby/sys/mountinfo/mountinfo_linux.go152
-rw-r--r--vendor/github.com/moby/sys/mountinfo/mountinfo_unsupported.go17
-rw-r--r--vendor/github.com/moby/sys/mountinfo/mountinfo_windows.go12
-rw-r--r--vendor/github.com/onsi/ginkgo/CHANGELOG.md5
-rw-r--r--vendor/github.com/onsi/ginkgo/README.md5
-rw-r--r--vendor/github.com/onsi/ginkgo/config/config.go2
-rw-r--r--vendor/github.com/onsi/ginkgo/ginkgo/nodot/nodot.go4
-rw-r--r--vendor/modules.txt8
51 files changed, 972 insertions, 322 deletions
diff --git a/.cirrus.yml b/.cirrus.yml
index 06ed7c5e0..67c212c15 100644
--- a/.cirrus.yml
+++ b/.cirrus.yml
@@ -154,7 +154,7 @@ container_image_build_task:
depends_on:
- "gating"
- # Only run for PRs, quay.io will automatically build after bramch-push
+ # Only run for PRs, quay.io will automatically build after branch-push
only_if: $CIRRUS_BRANCH != $DEST_BRANCH
matrix:
@@ -736,6 +736,7 @@ success_task:
- "verify_test_built_images"
- "docs"
- "static_build"
+ - "darwin_build"
env:
CIRRUS_WORKING_DIR: "/usr/src/libpod"
@@ -784,3 +785,18 @@ static_build_task:
binaries_artifacts:
path: "result/bin/podman"
+
+
+darwin_build_task:
+ depends_on:
+ - "gating"
+ osx_instance:
+ image: catalina-base
+ setup-script:
+ - brew install go
+ - brew install go-md2man
+ build-script:
+ - make podman-remote-darwin
+ - make install-podman-remote-darwin-docs
+ binaries_artifacts:
+ path: "bin/podman-remote-darwin"
diff --git a/Makefile b/Makefile
index 8ce1946ee..07ff21445 100644
--- a/Makefile
+++ b/Makefile
@@ -106,7 +106,10 @@ GOMD2MAN ?= $(shell command -v go-md2man || echo '$(GOBIN)/go-md2man')
CROSS_BUILD_TARGETS := \
bin/podman.cross.linux.amd64 \
bin/podman.cross.linux.ppc64le \
- bin/podman.cross.linux.arm
+ bin/podman.cross.linux.arm \
+ bin/podman.cross.linux.arm64 \
+ bin/podman.cross.linux.386 \
+ bin/podman.cross.linux.s390x
.PHONY: all
all: binaries docs
diff --git a/cmd/podman/generate/systemd.go b/cmd/podman/generate/systemd.go
index 851a104bc..f690836a4 100644
--- a/cmd/podman/generate/systemd.go
+++ b/cmd/podman/generate/systemd.go
@@ -1,15 +1,22 @@
package pods
import (
+ "encoding/json"
"fmt"
+ "os"
+ "path/filepath"
"github.com/containers/podman/v2/cmd/podman/registry"
"github.com/containers/podman/v2/cmd/podman/utils"
"github.com/containers/podman/v2/pkg/domain/entities"
+ "github.com/pkg/errors"
+ "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
)
var (
+ files bool
+ format string
systemdTimeout uint
systemdOptions = entities.GenerateSystemdOptions{}
systemdDescription = `Generate systemd units for a pod or container.
@@ -29,19 +36,20 @@ var (
func init() {
registry.Commands = append(registry.Commands, registry.CliCommand{
- Mode: []entities.EngineMode{entities.ABIMode},
+ Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode},
Command: systemdCmd,
Parent: generateCmd,
})
flags := systemdCmd.Flags()
flags.BoolVarP(&systemdOptions.Name, "name", "n", false, "Use container/pod names instead of IDs")
- flags.BoolVarP(&systemdOptions.Files, "files", "f", false, "Generate .service files instead of printing to stdout")
+ flags.BoolVarP(&files, "files", "f", false, "Generate .service files instead of printing to stdout")
flags.UintVarP(&systemdTimeout, "time", "t", containerConfig.Engine.StopTimeout, "Stop timeout override")
flags.StringVar(&systemdOptions.RestartPolicy, "restart-policy", "on-failure", "Systemd restart-policy")
flags.BoolVarP(&systemdOptions.New, "new", "", false, "Create a new container instead of starting an existing one")
flags.StringVar(&systemdOptions.ContainerPrefix, "container-prefix", "container", "Systemd unit name prefix for containers")
flags.StringVar(&systemdOptions.PodPrefix, "pod-prefix", "pod", "Systemd unit name prefix for pods")
flags.StringVar(&systemdOptions.Separator, "separator", "-", "Systemd unit name separator between name/id and prefix")
+ flags.StringVar(&format, "format", "", "Print the created units in specified format (json)")
flags.SetNormalizeFunc(utils.AliasFlags)
}
@@ -50,11 +58,68 @@ func systemd(cmd *cobra.Command, args []string) error {
systemdOptions.StopTimeout = &systemdTimeout
}
+ if registry.IsRemote() {
+ logrus.Warnln("The generated units should be placed on your remote system")
+ }
+
report, err := registry.ContainerEngine().GenerateSystemd(registry.GetContext(), args[0], systemdOptions)
if err != nil {
return err
}
- fmt.Println(report.Output)
+ if files {
+ cwd, err := os.Getwd()
+ if err != nil {
+ return errors.Wrap(err, "error getting current working directory")
+ }
+ for name, content := range report.Units {
+ path := filepath.Join(cwd, fmt.Sprintf("%s.service", name))
+ f, err := os.Create(path)
+ if err != nil {
+ return err
+ }
+ _, err = f.WriteString(content)
+ if err != nil {
+ return err
+ }
+ err = f.Close()
+ if err != nil {
+ return err
+ }
+
+ // add newline if default format is given
+ if format == "" {
+ path += "\n"
+ }
+ // modify in place so we can print the
+ // paths when --files is set
+ report.Units[name] = path
+ }
+ }
+
+ switch format {
+ case "json":
+ return printJSON(report.Units)
+ case "":
+ return printDefault(report.Units)
+ default:
+ return errors.Errorf("unknown --format argument: %s", format)
+ }
+
+}
+
+func printDefault(units map[string]string) error {
+ for _, content := range units {
+ fmt.Print(content)
+ }
+ return nil
+}
+
+func printJSON(units map[string]string) error {
+ b, err := json.MarshalIndent(units, "", " ")
+ if err != nil {
+ return err
+ }
+ fmt.Println(string(b))
return nil
}
diff --git a/cmd/podman/system/df.go b/cmd/podman/system/df.go
index 03991101e..b262c8478 100644
--- a/cmd/podman/system/df.go
+++ b/cmd/podman/system/df.go
@@ -134,7 +134,7 @@ func printSummary(reports *entities.SystemDfReport, userFormat string) error {
for _, v := range reports.Volumes {
activeVolumes += v.Links
volumesSize += v.Size
- volumesReclaimable += v.Size
+ volumesReclaimable += v.ReclaimableSize
}
volumeSummary := dfSummary{
Type: "Local Volumes",
@@ -182,7 +182,7 @@ func printVerbose(reports *entities.SystemDfReport) error {
dfContainers = append(dfContainers, &dfContainer{SystemDfContainerReport: d})
}
containerHeaders := "CONTAINER ID\tIMAGE\tCOMMAND\tLOCAL VOLUMES\tSIZE\tCREATED\tSTATUS\tNAMES\n"
- containerRow := "{{.ContainerID}}\t{{.Image}}\t{{.Command}}\t{{.LocalVolumes}}\t{{.Size}}\t{{.Created}}\t{{.Status}}\t{{.Names}}\n"
+ containerRow := "{{.ContainerID}}\t{{.Image}}\t{{.Command}}\t{{.LocalVolumes}}\t{{.RWSize}}\t{{.Created}}\t{{.Status}}\t{{.Names}}\n"
format = containerHeaders + "{{range . }}" + containerRow + "{{end}}"
if err := writeTemplate(w, format, dfContainers); err != nil {
return nil
@@ -257,8 +257,8 @@ func (d *dfContainer) Command() string {
return strings.Join(d.SystemDfContainerReport.Command, " ")
}
-func (d *dfContainer) Size() string {
- return units.HumanSize(float64(d.SystemDfContainerReport.Size))
+func (d *dfContainer) RWSize() string {
+ return units.HumanSize(float64(d.SystemDfContainerReport.RWSize))
}
func (d *dfContainer) Created() string {
diff --git a/contrib/podmanimage/README.md b/contrib/podmanimage/README.md
index d6abb8ae6..7641f6c7e 100644
--- a/contrib/podmanimage/README.md
+++ b/contrib/podmanimage/README.md
@@ -49,3 +49,8 @@ podman images
exit
```
+
+**Note:** If you encounter a `fuse: device not found` error when running the container image, it is likely that
+the fuse kernel module has not been loaded on your host system. Use the command `modprobe fuse` to load the
+module and then run the container image. To enable this automatically at boot time, you can add a configuration
+file to `/etc/modules.load.d`. See `man modules-load.d` for more details.
diff --git a/docs/source/markdown/podman-generate-systemd.1.md b/docs/source/markdown/podman-generate-systemd.1.md
index d0b1b3588..2ee290f0f 100644
--- a/docs/source/markdown/podman-generate-systemd.1.md
+++ b/docs/source/markdown/podman-generate-systemd.1.md
@@ -10,7 +10,7 @@ podman\-generate\-systemd - Generate systemd unit file(s) for a container or pod
**podman generate systemd** will create a systemd unit file that can be used to control a container or pod.
By default, the command will print the content of the unit files to stdout.
-Note that this command is not supported for the remote client.
+_Note: If you use this command with the remote client, you would still have to place the generated units on the remote system._
## OPTIONS:
@@ -20,6 +20,10 @@ Generate files instead of printing to stdout. The generated files are named {co
Note: On a system with SELinux enabled, the generated files will inherit contexts from the current working directory. Depending on the SELinux setup, changes to the generated files using `restorecon`, `chcon`, or `semanage` may be required to allow systemd to access these files. Alternatively, use the `-Z` option when running `mv` or `cp`.
+**--format**=*format*
+
+Print the created units in specified format (json). If `--files` is specified the paths to the created files will be printed instead of the unit content.
+
**--name**, **-n**
Use the name of the container for the start, stop, and description in the unit file
diff --git a/go.mod b/go.mod
index bf6ddd57f..cfa0946b4 100644
--- a/go.mod
+++ b/go.mod
@@ -15,7 +15,7 @@ require (
github.com/containers/conmon v2.0.20+incompatible
github.com/containers/image/v5 v5.5.2
github.com/containers/psgo v1.5.1
- github.com/containers/storage v1.23.2
+ github.com/containers/storage v1.23.4
github.com/coreos/go-systemd/v22 v22.1.0
github.com/cri-o/ocicni v0.2.0
github.com/cyphar/filepath-securejoin v0.2.2
@@ -35,7 +35,7 @@ require (
github.com/hpcloud/tail v1.0.0
github.com/json-iterator/go v1.1.10
github.com/mrunalp/fileutils v0.0.0-20171103030105-7d4729fb3618
- github.com/onsi/ginkgo v1.14.0
+ github.com/onsi/ginkgo v1.14.1
github.com/onsi/gomega v1.10.1
github.com/opencontainers/go-digest v1.0.0
github.com/opencontainers/image-spec v1.0.2-0.20190823105129-775207bd45b6
diff --git a/go.sum b/go.sum
index c8d4add47..767df1e3d 100644
--- a/go.sum
+++ b/go.sum
@@ -90,6 +90,8 @@ github.com/containers/storage v1.20.2/go.mod h1:oOB9Ie8OVPojvoaKWEGSEtHbXUAs+tSy
github.com/containers/storage v1.23.0/go.mod h1:I1EIAA7B4OwWRSA0b4yq2AW1wjvvfcY0zLWQuwTa4zw=
github.com/containers/storage v1.23.2 h1:GPZ8PXYezML1gmZ/uFaXQpyps7AH645lmdvvOJwJYNc=
github.com/containers/storage v1.23.2/go.mod h1:AyTMMiE5ANvZJiqvatQgSZ85wAl5yHucY3NDN/kemr4=
+github.com/containers/storage v1.23.4 h1:1raHKGNs2C52tEq2ydHqZ+wu2u1d79BHMO6O5JO20xQ=
+github.com/containers/storage v1.23.4/go.mod h1:KzpVgmUucelPYHq2YsseUTiTuucdVh3xfpPNmxmPZRU=
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/go-iptables v0.4.5 h1:DpHb9vJrZQEFMcVLFKAAGMUVX0XoRC0ptCthinRYm38=
@@ -267,6 +269,8 @@ github.com/klauspost/compress v1.10.11 h1:K9z59aO18Aywg2b/WSgBaUX99mHy2BES18Cr5l
github.com/klauspost/compress v1.10.11/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
github.com/klauspost/pgzip v1.2.4 h1:TQ7CNpYKovDOmqzRHKxJh0BeaBI7UdQZYc6p7pMQh1A=
github.com/klauspost/pgzip v1.2.4/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
+github.com/klauspost/pgzip v1.2.5 h1:qnWYvvKqedOF2ulHpMG72XQol4ILEJ8k2wwRl/Km8oE=
+github.com/klauspost/pgzip v1.2.5/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8=
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
@@ -291,6 +295,7 @@ github.com/mistifyio/go-zfs v2.1.1+incompatible h1:gAMO1HM9xBRONLHHYnu5iFsOJUiJd
github.com/mistifyio/go-zfs v2.1.1+incompatible/go.mod h1:8AuVvqP/mXw1px98n46wfvcGfQ4ci2FwoAjKYxuo3Z4=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
+github.com/moby/sys/mountinfo v0.1.3 h1:KIrhRO14+AkwKvG/g2yIpNMOUVZ02xNhOw8KY1WsLOI=
github.com/moby/sys/mountinfo v0.1.3/go.mod h1:w2t2Avltqx8vE7gX5l+QiBKxODu2TX0+Syr3h52Tw4o=
github.com/moby/vpnkit v0.4.0/go.mod h1:KyjUrL9cb6ZSNNAUwZfqRjhwwgJ3BJN+kXh0t43WTUQ=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
@@ -322,6 +327,8 @@ github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
github.com/onsi/ginkgo v1.14.0 h1:2mOpI4JVVPBN+WQRa0WKH2eXR+Ey+uK4n7Zj0aYpIQA=
github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=
+github.com/onsi/ginkgo v1.14.1 h1:jMU0WaQrP0a/YAEq8eJmJKjBoMs+pClEr1vDMlM/Do4=
+github.com/onsi/ginkgo v1.14.1/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=
github.com/onsi/gomega v0.0.0-20151007035656-2152b45fa28a/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
github.com/onsi/gomega v0.0.0-20190113212917-5533ce8a0da3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
diff --git a/libpod/image/image.go b/libpod/image/image.go
index dee2ce0ee..2d055cc44 100644
--- a/libpod/image/image.go
+++ b/libpod/image/image.go
@@ -1247,11 +1247,14 @@ func areParentAndChild(parent, child *imgspecv1.Image) bool {
// candidate parent's diff IDs, which together would have
// controlled which layers were used
- // issue #7444 describes a panic where the length of child.RootFS.DiffIDs
- // is checked but child is nil. Adding a simple band-aid approach to prevent
- // the problem until the origin of the problem can be worked out in the issue
- // itself.
- if child == nil || len(parent.RootFS.DiffIDs) > len(child.RootFS.DiffIDs) {
+ // Both, child and parent, may be nil when the storage is left in an
+ // incoherent state. Issue #7444 describes such a case when a build
+ // has been killed.
+ if child == nil || parent == nil {
+ return false
+ }
+
+ if len(parent.RootFS.DiffIDs) > len(child.RootFS.DiffIDs) {
return false
}
childUsesCandidateDiffs := true
diff --git a/libpod/image/layer_tree.go b/libpod/image/layer_tree.go
index 3699655fd..18101575e 100644
--- a/libpod/image/layer_tree.go
+++ b/libpod/image/layer_tree.go
@@ -32,7 +32,9 @@ func (t *layerTree) toOCI(ctx context.Context, i *Image) (*ociv1.Image, error) {
oci, exists := t.ociCache[i.ID()]
if !exists {
oci, err = i.ociv1Image(ctx)
- t.ociCache[i.ID()] = oci
+ if err == nil {
+ t.ociCache[i.ID()] = oci
+ }
}
return oci, err
}
diff --git a/pkg/api/handlers/libpod/generate.go b/pkg/api/handlers/libpod/generate.go
index 966874a2b..33bb75391 100644
--- a/pkg/api/handlers/libpod/generate.go
+++ b/pkg/api/handlers/libpod/generate.go
@@ -7,10 +7,55 @@ import (
"github.com/containers/podman/v2/pkg/api/handlers/utils"
"github.com/containers/podman/v2/pkg/domain/entities"
"github.com/containers/podman/v2/pkg/domain/infra/abi"
+ "github.com/containers/podman/v2/pkg/util"
"github.com/gorilla/schema"
"github.com/pkg/errors"
)
+func GenerateSystemd(w http.ResponseWriter, r *http.Request) {
+ runtime := r.Context().Value("runtime").(*libpod.Runtime)
+ decoder := r.Context().Value("decoder").(*schema.Decoder)
+ query := struct {
+ Name bool `schema:"useName"`
+ New bool `schema:"new"`
+ RestartPolicy string `schema:"restartPolicy"`
+ StopTimeout uint `schema:"stopTimeout"`
+ ContainerPrefix string `schema:"containerPrefix"`
+ PodPrefix string `schema:"podPrefix"`
+ Separator string `schema:"separator"`
+ }{
+ RestartPolicy: "on-failure",
+ StopTimeout: util.DefaultContainerConfig().Engine.StopTimeout,
+ ContainerPrefix: "container",
+ PodPrefix: "pod",
+ Separator: "-",
+ }
+
+ if err := decoder.Decode(&query, r.URL.Query()); err != nil {
+ utils.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest,
+ errors.Wrapf(err, "failed to parse parameters for %s", r.URL.String()))
+ return
+ }
+
+ containerEngine := abi.ContainerEngine{Libpod: runtime}
+ options := entities.GenerateSystemdOptions{
+ Name: query.Name,
+ New: query.New,
+ RestartPolicy: query.RestartPolicy,
+ StopTimeout: &query.StopTimeout,
+ ContainerPrefix: query.ContainerPrefix,
+ PodPrefix: query.PodPrefix,
+ Separator: query.Separator,
+ }
+ report, err := containerEngine.GenerateSystemd(r.Context(), utils.GetName(r), options)
+ if err != nil {
+ utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "error generating systemd units"))
+ return
+ }
+
+ utils.WriteResponse(w, http.StatusOK, report.Units)
+}
+
func GenerateKube(w http.ResponseWriter, r *http.Request) {
runtime := r.Context().Value("runtime").(*libpod.Runtime)
decoder := r.Context().Value("decoder").(*schema.Decoder)
diff --git a/pkg/api/server/register_generate.go b/pkg/api/server/register_generate.go
index 7db8ee387..60e5b03f7 100644
--- a/pkg/api/server/register_generate.go
+++ b/pkg/api/server/register_generate.go
@@ -8,6 +8,68 @@ import (
)
func (s *APIServer) registerGenerateHandlers(r *mux.Router) error {
+ // swagger:operation GET /libpod/generate/{name:.*}/systemd libpod libpodGenerateSystemd
+ // ---
+ // tags:
+ // - containers
+ // - pods
+ // summary: Generate Systemd Units
+ // description: Generate Systemd Units based on a pod or container.
+ // parameters:
+ // - in: path
+ // name: name:.*
+ // type: string
+ // required: true
+ // description: Name or ID of the container or pod.
+ // - in: query
+ // name: useName
+ // type: boolean
+ // default: false
+ // description: Use container/pod names instead of IDs.
+ // - in: query
+ // name: new
+ // type: boolean
+ // default: false
+ // description: Create a new container instead of starting an existing one.
+ // - in: query
+ // name: time
+ // type: integer
+ // default: 10
+ // description: Stop timeout override.
+ // - in: query
+ // name: restartPolicy
+ // default: on-failure
+ // type: string
+ // enum: ["no", on-success, on-failure, on-abnormal, on-watchdog, on-abort, always]
+ // description: Systemd restart-policy.
+ // - in: query
+ // name: containerPrefix
+ // type: string
+ // default: container
+ // description: Systemd unit name prefix for containers.
+ // - in: query
+ // name: podPrefix
+ // type: string
+ // default: pod
+ // description: Systemd unit name prefix for pods.
+ // - in: query
+ // name: separator
+ // type: string
+ // default: "-"
+ // description: Systemd unit name separator between name/id and prefix.
+ // produces:
+ // - application/json
+ // responses:
+ // 200:
+ // description: no error
+ // schema:
+ // type: object
+ // additionalProperties:
+ // type: string
+ // 500:
+ // $ref: "#/responses/InternalError"
+ r.HandleFunc(VersionedPath("/libpod/generate/{name:.*}/systemd"), s.APIHandler(libpod.GenerateSystemd)).Methods(http.MethodGet)
+
// swagger:operation GET /libpod/generate/{name:.*}/kube libpod libpodGenerateKube
// ---
// tags:
diff --git a/pkg/bindings/generate/generate.go b/pkg/bindings/generate/generate.go
index b02221765..dde1cc29c 100644
--- a/pkg/bindings/generate/generate.go
+++ b/pkg/bindings/generate/generate.go
@@ -10,6 +10,33 @@ import (
"github.com/containers/podman/v2/pkg/domain/entities"
)
+func Systemd(ctx context.Context, nameOrID string, options entities.GenerateSystemdOptions) (*entities.GenerateSystemdReport, error) {
+ conn, err := bindings.GetClient(ctx)
+ if err != nil {
+ return nil, err
+ }
+ params := url.Values{}
+
+ params.Set("useName", strconv.FormatBool(options.Name))
+ params.Set("new", strconv.FormatBool(options.New))
+ if options.RestartPolicy != "" {
+ params.Set("restartPolicy", options.RestartPolicy)
+ }
+ if options.StopTimeout != nil {
+ params.Set("stopTimeout", strconv.FormatUint(uint64(*options.StopTimeout), 10))
+ }
+ params.Set("containerPrefix", options.ContainerPrefix)
+ params.Set("podPrefix", options.PodPrefix)
+ params.Set("separator", options.Separator)
+
+ response, err := conn.DoRequest(nil, http.MethodGet, "/generate/%s/systemd", params, nil, nameOrID)
+ if err != nil {
+ return nil, err
+ }
+ report := &entities.GenerateSystemdReport{}
+ return report, response.Process(&report.Units)
+}
+
func Kube(ctx context.Context, nameOrID string, options entities.GenerateKubeOptions) (*entities.GenerateKubeReport, error) {
conn, err := bindings.GetClient(ctx)
if err != nil {
diff --git a/pkg/domain/entities/generate.go b/pkg/domain/entities/generate.go
index a8ad13705..4a0d7537e 100644
--- a/pkg/domain/entities/generate.go
+++ b/pkg/domain/entities/generate.go
@@ -4,8 +4,6 @@ import "io"
// GenerateSystemdOptions control the generation of systemd unit files.
type GenerateSystemdOptions struct {
- // Files - generate files instead of printing to stdout.
- Files bool
// Name - use container/pod name instead of its ID.
Name bool
// New - create a new container instead of starting a new one.
@@ -24,9 +22,8 @@ type GenerateSystemdOptions struct {
// GenerateSystemdReport
type GenerateSystemdReport struct {
- // Output of the generate process. Either the generated files or their
- // entire content.
- Output string
+ // Units of the generate process. key = unit name -> value = unit content
+ Units map[string]string
}
// GenerateKubeOptions control the generation of Kubernetes YAML files.
diff --git a/pkg/domain/entities/system.go b/pkg/domain/entities/system.go
index af355b0af..bde2b6ef2 100644
--- a/pkg/domain/entities/system.go
+++ b/pkg/domain/entities/system.go
@@ -75,9 +75,10 @@ type SystemDfContainerReport struct {
// SystemDfVolumeReport describes a volume and its size
type SystemDfVolumeReport struct {
- VolumeName string
- Links int
- Size int64
+ VolumeName string
+ Links int
+ Size int64
+ ReclaimableSize int64
}
// SystemResetOptions describes the options for resetting your
diff --git a/pkg/domain/infra/abi/containers.go b/pkg/domain/infra/abi/containers.go
index 3fee5d394..0537942e6 100644
--- a/pkg/domain/infra/abi/containers.go
+++ b/pkg/domain/infra/abi/containers.go
@@ -174,6 +174,12 @@ func (ic *ContainerEngine) ContainerStop(ctx context.Context, namesOrIds []strin
return err
}
}
+ if c.AutoRemove() {
+ // Issue #7384: if the container is configured for
+ // auto-removal, it might already have been removed at
+ // this point.
+ return nil
+ }
return c.Cleanup(ctx)
})
if err != nil {
diff --git a/pkg/domain/infra/abi/generate.go b/pkg/domain/infra/abi/generate.go
index 0b73ddd7e..79bf2291e 100644
--- a/pkg/domain/infra/abi/generate.go
+++ b/pkg/domain/infra/abi/generate.go
@@ -19,11 +19,11 @@ func (ic *ContainerEngine) GenerateSystemd(ctx context.Context, nameOrID string,
ctr, ctrErr := ic.Libpod.LookupContainer(nameOrID)
if ctrErr == nil {
// Generate the unit for the container.
- s, err := generate.ContainerUnit(ctr, options)
+ name, content, err := generate.ContainerUnit(ctr, options)
if err != nil {
return nil, err
}
- return &entities.GenerateSystemdReport{Output: s}, nil
+ return &entities.GenerateSystemdReport{Units: map[string]string{name: content}}, nil
}
// If it's not a container, we either have a pod or garbage.
@@ -34,11 +34,11 @@ func (ic *ContainerEngine) GenerateSystemd(ctx context.Context, nameOrID string,
}
// Generate the units for the pod and all its containers.
- s, err := generate.PodUnits(pod, options)
+ units, err := generate.PodUnits(pod, options)
if err != nil {
return nil, err
}
- return &entities.GenerateSystemdReport{Output: s}, nil
+ return &entities.GenerateSystemdReport{Units: units}, nil
}
func (ic *ContainerEngine) GenerateKube(ctx context.Context, nameOrID string, options entities.GenerateKubeOptions) (*entities.GenerateKubeReport, error) {
diff --git a/pkg/domain/infra/abi/system.go b/pkg/domain/infra/abi/system.go
index ff1052d86..914a7681d 100644
--- a/pkg/domain/infra/abi/system.go
+++ b/pkg/domain/infra/abi/system.go
@@ -313,6 +313,7 @@ func (ic *ContainerEngine) SystemDf(ctx context.Context, options entities.System
}
dfVolumes := make([]*entities.SystemDfVolumeReport, 0, len(vols))
+ var reclaimableSize int64
for _, v := range vols {
var consInUse int
volSize, err := sizeOfPath(v.MountPoint())
@@ -323,15 +324,19 @@ func (ic *ContainerEngine) SystemDf(ctx context.Context, options entities.System
if err != nil {
return nil, err
}
+ if len(inUse) == 0 {
+ reclaimableSize += volSize
+ }
for _, viu := range inUse {
if util.StringInSlice(viu, runningContainers) {
consInUse++
}
}
report := entities.SystemDfVolumeReport{
- VolumeName: v.Name(),
- Links: consInUse,
- Size: volSize,
+ VolumeName: v.Name(),
+ Links: consInUse,
+ Size: volSize,
+ ReclaimableSize: reclaimableSize,
}
dfVolumes = append(dfVolumes, &report)
}
diff --git a/pkg/domain/infra/tunnel/generate.go b/pkg/domain/infra/tunnel/generate.go
index c7d5cd9e2..966f707b1 100644
--- a/pkg/domain/infra/tunnel/generate.go
+++ b/pkg/domain/infra/tunnel/generate.go
@@ -5,11 +5,10 @@ import (
"github.com/containers/podman/v2/pkg/bindings/generate"
"github.com/containers/podman/v2/pkg/domain/entities"
- "github.com/pkg/errors"
)
func (ic *ContainerEngine) GenerateSystemd(ctx context.Context, nameOrID string, options entities.GenerateSystemdOptions) (*entities.GenerateSystemdReport, error) {
- return nil, errors.New("not implemented for tunnel")
+ return generate.Systemd(ic.ClientCxt, nameOrID, options)
}
func (ic *ContainerEngine) GenerateKube(ctx context.Context, nameOrID string, options entities.GenerateKubeOptions) (*entities.GenerateKubeReport, error) {
diff --git a/pkg/specgen/generate/security.go b/pkg/specgen/generate/security.go
index d3e3d9278..87e8029a7 100644
--- a/pkg/specgen/generate/security.go
+++ b/pkg/specgen/generate/security.go
@@ -60,7 +60,7 @@ func setLabelOpts(s *specgen.SpecGenerator, runtime *libpod.Runtime, pidConfig s
func setupApparmor(s *specgen.SpecGenerator, rtc *config.Config, g *generate.Generator) error {
hasProfile := len(s.ApparmorProfile) > 0
if !apparmor.IsEnabled() {
- if hasProfile {
+ if hasProfile && s.ApparmorProfile != "unconfined" {
return errors.Errorf("Apparmor profile %q specified, but Apparmor is not enabled on this system", s.ApparmorProfile)
}
return nil
diff --git a/pkg/systemd/generate/containers.go b/pkg/systemd/generate/containers.go
index 5f6376977..caf5de357 100644
--- a/pkg/systemd/generate/containers.go
+++ b/pkg/systemd/generate/containers.go
@@ -3,9 +3,7 @@ package generate
import (
"bytes"
"fmt"
- "io/ioutil"
"os"
- "path/filepath"
"sort"
"strings"
"text/template"
@@ -87,17 +85,22 @@ KillMode=none
Type=forking
[Install]
-WantedBy=multi-user.target default.target`
+WantedBy=multi-user.target default.target
+`
// ContainerUnit generates a systemd unit for the specified container. Based
// on the options, the return value might be the entire unit or a file it has
// been written to.
-func ContainerUnit(ctr *libpod.Container, options entities.GenerateSystemdOptions) (string, error) {
+func ContainerUnit(ctr *libpod.Container, options entities.GenerateSystemdOptions) (string, string, error) {
info, err := generateContainerInfo(ctr, options)
if err != nil {
- return "", err
+ return "", "", err
+ }
+ content, err := executeContainerTemplate(info, options)
+ if err != nil {
+ return "", "", err
}
- return executeContainerTemplate(info, options)
+ return info.ServiceName, content, nil
}
func generateContainerInfo(ctr *libpod.Container, options entities.GenerateSystemdOptions) (*containerInfo, error) {
@@ -288,18 +291,5 @@ func executeContainerTemplate(info *containerInfo, options entities.GenerateSyst
return "", err
}
- if !options.Files {
- return buf.String(), nil
- }
-
- buf.WriteByte('\n')
- cwd, err := os.Getwd()
- if err != nil {
- return "", errors.Wrap(err, "error getting current working directory")
- }
- path := filepath.Join(cwd, fmt.Sprintf("%s.service", info.ServiceName))
- if err := ioutil.WriteFile(path, buf.Bytes(), 0644); err != nil {
- return "", errors.Wrap(err, "error generating systemd unit")
- }
- return path, nil
+ return buf.String(), nil
}
diff --git a/pkg/systemd/generate/containers_test.go b/pkg/systemd/generate/containers_test.go
index b5c736c5a..d27062ef3 100644
--- a/pkg/systemd/generate/containers_test.go
+++ b/pkg/systemd/generate/containers_test.go
@@ -56,7 +56,8 @@ KillMode=none
Type=forking
[Install]
-WantedBy=multi-user.target default.target`
+WantedBy=multi-user.target default.target
+`
goodName := `# container-foobar.service
# autogenerated by Podman CI
@@ -78,7 +79,8 @@ KillMode=none
Type=forking
[Install]
-WantedBy=multi-user.target default.target`
+WantedBy=multi-user.target default.target
+`
goodNameBoundTo := `# container-foobar.service
# autogenerated by Podman CI
@@ -102,7 +104,8 @@ KillMode=none
Type=forking
[Install]
-WantedBy=multi-user.target default.target`
+WantedBy=multi-user.target default.target
+`
goodWithNameAndGeneric := `# jadda-jadda.service
# autogenerated by Podman CI
@@ -125,7 +128,8 @@ KillMode=none
Type=forking
[Install]
-WantedBy=multi-user.target default.target`
+WantedBy=multi-user.target default.target
+`
goodWithExplicitShortDetachParam := `# jadda-jadda.service
# autogenerated by Podman CI
@@ -148,7 +152,8 @@ KillMode=none
Type=forking
[Install]
-WantedBy=multi-user.target default.target`
+WantedBy=multi-user.target default.target
+`
goodNameNewWithPodFile := `# jadda-jadda.service
# autogenerated by Podman CI
@@ -171,7 +176,8 @@ KillMode=none
Type=forking
[Install]
-WantedBy=multi-user.target default.target`
+WantedBy=multi-user.target default.target
+`
goodNameNewDetach := `# jadda-jadda.service
# autogenerated by Podman CI
@@ -194,7 +200,8 @@ KillMode=none
Type=forking
[Install]
-WantedBy=multi-user.target default.target`
+WantedBy=multi-user.target default.target
+`
goodIDNew := `# container-639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401.service
# autogenerated by Podman CI
@@ -217,7 +224,8 @@ KillMode=none
Type=forking
[Install]
-WantedBy=multi-user.target default.target`
+WantedBy=multi-user.target default.target
+`
tests := []struct {
name string
@@ -375,8 +383,7 @@ WantedBy=multi-user.target default.target`
test := tt
t.Run(tt.name, func(t *testing.T) {
opts := entities.GenerateSystemdOptions{
- Files: false,
- New: test.new,
+ New: test.new,
}
got, err := executeContainerTemplate(&test.info, opts)
if (err != nil) != test.wantErr {
diff --git a/pkg/systemd/generate/pods.go b/pkg/systemd/generate/pods.go
index dec9587d9..c41eedd17 100644
--- a/pkg/systemd/generate/pods.go
+++ b/pkg/systemd/generate/pods.go
@@ -3,9 +3,7 @@ package generate
import (
"bytes"
"fmt"
- "io/ioutil"
"os"
- "path/filepath"
"sort"
"strings"
"text/template"
@@ -88,39 +86,40 @@ KillMode=none
Type=forking
[Install]
-WantedBy=multi-user.target default.target`
+WantedBy=multi-user.target default.target
+`
// PodUnits generates systemd units for the specified pod and its containers.
// Based on the options, the return value might be the content of all units or
// the files they been written to.
-func PodUnits(pod *libpod.Pod, options entities.GenerateSystemdOptions) (string, error) {
+func PodUnits(pod *libpod.Pod, options entities.GenerateSystemdOptions) (map[string]string, error) {
// Error out if the pod has no infra container, which we require to be the
// main service.
if !pod.HasInfraContainer() {
- return "", errors.Errorf("error generating systemd unit files: Pod %q has no infra container", pod.Name())
+ return nil, errors.Errorf("error generating systemd unit files: Pod %q has no infra container", pod.Name())
}
podInfo, err := generatePodInfo(pod, options)
if err != nil {
- return "", err
+ return nil, err
}
infraID, err := pod.InfraContainerID()
if err != nil {
- return "", err
+ return nil, err
}
// Compute the container-dependency graph for the Pod.
containers, err := pod.AllContainers()
if err != nil {
- return "", err
+ return nil, err
}
if len(containers) == 0 {
- return "", errors.Errorf("error generating systemd unit files: Pod %q has no containers", pod.Name())
+ return nil, errors.Errorf("error generating systemd unit files: Pod %q has no containers", pod.Name())
}
graph, err := libpod.BuildContainerGraph(containers)
if err != nil {
- return "", err
+ return nil, err
}
// Traverse the dependency graph and create systemdgen.containerInfo's for
@@ -133,7 +132,7 @@ func PodUnits(pod *libpod.Pod, options entities.GenerateSystemdOptions) (string,
}
ctrInfo, err := generateContainerInfo(ctr, options)
if err != nil {
- return "", err
+ return nil, err
}
// Now add the container's dependencies and at the container as a
// required service of the infra container.
@@ -149,24 +148,23 @@ func PodUnits(pod *libpod.Pod, options entities.GenerateSystemdOptions) (string,
containerInfos = append(containerInfos, ctrInfo)
}
+ units := map[string]string{}
// Now generate the systemd service for all containers.
- builder := strings.Builder{}
out, err := executePodTemplate(podInfo, options)
if err != nil {
- return "", err
+ return nil, err
}
- builder.WriteString(out)
+ units[podInfo.ServiceName] = out
for _, info := range containerInfos {
info.pod = podInfo
- builder.WriteByte('\n')
out, err := executeContainerTemplate(info, options)
if err != nil {
- return "", err
+ return nil, err
}
- builder.WriteString(out)
+ units[info.ServiceName] = out
}
- return builder.String(), nil
+ return units, nil
}
func generatePodInfo(pod *libpod.Pod, options entities.GenerateSystemdOptions) (*podInfo, error) {
@@ -339,18 +337,5 @@ func executePodTemplate(info *podInfo, options entities.GenerateSystemdOptions)
return "", err
}
- if !options.Files {
- return buf.String(), nil
- }
-
- buf.WriteByte('\n')
- cwd, err := os.Getwd()
- if err != nil {
- return "", errors.Wrap(err, "error getting current working directory")
- }
- path := filepath.Join(cwd, fmt.Sprintf("%s.service", info.ServiceName))
- if err := ioutil.WriteFile(path, buf.Bytes(), 0644); err != nil {
- return "", errors.Wrap(err, "error generating systemd unit")
- }
- return path, nil
+ return buf.String(), nil
}
diff --git a/pkg/systemd/generate/pods_test.go b/pkg/systemd/generate/pods_test.go
index 8bf4705a7..7f1f63b7e 100644
--- a/pkg/systemd/generate/pods_test.go
+++ b/pkg/systemd/generate/pods_test.go
@@ -58,7 +58,8 @@ KillMode=none
Type=forking
[Install]
-WantedBy=multi-user.target default.target`
+WantedBy=multi-user.target default.target
+`
podGoodNamedNew := `# pod-123abc.service
# autogenerated by Podman CI
@@ -84,7 +85,8 @@ KillMode=none
Type=forking
[Install]
-WantedBy=multi-user.target default.target`
+WantedBy=multi-user.target default.target
+`
tests := []struct {
name string
@@ -130,8 +132,7 @@ WantedBy=multi-user.target default.target`
test := tt
t.Run(tt.name, func(t *testing.T) {
opts := entities.GenerateSystemdOptions{
- Files: false,
- New: test.new,
+ New: test.new,
}
got, err := executePodTemplate(&test.info, opts)
if (err != nil) != test.wantErr {
diff --git a/test/e2e/generate_systemd_test.go b/test/e2e/generate_systemd_test.go
index 60d9162d1..cd3ee6e0a 100644
--- a/test/e2e/generate_systemd_test.go
+++ b/test/e2e/generate_systemd_test.go
@@ -1,5 +1,3 @@
-// +build !remote
-
package integration
import (
@@ -61,7 +59,7 @@ var _ = Describe("Podman generate systemd", func() {
session = podmanTest.Podman([]string{"generate", "systemd", "--restart-policy", "bogus", "foobar"})
session.WaitWithDefaultTimeout()
Expect(session).To(ExitWithError())
- found, _ := session.ErrorGrepString("Error: bogus is not a valid restart policy")
+ found, _ := session.ErrorGrepString("bogus is not a valid restart policy")
Expect(found).Should(BeTrue())
})
@@ -383,4 +381,15 @@ var _ = Describe("Podman generate systemd", func() {
found, _ = session.GrepString("pod rm --ignore -f --pod-id-file %t/pod-foo.pod-id")
Expect(found).To(BeTrue())
})
+
+ It("podman generate systemd --format json", func() {
+ n := podmanTest.Podman([]string{"create", "--name", "foo", ALPINE})
+ n.WaitWithDefaultTimeout()
+ Expect(n.ExitCode()).To(Equal(0))
+
+ session := podmanTest.Podman([]string{"generate", "systemd", "--format", "json", "foo"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+ Expect(session.IsJSONOutputValid()).To(BeTrue())
+ })
})
diff --git a/test/e2e/run_apparmor_test.go b/test/e2e/run_apparmor_test.go
index 53cac9529..7d522a752 100644
--- a/test/e2e/run_apparmor_test.go
+++ b/test/e2e/run_apparmor_test.go
@@ -155,4 +155,17 @@ profile aa-test-profile flags=(attach_disconnected,mediate_deleted) {
inspect := podmanTest.InspectContainer(cid)
Expect(inspect[0].AppArmorProfile).To(Equal(""))
})
+
+ It("podman run apparmor disabled unconfined", func() {
+ skipIfAppArmorEnabled()
+
+ session := podmanTest.Podman([]string{"create", "--security-opt", "apparmor=unconfined", ALPINE, "ls"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+
+ cid := session.OutputToString()
+ // Verify that apparmor.Profile is being set
+ inspect := podmanTest.InspectContainer(cid)
+ Expect(inspect[0].AppArmorProfile).To(Equal(""))
+ })
})
diff --git a/test/system/helpers.bash b/test/system/helpers.bash
index a6414344e..6c24b24b3 100644
--- a/test/system/helpers.bash
+++ b/test/system/helpers.bash
@@ -67,7 +67,7 @@ function basic_teardown() {
run_podman '?' pod rm --all --force
run_podman '?' rm --all --force
- /bin/rm -rf $PODMAN_TMPDIR
+ command rm -rf $PODMAN_TMPDIR
}
diff --git a/troubleshooting.md b/troubleshooting.md
index 7e8f9bcb0..9677b1821 100644
--- a/troubleshooting.md
+++ b/troubleshooting.md
@@ -592,3 +592,28 @@ access to that port. For example:
```
$ podman run --pod srcview --name src-expose -v "${PWD}:/var/opt/localrepo":Z,ro sourcegraph/src-expose:latest serve /var/opt/localrepo
```
+
+### 24) Podman container images fail with `fuse: device not found` when run
+
+Some container images require that the fuse kernel module is loaded in the kernel
+before they will run with the fuse filesystem in play.
+
+#### Symptom
+
+When trying to run the container images found at quay.io/podman, quay.io/containers
+registry.access.redhat.com/ubi8 or other locations, an error will sometimes be returned:
+
+```
+ERRO error unmounting /var/lib/containers/storage/overlay/30c058cdadc888177361dd14a7ed7edab441c58525b341df321f07bc11440e68/merged: invalid argument
+error mounting container "1ae176ca72b3da7c70af31db7434bcf6f94b07dbc0328bc7e4e8fc9579d0dc2e": error mounting build container "1ae176ca72b3da7c70af31db7434bcf6f94b07dbc0328bc7e4e8fc9579d0dc2e": error creating overlay mount to /var/lib/containers/storage/overlay/30c058cdadc888177361dd14a7ed7edab441c58525b341df321f07bc11440e68/merged: using mount program /usr/bin/fuse-overlayfs: fuse: device not found, try 'modprobe fuse' first
+fuse-overlayfs: cannot mount: No such device
+: exit status 1
+ERRO exit status 1
+```
+
+#### Solution
+
+If you encounter a `fuse: device not found` error when running the container image, it is likely that
+the fuse kernel module has not been loaded on your host system. Use the command `modprobe fuse` to load the
+module and then run the container image afterwards. To enable this automatically at boot time, you can add a configuration
+file to `/etc/modules.load.d`. See `man modules-load.d` for more details.
diff --git a/vendor/github.com/containers/storage/VERSION b/vendor/github.com/containers/storage/VERSION
index 14bee92c9..27ddcc14d 100644
--- a/vendor/github.com/containers/storage/VERSION
+++ b/vendor/github.com/containers/storage/VERSION
@@ -1 +1 @@
-1.23.2
+1.23.4
diff --git a/vendor/github.com/containers/storage/go.mod b/vendor/github.com/containers/storage/go.mod
index 77eef7598..7a568273f 100644
--- a/vendor/github.com/containers/storage/go.mod
+++ b/vendor/github.com/containers/storage/go.mod
@@ -9,9 +9,10 @@ require (
github.com/docker/go-units v0.4.0
github.com/hashicorp/go-multierror v1.1.0
github.com/klauspost/compress v1.10.11
- github.com/klauspost/pgzip v1.2.4
+ github.com/klauspost/pgzip v1.2.5
github.com/mattn/go-shellwords v1.0.10
github.com/mistifyio/go-zfs v2.1.1+incompatible
+ github.com/moby/sys/mountinfo v0.1.3
github.com/opencontainers/go-digest v1.0.0
github.com/opencontainers/runc v1.0.0-rc91
github.com/opencontainers/runtime-spec v1.0.3-0.20200520003142-237cc4f519e2
diff --git a/vendor/github.com/containers/storage/go.sum b/vendor/github.com/containers/storage/go.sum
index 04d48eb4f..dba69025f 100644
--- a/vendor/github.com/containers/storage/go.sum
+++ b/vendor/github.com/containers/storage/go.sum
@@ -64,8 +64,8 @@ github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQL
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/compress v1.10.11 h1:K9z59aO18Aywg2b/WSgBaUX99mHy2BES18Cr5lBKZHk=
github.com/klauspost/compress v1.10.11/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
-github.com/klauspost/pgzip v1.2.4 h1:TQ7CNpYKovDOmqzRHKxJh0BeaBI7UdQZYc6p7pMQh1A=
-github.com/klauspost/pgzip v1.2.4/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
+github.com/klauspost/pgzip v1.2.5 h1:qnWYvvKqedOF2ulHpMG72XQol4ILEJ8k2wwRl/Km8oE=
+github.com/klauspost/pgzip v1.2.5/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8=
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
diff --git a/vendor/github.com/containers/storage/layers.go b/vendor/github.com/containers/storage/layers.go
index dc21f75fd..52577299c 100644
--- a/vendor/github.com/containers/storage/layers.go
+++ b/vendor/github.com/containers/storage/layers.go
@@ -1342,6 +1342,7 @@ func (r *layerStore) ApplyDiff(to string, diff io.Reader) (size int64, err error
if err != nil {
return -1, err
}
+ defer idLogger.Close()
payload, err := asm.NewInputTarStream(io.TeeReader(uncompressed, io.MultiWriter(uncompressedCounter, idLogger)), metadata, storage.NewDiscardFilePutter())
if err != nil {
return -1, err
@@ -1356,7 +1357,6 @@ func (r *layerStore) ApplyDiff(to string, diff io.Reader) (size int64, err error
return -1, err
}
compressor.Close()
- idLogger.Close()
if err == nil {
if err := os.MkdirAll(filepath.Dir(r.tspath(layer.ID)), 0700); err != nil {
return -1, err
diff --git a/vendor/github.com/containers/storage/pkg/mount/mount.go b/vendor/github.com/containers/storage/pkg/mount/mount.go
index 4b888dceb..8273ab5a9 100644
--- a/vendor/github.com/containers/storage/pkg/mount/mount.go
+++ b/vendor/github.com/containers/storage/pkg/mount/mount.go
@@ -4,8 +4,6 @@ import (
"sort"
"strconv"
"strings"
-
- "github.com/containers/storage/pkg/fileutils"
)
// mountError holds an error from a mount or unmount operation
@@ -43,33 +41,6 @@ func (e *mountError) Cause() error {
return e.err
}
-// GetMounts retrieves a list of mounts for the current running process.
-func GetMounts() ([]*Info, error) {
- return parseMountTable()
-}
-
-// Mounted determines if a specified mountpoint has been mounted.
-// On Linux it looks at /proc/self/mountinfo and on Solaris at mnttab.
-func Mounted(mountpoint string) (bool, error) {
- entries, err := parseMountTable()
- if err != nil {
- return false, err
- }
-
- mountpoint, err = fileutils.ReadSymlinkedPath(mountpoint)
- if err != nil {
- return false, err
- }
-
- // Search the table for the mountpoint
- for _, e := range entries {
- if e.Mountpoint == mountpoint {
- return true, nil
- }
- }
- return false, nil
-}
-
// Mount will mount filesystem according to the specified configuration, on the
// condition that the target path is *not* already mounted. Options must be
// specified like the mount or fstab unix commands: "opt1=val1,opt2=val2". See
diff --git a/vendor/github.com/containers/storage/pkg/mount/mountinfo.go b/vendor/github.com/containers/storage/pkg/mount/mountinfo.go
index e3fc3535e..efc6c406e 100644
--- a/vendor/github.com/containers/storage/pkg/mount/mountinfo.go
+++ b/vendor/github.com/containers/storage/pkg/mount/mountinfo.go
@@ -1,40 +1,21 @@
package mount
-// Info reveals information about a particular mounted filesystem. This
-// struct is populated from the content in the /proc/<pid>/mountinfo file.
-type Info struct {
- // ID is a unique identifier of the mount (may be reused after umount).
- ID int
+import (
+ "github.com/containers/storage/pkg/fileutils"
+ "github.com/moby/sys/mountinfo"
+)
- // Parent indicates the ID of the mount parent (or of self for the top of the
- // mount tree).
- Parent int
+type Info = mountinfo.Info
- // Major indicates one half of the device ID which identifies the device class.
- Major int
-
- // Minor indicates one half of the device ID which identifies a specific
- // instance of device.
- Minor int
-
- // Root of the mount within the filesystem.
- Root string
-
- // Mountpoint indicates the mount point relative to the process's root.
- Mountpoint string
-
- // Opts represents mount-specific options.
- Opts string
-
- // Optional represents optional fields.
- Optional string
-
- // Fstype indicates the type of filesystem, such as EXT3.
- Fstype string
-
- // Source indicates filesystem specific information or "none".
- Source string
+func GetMounts() ([]*Info, error) {
+ return mountinfo.GetMounts(nil)
+}
- // VfsOpts represents per super block options.
- VfsOpts string
+// Mounted determines if a specified mountpoint has been mounted.
+func Mounted(mountpoint string) (bool, error) {
+ mountpoint, err := fileutils.ReadSymlinkedPath(mountpoint)
+ if err != nil {
+ return false, err
+ }
+ return mountinfo.Mounted(mountpoint)
}
diff --git a/vendor/github.com/containers/storage/pkg/mount/mountinfo_linux.go b/vendor/github.com/containers/storage/pkg/mount/mountinfo_linux.go
index 19556d06b..cbc0299fb 100644
--- a/vendor/github.com/containers/storage/pkg/mount/mountinfo_linux.go
+++ b/vendor/github.com/containers/storage/pkg/mount/mountinfo_linux.go
@@ -1,120 +1,5 @@
package mount
-import (
- "bufio"
- "fmt"
- "io"
- "os"
- "strconv"
- "strings"
+import "github.com/moby/sys/mountinfo"
- "github.com/pkg/errors"
-)
-
-// Parse /proc/self/mountinfo because comparing Dev and ino does not work from
-// bind mounts
-func parseMountTable() ([]*Info, error) {
- f, err := os.Open("/proc/self/mountinfo")
- if err != nil {
- return nil, err
- }
- defer f.Close()
-
- return parseInfoFile(f)
-}
-
-func parseInfoFile(r io.Reader) ([]*Info, error) {
- s := bufio.NewScanner(r)
- out := []*Info{}
-
- for s.Scan() {
- /*
- 36 35 98:0 /mnt1 /mnt2 rw,noatime master:1 - ext3 /dev/root rw,errors=continue
- (0)(1)(2) (3) (4) (5) (6) (7) (8) (9) (10)
-
- (0) mount ID: unique identifier of the mount (may be reused after umount)
- (1) parent ID: ID of parent (or of self for the top of the mount tree)
- (2) major:minor: value of st_dev for files on filesystem
- (3) root: root of the mount within the filesystem
- (4) mount point: mount point relative to the process's root
- (5) mount options: per mount options
- (6) optional fields: zero or more fields of the form "tag[:value]"
- (7) separator: marks the end of the optional fields
- (8) filesystem type: name of filesystem of the form "type[.subtype]"
- (9) mount source: filesystem specific information or "none"
- (10) super options: per super block options
- */
- text := s.Text()
- fields := strings.Split(text, " ")
- numFields := len(fields)
- if numFields < 10 {
- // should be at least 10 fields
- return nil, errors.Errorf("Parsing %q failed: not enough fields (%d)", text, numFields)
- }
-
- p := &Info{}
- // ignore any number parsing errors, there should not be any
- p.ID, _ = strconv.Atoi(fields[0])
- p.Parent, _ = strconv.Atoi(fields[1])
- mm := strings.Split(fields[2], ":")
- if len(mm) != 2 {
- return nil, fmt.Errorf("Parsing %q failed: unexpected minor:major pair %s", text, mm)
- }
- p.Major, _ = strconv.Atoi(mm[0])
- p.Minor, _ = strconv.Atoi(mm[1])
- p.Root = fields[3]
- p.Mountpoint = fields[4]
- p.Opts = fields[5]
-
- // one or more optional fields, when a separator (-)
- i := 6
- for ; i < numFields && fields[i] != "-"; i++ {
- switch i {
- case 6:
- p.Optional = string(fields[6])
- default:
- /* NOTE there might be more optional fields before the separator,
- such as fields[7] or fields[8], although as of Linux kernel 5.5
- the only known ones are mount propagation flags in fields[6].
- The correct behavior is to ignore any unknown optional fields.
- */
- }
- }
- if i == numFields {
- return nil, fmt.Errorf("Parsing %q failed: missing - separator", text)
- }
-
- // There should be 3 fields after the separator...
- if i+4 > numFields {
- return nil, fmt.Errorf("Parsing %q failed: not enough fields after a - separator", text)
- }
- // ... but in Linux <= 3.9 mounting a cifs with spaces in a share name
- // (like "//serv/My Documents") _may_ end up having a space in the last field
- // of mountinfo (like "unc=//serv/My Documents"). Since kernel 3.10-rc1, cifs
- // option unc= is ignored, so a space should not appear. In here we ignore
- // those "extra" fields caused by extra spaces.
- p.Fstype = fields[i+1]
- p.Source = fields[i+2]
- p.VfsOpts = fields[i+3]
-
- out = append(out, p)
- }
- if err := s.Err(); err != nil {
- return nil, err
- }
-
- return out, nil
-}
-
-// PidMountInfo collects the mounts for a specific process ID. If the process
-// ID is unknown, it is better to use `GetMounts` which will inspect
-// "/proc/self/mountinfo" instead.
-func PidMountInfo(pid int) ([]*Info, error) {
- f, err := os.Open(fmt.Sprintf("/proc/%d/mountinfo", pid))
- if err != nil {
- return nil, err
- }
- defer f.Close()
-
- return parseInfoFile(f)
-}
+var PidMountInfo = mountinfo.PidMountInfo
diff --git a/vendor/github.com/containers/storage/pkg/mount/mountinfo_unsupported.go b/vendor/github.com/containers/storage/pkg/mount/mountinfo_unsupported.go
deleted file mode 100644
index 6cde1ed77..000000000
--- a/vendor/github.com/containers/storage/pkg/mount/mountinfo_unsupported.go
+++ /dev/null
@@ -1,12 +0,0 @@
-// +build !linux
-
-package mount
-
-import (
- "fmt"
- "runtime"
-)
-
-func parseMountTable() ([]*Info, error) {
- return nil, fmt.Errorf("mount.parseMountTable is not implemented on %s/%s", runtime.GOOS, runtime.GOARCH)
-}
diff --git a/vendor/github.com/klauspost/pgzip/.travis.yml b/vendor/github.com/klauspost/pgzip/.travis.yml
index 6e9fca0ba..acfec4bb0 100644
--- a/vendor/github.com/klauspost/pgzip/.travis.yml
+++ b/vendor/github.com/klauspost/pgzip/.travis.yml
@@ -1,19 +1,22 @@
language: go
-sudo: false
-
os:
- linux
- osx
go:
- - 1.9.x
- - 1.10.x
+ - 1.13.x
+ - 1.14.x
+ - 1.15.x
- master
-script:
- - go test -v -cpu=1,2,4 .
- - go test -v -cpu=2 -race -short .
+env:
+ - GO111MODULE=off
+
+script:
+ - diff <(gofmt -d .) <(printf "")
+ - go test -v -cpu=1,2,4 .
+ - go test -v -cpu=2 -race -short .
matrix:
allow_failures:
diff --git a/vendor/github.com/klauspost/pgzip/gunzip.go b/vendor/github.com/klauspost/pgzip/gunzip.go
index 93efec714..d1ae730b2 100644
--- a/vendor/github.com/klauspost/pgzip/gunzip.go
+++ b/vendor/github.com/klauspost/pgzip/gunzip.go
@@ -331,6 +331,16 @@ func (z *Reader) killReadAhead() error {
// Wait for decompressor to be closed and return error, if any.
e, ok := <-z.closeErr
z.activeRA = false
+
+ for blk := range z.readAhead {
+ if blk.b != nil {
+ z.blockPool <- blk.b
+ }
+ }
+ if cap(z.current) > 0 {
+ z.blockPool <- z.current
+ z.current = nil
+ }
if !ok {
// Channel is closed, so if there was any error it has already been returned.
return nil
@@ -418,6 +428,7 @@ func (z *Reader) doReadAhead() {
case z.readAhead <- read{b: buf, err: err}:
case <-closeReader:
// Sent on close, we don't care about the next results
+ z.blockPool <- buf
return
}
if err != nil {
diff --git a/vendor/github.com/moby/sys/mountinfo/LICENSE b/vendor/github.com/moby/sys/mountinfo/LICENSE
new file mode 100644
index 000000000..d64569567
--- /dev/null
+++ b/vendor/github.com/moby/sys/mountinfo/LICENSE
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/vendor/github.com/moby/sys/mountinfo/go.mod b/vendor/github.com/moby/sys/mountinfo/go.mod
new file mode 100644
index 000000000..10d9a15a6
--- /dev/null
+++ b/vendor/github.com/moby/sys/mountinfo/go.mod
@@ -0,0 +1,3 @@
+module github.com/moby/sys/mountinfo
+
+go 1.14
diff --git a/vendor/github.com/moby/sys/mountinfo/mountinfo.go b/vendor/github.com/moby/sys/mountinfo/mountinfo.go
new file mode 100644
index 000000000..136b14167
--- /dev/null
+++ b/vendor/github.com/moby/sys/mountinfo/mountinfo.go
@@ -0,0 +1,67 @@
+package mountinfo
+
+import "io"
+
+// GetMounts retrieves a list of mounts for the current running process,
+// with an optional filter applied (use nil for no filter).
+func GetMounts(f FilterFunc) ([]*Info, error) {
+ return parseMountTable(f)
+}
+
+// GetMountsFromReader retrieves a list of mounts from the
+// reader provided, with an optional filter applied (use nil
+// for no filter). This can be useful in tests or benchmarks
+// that provide a fake mountinfo data.
+func GetMountsFromReader(reader io.Reader, f FilterFunc) ([]*Info, error) {
+ return parseInfoFile(reader, f)
+}
+
+// Mounted determines if a specified mountpoint has been mounted.
+// On Linux it looks at /proc/self/mountinfo.
+func Mounted(mountpoint string) (bool, error) {
+ entries, err := GetMounts(SingleEntryFilter(mountpoint))
+ if err != nil {
+ return false, err
+ }
+
+ return len(entries) > 0, nil
+}
+
+// Info reveals information about a particular mounted filesystem. This
+// struct is populated from the content in the /proc/<pid>/mountinfo file.
+type Info struct {
+ // ID is a unique identifier of the mount (may be reused after umount).
+ ID int
+
+ // Parent indicates the ID of the mount parent (or of self for the top of the
+ // mount tree).
+ Parent int
+
+ // Major indicates one half of the device ID which identifies the device class.
+ Major int
+
+ // Minor indicates one half of the device ID which identifies a specific
+ // instance of device.
+ Minor int
+
+ // Root of the mount within the filesystem.
+ Root string
+
+ // Mountpoint indicates the mount point relative to the process's root.
+ Mountpoint string
+
+ // Opts represents mount-specific options.
+ Opts string
+
+ // Optional represents optional fields.
+ Optional string
+
+ // Fstype indicates the type of filesystem, such as EXT3.
+ Fstype string
+
+ // Source indicates filesystem specific information or "none".
+ Source string
+
+ // VfsOpts represents per super block options.
+ VfsOpts string
+}
diff --git a/vendor/github.com/moby/sys/mountinfo/mountinfo_filters.go b/vendor/github.com/moby/sys/mountinfo/mountinfo_filters.go
new file mode 100644
index 000000000..795026465
--- /dev/null
+++ b/vendor/github.com/moby/sys/mountinfo/mountinfo_filters.go
@@ -0,0 +1,58 @@
+package mountinfo
+
+import "strings"
+
+// FilterFunc is a type defining a callback function for GetMount(),
+// used to filter out mountinfo entries we're not interested in,
+// and/or stop further processing if we found what we wanted.
+//
+// It takes a pointer to the Info struct (not fully populated,
+// currently only Mountpoint, Fstype, Source, and (on Linux)
+// VfsOpts are filled in), and returns two booleans:
+//
+// - skip: true if the entry should be skipped
+// - stop: true if parsing should be stopped after the entry
+type FilterFunc func(*Info) (skip, stop bool)
+
+// PrefixFilter discards all entries whose mount points
+// do not start with a specific prefix
+func PrefixFilter(prefix string) FilterFunc {
+ return func(m *Info) (bool, bool) {
+ skip := !strings.HasPrefix(m.Mountpoint, prefix)
+ return skip, false
+ }
+}
+
+// SingleEntryFilter looks for a specific entry
+func SingleEntryFilter(mp string) FilterFunc {
+ return func(m *Info) (bool, bool) {
+ if m.Mountpoint == mp {
+ return false, true // don't skip, stop now
+ }
+ return true, false // skip, keep going
+ }
+}
+
+// ParentsFilter returns all entries whose mount points
+// can be parents of a path specified, discarding others.
+//
+// For example, given `/var/lib/docker/something`, entries
+// like `/var/lib/docker`, `/var` and `/` are returned.
+func ParentsFilter(path string) FilterFunc {
+ return func(m *Info) (bool, bool) {
+ skip := !strings.HasPrefix(path, m.Mountpoint)
+ return skip, false
+ }
+}
+
+// FstypeFilter returns all entries that match provided fstype(s).
+func FstypeFilter(fstype ...string) FilterFunc {
+ return func(m *Info) (bool, bool) {
+ for _, t := range fstype {
+ if m.Fstype == t {
+ return false, false // don't skeep, keep going
+ }
+ }
+ return true, false // skip, keep going
+ }
+}
diff --git a/vendor/github.com/containers/storage/pkg/mount/mountinfo_freebsd.go b/vendor/github.com/moby/sys/mountinfo/mountinfo_freebsd.go
index 4f32edcd9..a7dbb1b46 100644
--- a/vendor/github.com/containers/storage/pkg/mount/mountinfo_freebsd.go
+++ b/vendor/github.com/moby/sys/mountinfo/mountinfo_freebsd.go
@@ -1,4 +1,4 @@
-package mount
+package mountinfo
/*
#include <sys/param.h>
@@ -13,9 +13,8 @@ import (
"unsafe"
)
-// Parse /proc/self/mountinfo because comparing Dev and ino does not work from
-// bind mounts.
-func parseMountTable() ([]*Info, error) {
+// parseMountTable returns information about mounted filesystems
+func parseMountTable(filter FilterFunc) ([]*Info, error) {
var rawEntries *C.struct_statfs
count := int(C.getmntinfo(&rawEntries, C.MNT_WAIT))
@@ -32,10 +31,23 @@ func parseMountTable() ([]*Info, error) {
var out []*Info
for _, entry := range entries {
var mountinfo Info
+ var skip, stop bool
mountinfo.Mountpoint = C.GoString(&entry.f_mntonname[0])
- mountinfo.Source = C.GoString(&entry.f_mntfromname[0])
mountinfo.Fstype = C.GoString(&entry.f_fstypename[0])
+ mountinfo.Source = C.GoString(&entry.f_mntfromname[0])
+
+ if filter != nil {
+ // filter out entries we're not interested in
+ skip, stop = filter(&mountinfo)
+ if skip {
+ continue
+ }
+ }
+
out = append(out, &mountinfo)
+ if stop {
+ break
+ }
}
return out, nil
}
diff --git a/vendor/github.com/moby/sys/mountinfo/mountinfo_linux.go b/vendor/github.com/moby/sys/mountinfo/mountinfo_linux.go
new file mode 100644
index 000000000..2d630c8dc
--- /dev/null
+++ b/vendor/github.com/moby/sys/mountinfo/mountinfo_linux.go
@@ -0,0 +1,152 @@
+// +build go1.13
+
+package mountinfo
+
+import (
+ "bufio"
+ "fmt"
+ "io"
+ "os"
+ "strconv"
+ "strings"
+)
+
+func parseInfoFile(r io.Reader, filter FilterFunc) ([]*Info, error) {
+ s := bufio.NewScanner(r)
+ out := []*Info{}
+ var err error
+ for s.Scan() {
+ if err = s.Err(); err != nil {
+ return nil, err
+ }
+ /*
+ See http://man7.org/linux/man-pages/man5/proc.5.html
+
+ 36 35 98:0 /mnt1 /mnt2 rw,noatime master:1 - ext3 /dev/root rw,errors=continue
+ (1)(2)(3) (4) (5) (6) (7) (8) (9) (10) (11)
+
+ (1) mount ID: unique identifier of the mount (may be reused after umount)
+ (2) parent ID: ID of parent (or of self for the top of the mount tree)
+ (3) major:minor: value of st_dev for files on filesystem
+ (4) root: root of the mount within the filesystem
+ (5) mount point: mount point relative to the process's root
+ (6) mount options: per mount options
+ (7) optional fields: zero or more fields of the form "tag[:value]"
+ (8) separator: marks the end of the optional fields
+ (9) filesystem type: name of filesystem of the form "type[.subtype]"
+ (10) mount source: filesystem specific information or "none"
+ (11) super options: per super block options
+
+ In other words, we have:
+ * 6 mandatory fields (1)..(6)
+ * 0 or more optional fields (7)
+ * a separator field (8)
+ * 3 mandatory fields (9)..(11)
+ */
+
+ text := s.Text()
+ fields := strings.Split(text, " ")
+ numFields := len(fields)
+ if numFields < 10 {
+ // should be at least 10 fields
+ return nil, fmt.Errorf("Parsing '%s' failed: not enough fields (%d)", text, numFields)
+ }
+
+ // separator field
+ sepIdx := numFields - 4
+ // In Linux <= 3.9 mounting a cifs with spaces in a share
+ // name (like "//srv/My Docs") _may_ end up having a space
+ // in the last field of mountinfo (like "unc=//serv/My Docs").
+ // Since kernel 3.10-rc1, cifs option "unc=" is ignored,
+ // so spaces should not appear.
+ //
+ // Check for a separator, and work around the spaces bug
+ for fields[sepIdx] != "-" {
+ sepIdx--
+ if sepIdx == 5 {
+ return nil, fmt.Errorf("Parsing '%s' failed: missing - separator", text)
+ }
+ }
+
+ p := &Info{}
+
+ // Fill in the fields that a filter might check
+ p.Mountpoint, err = strconv.Unquote(`"` + fields[4] + `"`)
+ if err != nil {
+ return nil, fmt.Errorf("Parsing '%s' failed: unable to unquote mount point field: %w", fields[4], err)
+ }
+ p.Fstype = fields[sepIdx+1]
+ p.Source = fields[sepIdx+2]
+ p.VfsOpts = fields[sepIdx+3]
+
+ // Run a filter soon so we can skip parsing/adding entries
+ // the caller is not interested in
+ var skip, stop bool
+ if filter != nil {
+ skip, stop = filter(p)
+ if skip {
+ continue
+ }
+ }
+
+ // Fill in the rest of the fields
+
+ // ignore any numbers parsing errors, as there should not be any
+ p.ID, _ = strconv.Atoi(fields[0])
+ p.Parent, _ = strconv.Atoi(fields[1])
+ mm := strings.Split(fields[2], ":")
+ if len(mm) != 2 {
+ return nil, fmt.Errorf("Parsing '%s' failed: unexpected minor:major pair %s", text, mm)
+ }
+ p.Major, _ = strconv.Atoi(mm[0])
+ p.Minor, _ = strconv.Atoi(mm[1])
+
+ p.Root, err = strconv.Unquote(`"` + fields[3] + `"`)
+ if err != nil {
+ return nil, fmt.Errorf("Parsing '%s' failed: unable to unquote root field: %w", fields[3], err)
+ }
+
+ p.Opts = fields[5]
+
+ // zero or more optional fields
+ switch {
+ case sepIdx == 6:
+ // zero, do nothing
+ case sepIdx == 7:
+ p.Optional = fields[6]
+ default:
+ p.Optional = strings.Join(fields[6:sepIdx-1], " ")
+ }
+
+ out = append(out, p)
+ if stop {
+ break
+ }
+ }
+ return out, nil
+}
+
+// Parse /proc/self/mountinfo because comparing Dev and ino does not work from
+// bind mounts
+func parseMountTable(filter FilterFunc) ([]*Info, error) {
+ f, err := os.Open("/proc/self/mountinfo")
+ if err != nil {
+ return nil, err
+ }
+ defer f.Close()
+
+ return parseInfoFile(f, filter)
+}
+
+// PidMountInfo collects the mounts for a specific process ID. If the process
+// ID is unknown, it is better to use `GetMounts` which will inspect
+// "/proc/self/mountinfo" instead.
+func PidMountInfo(pid int) ([]*Info, error) {
+ f, err := os.Open(fmt.Sprintf("/proc/%d/mountinfo", pid))
+ if err != nil {
+ return nil, err
+ }
+ defer f.Close()
+
+ return parseInfoFile(f, nil)
+}
diff --git a/vendor/github.com/moby/sys/mountinfo/mountinfo_unsupported.go b/vendor/github.com/moby/sys/mountinfo/mountinfo_unsupported.go
new file mode 100644
index 000000000..dc1869211
--- /dev/null
+++ b/vendor/github.com/moby/sys/mountinfo/mountinfo_unsupported.go
@@ -0,0 +1,17 @@
+// +build !windows,!linux,!freebsd freebsd,!cgo
+
+package mountinfo
+
+import (
+ "fmt"
+ "io"
+ "runtime"
+)
+
+func parseMountTable(_ FilterFunc) ([]*Info, error) {
+ return nil, fmt.Errorf("mount.parseMountTable is not implemented on %s/%s", runtime.GOOS, runtime.GOARCH)
+}
+
+func parseInfoFile(_ io.Reader, f FilterFunc) ([]*Info, error) {
+ return parseMountTable(f)
+}
diff --git a/vendor/github.com/moby/sys/mountinfo/mountinfo_windows.go b/vendor/github.com/moby/sys/mountinfo/mountinfo_windows.go
new file mode 100644
index 000000000..69ffdc52b
--- /dev/null
+++ b/vendor/github.com/moby/sys/mountinfo/mountinfo_windows.go
@@ -0,0 +1,12 @@
+package mountinfo
+
+import "io"
+
+func parseMountTable(_ FilterFunc) ([]*Info, error) {
+ // Do NOT return an error!
+ return nil, nil
+}
+
+func parseInfoFile(_ io.Reader, f FilterFunc) ([]*Info, error) {
+ return parseMountTable(f)
+}
diff --git a/vendor/github.com/onsi/ginkgo/CHANGELOG.md b/vendor/github.com/onsi/ginkgo/CHANGELOG.md
index bdf18327e..6092fcb63 100644
--- a/vendor/github.com/onsi/ginkgo/CHANGELOG.md
+++ b/vendor/github.com/onsi/ginkgo/CHANGELOG.md
@@ -1,3 +1,8 @@
+## 1.14.1
+
+### Fixes
+- Discard exported method declaration when running ginkgo bootstrap (#558) [f4b0240]
+
## 1.14.0
### Features
diff --git a/vendor/github.com/onsi/ginkgo/README.md b/vendor/github.com/onsi/ginkgo/README.md
index fab114580..475e04994 100644
--- a/vendor/github.com/onsi/ginkgo/README.md
+++ b/vendor/github.com/onsi/ginkgo/README.md
@@ -80,10 +80,11 @@ Agouti allows you run WebDriver integration tests. Learn more about Agouti [her
You'll need the Go command-line tools. Follow the [installation instructions](https://golang.org/doc/install) if you don't have it installed.
### Global installation
-To install the Ginkgo command line interface into the `$PATH` (actually to `$GOBIN`):
+To install the Ginkgo command line interface:
```bash
go get -u github.com/onsi/ginkgo/ginkgo
```
+Note that this will install it to `$GOBIN`, which will need to be in the `$PATH` (or equivalent). Run `go help install` for more information.
### Go module ["tools package"](https://github.com/golang/go/issues/25922):
Create (or update) a file called `tools/tools.go` with the following contents:
@@ -93,7 +94,7 @@ Create (or update) a file called `tools/tools.go` with the following contents:
package tools
import (
- _ "github.com/onsi/ginkgo"
+ _ "github.com/onsi/ginkgo/ginkgo"
)
// This file imports packages that are used when running go generate, or used
diff --git a/vendor/github.com/onsi/ginkgo/config/config.go b/vendor/github.com/onsi/ginkgo/config/config.go
index 2ae48b804..feef2bcd6 100644
--- a/vendor/github.com/onsi/ginkgo/config/config.go
+++ b/vendor/github.com/onsi/ginkgo/config/config.go
@@ -20,7 +20,7 @@ import (
"fmt"
)
-const VERSION = "1.14.0"
+const VERSION = "1.14.1"
type GinkgoConfigType struct {
RandomSeed int64
diff --git a/vendor/github.com/onsi/ginkgo/ginkgo/nodot/nodot.go b/vendor/github.com/onsi/ginkgo/ginkgo/nodot/nodot.go
index 3f7237c60..c87b72165 100644
--- a/vendor/github.com/onsi/ginkgo/ginkgo/nodot/nodot.go
+++ b/vendor/github.com/onsi/ginkgo/ginkgo/nodot/nodot.go
@@ -186,7 +186,9 @@ func getExportedDeclarationsForFile(path string) ([]string, error) {
declarations = append(declarations, s.Names[0].Name)
}
case *ast.FuncDecl:
- declarations = append(declarations, x.Name.Name)
+ if x.Recv == nil {
+ declarations = append(declarations, x.Name.Name)
+ }
}
}
diff --git a/vendor/modules.txt b/vendor/modules.txt
index d26995f68..30602853c 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -158,7 +158,7 @@ github.com/containers/psgo/internal/dev
github.com/containers/psgo/internal/host
github.com/containers/psgo/internal/proc
github.com/containers/psgo/internal/process
-# github.com/containers/storage v1.23.2
+# github.com/containers/storage v1.23.4
github.com/containers/storage
github.com/containers/storage/drivers
github.com/containers/storage/drivers/aufs
@@ -336,7 +336,7 @@ github.com/klauspost/compress/huff0
github.com/klauspost/compress/snappy
github.com/klauspost/compress/zstd
github.com/klauspost/compress/zstd/internal/xxhash
-# github.com/klauspost/pgzip v1.2.4
+# github.com/klauspost/pgzip v1.2.5
github.com/klauspost/pgzip
# github.com/konsorten/go-windows-terminal-sequences v1.0.3
github.com/konsorten/go-windows-terminal-sequences
@@ -350,6 +350,8 @@ github.com/mattn/go-shellwords
github.com/matttproud/golang_protobuf_extensions/pbutil
# github.com/mistifyio/go-zfs v2.1.1+incompatible
github.com/mistifyio/go-zfs
+# github.com/moby/sys/mountinfo v0.1.3
+github.com/moby/sys/mountinfo
# github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd
github.com/modern-go/concurrent
# github.com/modern-go/reflect2 v1.0.1
@@ -366,7 +368,7 @@ github.com/nxadm/tail/ratelimiter
github.com/nxadm/tail/util
github.com/nxadm/tail/watch
github.com/nxadm/tail/winfile
-# github.com/onsi/ginkgo v1.14.0
+# github.com/onsi/ginkgo v1.14.1
github.com/onsi/ginkgo
github.com/onsi/ginkgo/config
github.com/onsi/ginkgo/extensions/table