diff options
113 files changed, 1126 insertions, 339 deletions
diff --git a/cmd/podman/containers/logs.go b/cmd/podman/containers/logs.go index 00a8d4b52..1548c6c24 100644 --- a/cmd/podman/containers/logs.go +++ b/cmd/podman/containers/logs.go @@ -120,7 +120,7 @@ func logsFlags(cmd *cobra.Command) { func logs(_ *cobra.Command, args []string) error { if logsOptions.SinceRaw != "" { // parse time, error out if something is wrong - since, err := util.ParseInputTime(logsOptions.SinceRaw) + since, err := util.ParseInputTime(logsOptions.SinceRaw, true) if err != nil { return errors.Wrapf(err, "error parsing --since %q", logsOptions.SinceRaw) } @@ -128,7 +128,7 @@ func logs(_ *cobra.Command, args []string) error { } if logsOptions.UntilRaw != "" { // parse time, error out if something is wrong - until, err := util.ParseInputTime(logsOptions.UntilRaw) + until, err := util.ParseInputTime(logsOptions.UntilRaw, false) if err != nil { return errors.Wrapf(err, "error parsing --until %q", logsOptions.UntilRaw) } diff --git a/cmd/podman/generate/kube.go b/cmd/podman/generate/kube.go index b4c9f9146..60b8f0af0 100644 --- a/cmd/podman/generate/kube.go +++ b/cmd/podman/generate/kube.go @@ -2,6 +2,7 @@ package pods import ( "fmt" + "io" "io/ioutil" "os" @@ -61,6 +62,10 @@ func kube(cmd *cobra.Command, args []string) error { if err != nil { return err } + if r, ok := report.Reader.(io.ReadCloser); ok { + defer r.Close() + } + if cmd.Flags().Changed("filename") { if _, err := os.Stat(kubeFile); err == nil { return errors.Errorf("cannot write to %q; file exists", kubeFile) diff --git a/cmd/podman/machine/init.go b/cmd/podman/machine/init.go index f4133dbde..ac0d06a07 100644 --- a/cmd/podman/machine/init.go +++ b/cmd/podman/machine/init.go @@ -34,6 +34,7 @@ func init() { Parent: machineCmd, }) flags := initCmd.Flags() + cfg := registry.PodmanConfig() cpusFlagName := "cpus" flags.Uint64Var( @@ -61,7 +62,7 @@ func init() { _ = initCmd.RegisterFlagCompletionFunc(memoryFlagName, completion.AutocompleteNone) ImagePathFlagName := "image-path" - flags.StringVar(&initOpts.ImagePath, ImagePathFlagName, "", "Path to qcow image") + flags.StringVar(&initOpts.ImagePath, ImagePathFlagName, cfg.Engine.MachineImage, "Path to qcow image") _ = initCmd.RegisterFlagCompletionFunc(ImagePathFlagName, completion.AutocompleteDefault) IgnitionPathFlagName := "ignition-path" diff --git a/cmd/podman/volumes/import.go b/cmd/podman/volumes/import.go new file mode 100644 index 000000000..441bd0fe4 --- /dev/null +++ b/cmd/podman/volumes/import.go @@ -0,0 +1,97 @@ +package volumes + +import ( + "fmt" + "os" + + "github.com/containers/podman/v3/cmd/podman/common" + "github.com/containers/podman/v3/cmd/podman/inspect" + "github.com/containers/podman/v3/cmd/podman/parse" + "github.com/containers/podman/v3/cmd/podman/registry" + "github.com/containers/podman/v3/pkg/domain/entities" + "github.com/containers/podman/v3/utils" + "github.com/pkg/errors" + "github.com/spf13/cobra" +) + +var ( + importDescription = `Imports contents into a podman volume from specified tarball (.tar, .tar.gz, .tgz, .bzip, .tar.xz, .txz).` + importCommand = &cobra.Command{ + Annotations: map[string]string{registry.EngineMode: registry.ABIMode}, + Use: "import VOLUME [SOURCE]", + Short: "Import a tarball contents into a podman volume", + Long: importDescription, + RunE: importVol, + Args: cobra.ExactArgs(2), + ValidArgsFunction: common.AutocompleteVolumes, + Example: `podman volume import my_vol /home/user/import.tar + cat ctr.tar | podman import volume my_vol -`, + } +) + +func init() { + registry.Commands = append(registry.Commands, registry.CliCommand{ + Command: importCommand, + Parent: volumeCmd, + }) +} + +func importVol(cmd *cobra.Command, args []string) error { + var inspectOpts entities.InspectOptions + var tarFile *os.File + containerEngine := registry.ContainerEngine() + ctx := registry.Context() + // create a slice of volumes since inspect expects slice as arg + volumes := []string{args[0]} + tarPath := args[1] + + if tarPath != "-" { + err := parse.ValidateFileName(tarPath) + if err != nil { + return err + } + + // open tar file + tarFile, err = os.Open(tarPath) + if err != nil { + return err + } + } else { + tarFile = os.Stdin + } + + inspectOpts.Type = inspect.VolumeType + volumeData, _, err := containerEngine.VolumeInspect(ctx, volumes, inspectOpts) + if err != nil { + return err + } + if len(volumeData) < 1 { + return errors.New("no volume data found") + } + mountPoint := volumeData[0].VolumeConfigResponse.Mountpoint + driver := volumeData[0].VolumeConfigResponse.Driver + volumeOptions := volumeData[0].VolumeConfigResponse.Options + volumeMountStatus, err := containerEngine.VolumeMounted(ctx, args[0]) + if err != nil { + return err + } + if mountPoint == "" { + return errors.New("volume is not mounted anywhere on host") + } + // Check if volume is using external plugin and export only if volume is mounted + if driver != "" && driver != "local" { + if !volumeMountStatus.Value { + return fmt.Errorf("volume is using a driver %s and volume is not mounted on %s", driver, mountPoint) + } + } + // Check if volume is using `local` driver and has mount options type other than tmpfs + if driver == "local" { + if mountOptionType, ok := volumeOptions["type"]; ok { + if mountOptionType != "tmpfs" && !volumeMountStatus.Value { + return fmt.Errorf("volume is using a driver %s and volume is not mounted on %s", driver, mountPoint) + } + } + } + // dont care if volume is mounted or not we are gonna import everything to mountPoint + return utils.UntarToFileSystem(mountPoint, tarFile, nil) +} diff --git a/docs/source/markdown/podman-machine-init.1.md b/docs/source/markdown/podman-machine-init.1.md index 32aae91c1..740897666 100644 --- a/docs/source/markdown/podman-machine-init.1.md +++ b/docs/source/markdown/podman-machine-init.1.md @@ -39,7 +39,9 @@ do these things manually or handle otherwise. #### **--image-path** -Fully qualified path of the uncompressed image file +Fully qualified path or URL to the VM image. +Can also be set to `testing` or `stable` to pull down default image. +Defaults to `testing`. #### **--memory**, **-m**=*number* diff --git a/docs/source/markdown/podman-volume-export.1.md b/docs/source/markdown/podman-volume-export.1.md index caaa37652..7db1e421d 100644 --- a/docs/source/markdown/podman-volume-export.1.md +++ b/docs/source/markdown/podman-volume-export.1.md @@ -35,4 +35,4 @@ $ podman volume export myvol --output myvol.tar ``` ## SEE ALSO -podman-volume(1) +podman-volume(1), podman-volume-import(1) diff --git a/docs/source/markdown/podman-volume-import.1.md b/docs/source/markdown/podman-volume-import.1.md new file mode 100644 index 000000000..6bb868774 --- /dev/null +++ b/docs/source/markdown/podman-volume-import.1.md @@ -0,0 +1,35 @@ +% podman-volume-import(1) + +## NAME +podman\-volume\-import - Import tarball contents into a podman volume + +## SYNOPSIS +**podman volume import** *volume* [*source*] + +## DESCRIPTION + +**podman volume import** imports the contents of a tarball into the podman volume's mount point. +**podman volume import** can consume piped input when using `-` as source path. + +Note: Following command is not supported by podman-remote. + +**podman volume import VOLUME [SOURCE]** + +#### **--help** + +Print usage statement + +## EXAMPLES + +``` +$ gunzip -c hellow.tar.gz | podman volume import myvol - +``` +``` +$ podman volume import myvol test.tar +``` +``` +$ podman volume export myvol | podman volume import oldmyvol - +``` + +## SEE ALSO +podman-volume(1), podman-volume-export(1) diff --git a/docs/source/markdown/podman-volume-ls.1.md b/docs/source/markdown/podman-volume-ls.1.md index b562aff61..6c80ec152 100644 --- a/docs/source/markdown/podman-volume-ls.1.md +++ b/docs/source/markdown/podman-volume-ls.1.md @@ -18,13 +18,15 @@ flag. Use the **--quiet** flag to print only the volume names. Volumes can be filtered by the following attributes: -- dangling -- driver -- label -- name -- opt -- scope -- until +| **Filter** | **Description** | +| ---------- | ------------------------------------------------------------------------------------- | +| dangling | [Dangling] Matches all volumes not referenced by any containers | +| driver | [Driver] Matches volumes based on their driver | +| label | [Key] or [Key=Value] Label assigned to a volume | +| name | [Name] Volume name (accepts regex) | +| opt | Matches a storage driver options | +| scope | Filters volume by scope | +| until | Only remove volumes created before given timestamp | #### **--format**=*format* diff --git a/docs/source/markdown/podman-volume-prune.1.md b/docs/source/markdown/podman-volume-prune.1.md index b9599c200..cfdfc1a44 100644 --- a/docs/source/markdown/podman-volume-prune.1.md +++ b/docs/source/markdown/podman-volume-prune.1.md @@ -23,8 +23,10 @@ Do not prompt for confirmation. Filter volumes to be pruned. Volumes can be filtered by the following attributes: -- label -- until +| **Filter** | **Description** | +| ---------- | ------------------------------------------------------------------------------------- | +| label | [Key] or [Key=Value] Label assigned to a volume | +| until | Only remove volumes created before given timestamp | #### **--help** diff --git a/docs/source/markdown/podman-volume.1.md b/docs/source/markdown/podman-volume.1.md index 20319ccf7..64b37c28c 100644 --- a/docs/source/markdown/podman-volume.1.md +++ b/docs/source/markdown/podman-volume.1.md @@ -16,6 +16,7 @@ podman volume is a set of subcommands that manage volumes. | create | [podman-volume-create(1)](podman-volume-create.1.md) | Create a new volume. | | exists | [podman-volume-exists(1)](podman-volume-exists.1.md) | Check if the given volume exists. | | export | [podman-volume-export(1)](podman-volume-export.1.md) | Exports volume to external tar. | +| import | [podman-volume-import(1)](podman-volume-import.1.md) | Import tarball contents into a podman volume. | | inspect | [podman-volume-inspect(1)](podman-volume-inspect.1.md) | Get detailed information on one or more volumes. | | ls | [podman-volume-ls(1)](podman-volume-ls.1.md) | List all the available volumes. | | prune | [podman-volume-prune(1)](podman-volume-prune.1.md) | Remove all unused volumes. | diff --git a/docs/source/volume.rst b/docs/source/volume.rst index fb607cc2b..af81f39bc 100644 --- a/docs/source/volume.rst +++ b/docs/source/volume.rst @@ -6,6 +6,8 @@ Volume :doc:`export <markdown/podman-volume-export.1>` Exports volume to external tar +:doc:`import <markdown/podman-volume-import.1>` Import tarball contents into a podman volume + :doc:`inspect <markdown/podman-volume-inspect.1>` Display detailed information on one or more volumes :doc:`ls <markdown/podman-volume-ls.1>` List volumes @@ -12,7 +12,7 @@ require ( github.com/containernetworking/cni v0.8.1 github.com/containernetworking/plugins v0.9.1 github.com/containers/buildah v1.22.3 - github.com/containers/common v0.42.1 + github.com/containers/common v0.43.2 github.com/containers/conmon v2.0.20+incompatible github.com/containers/image/v5 v5.15.2 github.com/containers/ocicrypt v1.1.2 @@ -30,7 +30,7 @@ require ( github.com/docker/go-plugins-helpers v0.0.0-20200102110956-c9a8a2d92ccc github.com/docker/go-units v0.4.0 github.com/dtylman/scp v0.0.0-20181017070807-f3000a34aef4 - github.com/fsnotify/fsnotify v1.4.9 + github.com/fsnotify/fsnotify v1.5.1 github.com/ghodss/yaml v1.0.0 github.com/godbus/dbus/v5 v5.0.4 github.com/google/shlex v0.0.0-20181106134648-c34317bd91bf @@ -65,7 +65,7 @@ require ( go.etcd.io/bbolt v1.3.6 golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a golang.org/x/sync v0.0.0-20210220032951-036812b2e83c - golang.org/x/sys v0.0.0-20210616094352-59db8d763f22 + golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b k8s.io/api v0.22.1 k8s.io/apimachinery v0.22.1 @@ -240,11 +240,13 @@ github.com/containernetworking/plugins v0.9.1 h1:FD1tADPls2EEi3flPc2OegIY1M9pUa9 github.com/containernetworking/plugins v0.9.1/go.mod h1:xP/idU2ldlzN6m4p5LmGiwRDjeJr6FLK6vuiUwoH7P8= github.com/containers/buildah v1.22.3 h1:RomxwUa24jMcqzXQetpw4wGMfNlNZLhc9qwyoWHblwc= github.com/containers/buildah v1.22.3/go.mod h1:JVXRyx5Rkp5w5jwvaXe45kuHtyoxpERMjXrR45+3Wfg= -github.com/containers/common v0.42.1 h1:ADOZrVAS8ZY5hBAvr/GoRoPv5Z7TBkxWgxQEXQjlqac= github.com/containers/common v0.42.1/go.mod h1:AaF3ipZfgezsctDuhzLkq4Vl+LkEy7J74ikh2HSXDsg= +github.com/containers/common v0.43.2 h1:oSP5d5sDrq7OkoqLPVrLpi1LZOAwpTwOZXgPDHfmD0E= +github.com/containers/common v0.43.2/go.mod h1:BAoVyRYlxKZKAYpHcFMdrXlIZyzbJp9NwKTgadTd/Dg= github.com/containers/conmon v2.0.20+incompatible h1:YbCVSFSCqFjjVwHTPINGdMX1F6JXHGTUje2ZYobNrkg= github.com/containers/conmon v2.0.20+incompatible/go.mod h1:hgwZ2mtuDrppv78a/cOBNiCm6O0UMWGx1mu7P00nu5I= github.com/containers/image/v5 v5.14.0/go.mod h1:SxiBKOcKuT+4yTjD0AskjO+UwFvNcVOJ9qlAw1HNSPU= +github.com/containers/image/v5 v5.15.0/go.mod h1:gzdBcooi6AFdiqfzirUqv90hUyHyI0MMdaqKzACKr2s= github.com/containers/image/v5 v5.15.2 h1:DKicmVr0h1HGkzs9muoErX+fVbV9sV9W5TyMy5perLE= github.com/containers/image/v5 v5.15.2/go.mod h1:8jejVSzTDfyPwr/HXp9rri34n/vbdavYk6IzTiB3TBw= github.com/containers/libtrust v0.0.0-20190913040956-14b96171aa3b h1:Q8ePgVfHDplZ7U33NwHZkrVELsZP5fYj9pM5WBZB2GE= @@ -258,7 +260,9 @@ github.com/containers/psgo v1.5.2 h1:3aoozst/GIwsrr/5jnFy3FrJay98uujPCu9lTuSZ/Cw github.com/containers/psgo v1.5.2/go.mod h1:2ubh0SsreMZjSXW1Hif58JrEcFudQyIy9EzPUWfawVU= github.com/containers/storage v1.23.5/go.mod h1:ha26Q6ngehFNhf3AWoXldvAvwI4jFe3ETQAf/CeZPyM= github.com/containers/storage v1.32.6/go.mod h1:mdB+b89p+jU8zpzLTVXA0gWMmIo0WrkfGMh1R8O2IQw= +github.com/containers/storage v1.33.0/go.mod h1:FUZPF4nJijX8ixdhByZJXf02cvbyLi6dyDwXdIe8QVY= github.com/containers/storage v1.33.1/go.mod h1:FUZPF4nJijX8ixdhByZJXf02cvbyLi6dyDwXdIe8QVY= +github.com/containers/storage v1.34.0/go.mod h1:t6I+hTgPU0/tVxQ75vw406wDi/TXwYBqZp4QZV9N7b8= github.com/containers/storage v1.34.1 h1:PsBGMH7hwuQ3MOr7qTgPznFrE8ebfIbwQbg2gKvg0lE= github.com/containers/storage v1.34.1/go.mod h1:FY2TcbfgCLMU4lYoKnlZeZXeH353TOTbpDEA+sAcqAY= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= @@ -362,8 +366,9 @@ github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5Kwzbycv github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/fsnotify/fsnotify v1.5.1 h1:mZcQUHVQUQWoPXXtuf9yuEXKudkV2sx1E06UadKWpgI= +github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU= github.com/fsouza/go-dockerclient v1.7.3 h1:i6iMcktl688vsKUEExA6gU1UjPgIvmGtJeQ0mbuFqZo= github.com/fsouza/go-dockerclient v1.7.3/go.mod h1:8xfZB8o9SptLNJ13VoV5pMiRbZGWkU/Omu5VOu/KC9Y= github.com/fullsailor/pkcs7 v0.0.0-20190404230743-d7302db945fa/go.mod h1:KnogPXtdwXqoenmZCw6S+25EAm2MkxbG0deNDu4cbSA= @@ -582,6 +587,7 @@ github.com/klauspost/compress v1.11.0/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYs github.com/klauspost/compress v1.11.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.11.13/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.13.1/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= +github.com/klauspost/compress v1.13.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/klauspost/compress v1.13.4 h1:0zhec2I8zGnjWcKyLl6i3gPqKANCCn5e9xmviEEeX6s= github.com/klauspost/compress v1.13.4/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/klauspost/pgzip v1.2.5 h1:qnWYvvKqedOF2ulHpMG72XQol4ILEJ8k2wwRl/Km8oE= @@ -713,6 +719,7 @@ github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1y github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc= github.com/onsi/gomega v1.10.5/go.mod h1:gza4q3jKQJijlu05nKWRCW/GavJumGt8aNRxWg7mt48= github.com/onsi/gomega v1.14.0/go.mod h1:cIuvLEne0aoVhAgh/O6ac0Op8WWw9H6eYCriF+tEHG0= +github.com/onsi/gomega v1.15.0/go.mod h1:cIuvLEne0aoVhAgh/O6ac0Op8WWw9H6eYCriF+tEHG0= github.com/onsi/gomega v1.16.0 h1:6gjqkI8iiRHMvdccRJM8rVKjCWk6ZIm6FTm3ddIe4/c= github.com/onsi/gomega v1.16.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= @@ -751,6 +758,7 @@ github.com/opencontainers/selinux v1.5.1/go.mod h1:yTcKuYAh6R95iDpefGLQaPaRwJFwy github.com/opencontainers/selinux v1.6.0/go.mod h1:VVGKuOLlE7v4PJyT6h7mNWvq1rzqiriPsEqVhc+svHE= github.com/opencontainers/selinux v1.8.0/go.mod h1:RScLhm78qiWa2gbVCcGkC7tCGdgk3ogry1nUQF8Evvo= github.com/opencontainers/selinux v1.8.2/go.mod h1:MUIHuUEvKB1wtJjQdOyYRgOnLD2xAPP8dBsCoU0KuF8= +github.com/opencontainers/selinux v1.8.3/go.mod h1:HTvjPFoGMbpQsG886e3lQwnsRWtE4TC1OF3OUvG9FAo= github.com/opencontainers/selinux v1.8.4 h1:krlgQ6/j9CkCXT5oW0yVXdQFOME3NjKuuAZXuR6O7P4= github.com/opencontainers/selinux v1.8.4/go.mod h1:HTvjPFoGMbpQsG886e3lQwnsRWtE4TC1OF3OUvG9FAo= github.com/openshift/imagebuilder v1.2.2-0.20210415181909-87f3e48c2656 h1:WaxyNFpmIDu4i6so9r6LVFIbSaXqsj8oitMitt86ae4= @@ -1188,8 +1196,9 @@ golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210616094352-59db8d763f22 h1:RqytpXGR1iVNX7psjB3ff8y7sNFinVFvkx1c8SjBkio= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c h1:F1jZWGFhYfh0Ci55sIpILtKKK8p3i2/krTr0H1rg74I= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201113234701-d7a72108b828/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= diff --git a/libpod/container_commit.go b/libpod/container_commit.go index c1dd42942..87e5d511c 100644 --- a/libpod/container_commit.go +++ b/libpod/container_commit.go @@ -99,6 +99,11 @@ func (c *Container) Commit(ctx context.Context, destImage string, options Contai for _, p := range c.config.PortMappings { importBuilder.SetPort(fmt.Sprintf("%d/%s", p.ContainerPort, p.Protocol)) } + for port, protocols := range c.config.ExposedPorts { + for _, protocol := range protocols { + importBuilder.SetPort(fmt.Sprintf("%d/%s", port, protocol)) + } + } // Labels for k, v := range c.Labels() { importBuilder.SetLabel(k, v) diff --git a/libpod/container_config.go b/libpod/container_config.go index e15030c15..b80b23c25 100644 --- a/libpod/container_config.go +++ b/libpod/container_config.go @@ -229,6 +229,12 @@ type ContainerNetworkConfig struct { // namespace // These are not used unless CreateNetNS is true PortMappings []ocicni.PortMapping `json:"portMappings,omitempty"` + // ExposedPorts are the ports which are exposed but not forwarded + // into the container. + // The map key is the port and the string slice contains the protocols, + // e.g. tcp and udp + // These are only set when exposed ports are given but not published. + ExposedPorts map[uint16][]string `json:"exposedPorts,omitempty"` // UseImageResolvConf indicates that resolv.conf should not be // bind-mounted inside the container. // Conflicts with DNSServer, DNSSearch, DNSOption. diff --git a/libpod/container_inspect.go b/libpod/container_inspect.go index 8c662c488..97318a2e8 100644 --- a/libpod/container_inspect.go +++ b/libpod/container_inspect.go @@ -624,7 +624,7 @@ func (c *Container) generateInspectContainerHostConfig(ctrSpec *spec.Spec, named // Port bindings. // Only populate if we're using CNI to configure the network. if c.config.CreateNetNS { - hostConfig.PortBindings = makeInspectPortBindings(c.config.PortMappings) + hostConfig.PortBindings = makeInspectPortBindings(c.config.PortMappings, c.config.ExposedPorts) } else { hostConfig.PortBindings = make(map[string][]define.InspectHostPort) } diff --git a/libpod/container_log_linux.go b/libpod/container_log_linux.go index 4eb600bfe..ca1e11ef5 100644 --- a/libpod/container_log_linux.go +++ b/libpod/container_log_linux.go @@ -12,6 +12,7 @@ import ( "github.com/containers/podman/v3/libpod/define" "github.com/containers/podman/v3/libpod/events" "github.com/containers/podman/v3/libpod/logs" + "github.com/coreos/go-systemd/v22/journal" "github.com/coreos/go-systemd/v22/sdjournal" "github.com/pkg/errors" "github.com/sirupsen/logrus" @@ -29,6 +30,19 @@ func init() { logDrivers = append(logDrivers, define.JournaldLogging) } +// initializeJournal will write an empty string to the journal +// when a journal is created. This solves a problem when people +// attempt to read logs from a container that has never had stdout/stderr +func (c *Container) initializeJournal(ctx context.Context) error { + m := make(map[string]string) + m["SYSLOG_IDENTIFIER"] = "podman" + m["PODMAN_ID"] = c.ID() + m["CONTAINER_ID_FULL"] = c.ID() + history := events.History + m["PODMAN_EVENT"] = history.String() + return journal.Send("", journal.PriInfo, m) +} + func (c *Container) readFromJournal(ctx context.Context, options *logs.LogOptions, logChannel chan *logs.LogLine) error { journal, err := sdjournal.NewJournal() if err != nil { @@ -63,12 +77,12 @@ func (c *Container) readFromJournal(ctx context.Context, options *logs.LogOption } // API requires Next() immediately after SeekHead(). if _, err := journal.Next(); err != nil { - return errors.Wrap(err, "initial journal cursor") + return errors.Wrap(err, "next journal") } // API requires a next|prev before getting a cursor. if _, err := journal.Previous(); err != nil { - return errors.Wrap(err, "initial journal cursor") + return errors.Wrap(err, "previous journal") } // Note that the initial cursor may not yet be ready, so we'll do an @@ -77,10 +91,10 @@ func (c *Container) readFromJournal(ctx context.Context, options *logs.LogOption var cursorError error for i := 1; i <= 3; i++ { cursor, cursorError = journal.GetCursor() - if err != nil { + if cursorError != nil { + time.Sleep(time.Duration(i*100) * time.Millisecond) continue } - time.Sleep(time.Duration(i*100) * time.Millisecond) break } if cursorError != nil { @@ -104,6 +118,7 @@ func (c *Container) readFromJournal(ctx context.Context, options *logs.LogOption tailQueue := []*logs.LogLine{} // needed for options.Tail doTail := options.Tail > 0 + lastReadCursor := "" for { select { case <-ctx.Done(): @@ -113,18 +128,25 @@ func (c *Container) readFromJournal(ctx context.Context, options *logs.LogOption // Fallthrough } - if _, err := journal.Next(); err != nil { - logrus.Errorf("Failed to move journal cursor to next entry: %v", err) - return + if lastReadCursor != "" { + // Advance to next entry if we read this one. + if _, err := journal.Next(); err != nil { + logrus.Errorf("Failed to move journal cursor to next entry: %v", err) + return + } } - latestCursor, err := journal.GetCursor() + + // Fetch the location of this entry, presumably either + // the one that follows the last one we read, or that + // same last one, if there is no next entry (yet). + cursor, err = journal.GetCursor() if err != nil { logrus.Errorf("Failed to get journal cursor: %v", err) return } - // Hit the end of the journal. - if cursor == latestCursor { + // Hit the end of the journal (so far?). + if cursor == lastReadCursor { if doTail { // Flush *once* we hit the end of the journal. startIndex := int64(len(tailQueue)-1) - options.Tail @@ -145,8 +167,9 @@ func (c *Container) readFromJournal(ctx context.Context, options *logs.LogOption journal.Wait(sdjournal.IndefiniteWait) continue } - cursor = latestCursor + lastReadCursor = cursor + // Read the journal entry. entry, err := journal.GetEntry() if err != nil { logrus.Errorf("Failed to get journal entry: %v", err) diff --git a/libpod/container_log_unsupported.go b/libpod/container_log_unsupported.go index d10082141..a551df942 100644 --- a/libpod/container_log_unsupported.go +++ b/libpod/container_log_unsupported.go @@ -13,3 +13,7 @@ import ( func (c *Container) readFromJournal(_ context.Context, _ *logs.LogOptions, _ chan *logs.LogLine) error { return errors.Wrapf(define.ErrOSNotSupported, "Journald logging only enabled with systemd on linux") } + +func (c *Container) initializeJournal(ctx context.Context) error { + return errors.Wrapf(define.ErrOSNotSupported, "Journald logging only enabled with systemd on linux") +} diff --git a/libpod/events/filters.go b/libpod/events/filters.go index 4d27e8fc4..d5e2b81f3 100644 --- a/libpod/events/filters.go +++ b/libpod/events/filters.go @@ -135,7 +135,7 @@ func generateEventFilters(filters []string, since, until string) (map[string][]E } if len(since) > 0 { - timeSince, err := util.ParseInputTime(since) + timeSince, err := util.ParseInputTime(since, true) if err != nil { return nil, errors.Wrapf(err, "unable to convert since time of %s", since) } @@ -144,7 +144,7 @@ func generateEventFilters(filters []string, since, until string) (map[string][]E } if len(until) > 0 { - timeUntil, err := util.ParseInputTime(until) + timeUntil, err := util.ParseInputTime(until, false) if err != nil { return nil, errors.Wrapf(err, "unable to convert until time of %s", until) } diff --git a/libpod/events/journal_linux.go b/libpod/events/journal_linux.go index 7006290e9..a3e0d9754 100644 --- a/libpod/events/journal_linux.go +++ b/libpod/events/journal_linux.go @@ -73,13 +73,15 @@ func (e EventJournalD) Read(ctx context.Context, options ReadOptions) error { if err != nil { return errors.Wrapf(err, "failed to parse event filters") } + var untilTime time.Time if len(options.Until) > 0 { - untilTime, err = util.ParseInputTime(options.Until) + untilTime, err = util.ParseInputTime(options.Until, false) if err != nil { return err } } + j, err := sdjournal.NewJournal() if err != nil { return err diff --git a/libpod/events/logfile.go b/libpod/events/logfile.go index 952444f2b..e3f0ab8f0 100644 --- a/libpod/events/logfile.go +++ b/libpod/events/logfile.go @@ -53,7 +53,7 @@ func (e EventLogFile) Read(ctx context.Context, options ReadOptions) error { return err } if len(options.Until) > 0 { - untilTime, err := util.ParseInputTime(options.Until) + untilTime, err := util.ParseInputTime(options.Until, false) if err != nil { return err } diff --git a/libpod/logs/log.go b/libpod/logs/log.go index 1a0223edc..a584de0ee 100644 --- a/libpod/logs/log.go +++ b/libpod/logs/log.go @@ -251,11 +251,19 @@ func (l *LogLine) Write(stdout io.Writer, stderr io.Writer, logOpts *LogOptions) switch l.Device { case "stdout": if stdout != nil { - fmt.Fprintln(stdout, l.String(logOpts)) + if l.Partial() { + fmt.Fprint(stdout, l.String(logOpts)) + } else { + fmt.Fprintln(stdout, l.String(logOpts)) + } } case "stderr": if stderr != nil { - fmt.Fprintln(stderr, l.String(logOpts)) + if l.Partial() { + fmt.Fprint(stderr, l.String(logOpts)) + } else { + fmt.Fprintln(stderr, l.String(logOpts)) + } } default: // Warn the user if the device type does not match. Most likely the file is corrupted. diff --git a/libpod/networking_linux.go b/libpod/networking_linux.go index 2ed2bb01b..dbe2274d3 100644 --- a/libpod/networking_linux.go +++ b/libpod/networking_linux.go @@ -1015,7 +1015,7 @@ func (c *Container) getContainerNetworkInfo() (*define.InspectNetworkSettings, e } settings := new(define.InspectNetworkSettings) - settings.Ports = makeInspectPortBindings(c.config.PortMappings) + settings.Ports = makeInspectPortBindings(c.config.PortMappings, c.config.ExposedPorts) networks, isDefault, err := c.networks() if err != nil { diff --git a/libpod/oci_conmon_linux.go b/libpod/oci_conmon_linux.go index ff25be234..c14911980 100644 --- a/libpod/oci_conmon_linux.go +++ b/libpod/oci_conmon_linux.go @@ -625,9 +625,11 @@ func (r *ConmonOCIRuntime) HTTPAttach(ctr *Container, req *http.Request, w http. if err != nil { break } - _, err = httpBuf.Write([]byte("\n")) - if err != nil { - break + if !logLine.Partial() { + _, err = httpBuf.Write([]byte("\n")) + if err != nil { + break + } } err = httpBuf.Flush() if err != nil { diff --git a/libpod/options.go b/libpod/options.go index 59aec66c6..0bcd1e3a6 100644 --- a/libpod/options.go +++ b/libpod/options.go @@ -1041,7 +1041,7 @@ func WithDependencyCtrs(ctrs []*Container) CtrCreateOption { // namespace with a minimal configuration. // An optional array of port mappings can be provided. // Conflicts with WithNetNSFrom(). -func WithNetNS(portMappings []ocicni.PortMapping, postConfigureNetNS bool, netmode string, networks []string) CtrCreateOption { +func WithNetNS(portMappings []ocicni.PortMapping, exposedPorts map[uint16][]string, postConfigureNetNS bool, netmode string, networks []string) CtrCreateOption { return func(ctr *Container) error { if ctr.valid { return define.ErrCtrFinalized @@ -1051,6 +1051,7 @@ func WithNetNS(portMappings []ocicni.PortMapping, postConfigureNetNS bool, netmo ctr.config.NetMode = namespaces.NetworkMode(netmode) ctr.config.CreateNetNS = true ctr.config.PortMappings = portMappings + ctr.config.ExposedPorts = exposedPorts ctr.config.Networks = networks diff --git a/libpod/pod_api.go b/libpod/pod_api.go index 716eb2e5b..53fb9538f 100644 --- a/libpod/pod_api.go +++ b/libpod/pod_api.go @@ -616,7 +616,7 @@ func (p *Pod) Inspect() (*define.InspectPodData, error) { infraConfig.Networks = append(infraConfig.Networks, p.config.InfraContainer.Networks...) } infraConfig.NetworkOptions = p.config.InfraContainer.NetworkOptions - infraConfig.PortBindings = makeInspectPortBindings(p.config.InfraContainer.PortBindings) + infraConfig.PortBindings = makeInspectPortBindings(p.config.InfraContainer.PortBindings, nil) } inspectData := define.InspectPodData{ diff --git a/libpod/runtime_ctr.go b/libpod/runtime_ctr.go index 02bbb6981..52072b0f3 100644 --- a/libpod/runtime_ctr.go +++ b/libpod/runtime_ctr.go @@ -462,8 +462,15 @@ func (r *Runtime) setupContainer(ctx context.Context, ctr *Container) (_ *Contai ctrNamedVolumes = append(ctrNamedVolumes, newVol) } - if ctr.config.LogPath == "" && ctr.config.LogDriver != define.JournaldLogging && ctr.config.LogDriver != define.NoLogging { - ctr.config.LogPath = filepath.Join(ctr.config.StaticDir, "ctr.log") + switch ctr.config.LogDriver { + case define.NoLogging: + break + case define.JournaldLogging: + ctr.initializeJournal(ctx) + default: + if ctr.config.LogPath == "" { + ctr.config.LogPath = filepath.Join(ctr.config.StaticDir, "ctr.log") + } } if !MountExists(ctr.config.Spec.Mounts, "/dev/shm") && ctr.config.ShmDir == "" { diff --git a/libpod/runtime_pod_infra_linux.go b/libpod/runtime_pod_infra_linux.go index 49213032e..9236fb1f5 100644 --- a/libpod/runtime_pod_infra_linux.go +++ b/libpod/runtime_pod_infra_linux.go @@ -112,7 +112,8 @@ func (r *Runtime) makeInfraContainer(ctx context.Context, p *Pod, imgName, rawIm options = append(options, WithNetworkOptions(p.config.InfraContainer.NetworkOptions)) } } - options = append(options, WithNetNS(p.config.InfraContainer.PortBindings, !p.config.InfraContainer.Userns.IsHost(), netmode, p.config.InfraContainer.Networks)) + // FIXME allow pods to have exposed ports + options = append(options, WithNetNS(p.config.InfraContainer.PortBindings, nil, !p.config.InfraContainer.Userns.IsHost(), netmode, p.config.InfraContainer.Networks)) } // For each option in InfraContainerConfig - if set, pass into diff --git a/libpod/util.go b/libpod/util.go index 3b32fb264..ed5c4e6c6 100644 --- a/libpod/util.go +++ b/libpod/util.go @@ -295,8 +295,8 @@ func writeHijackHeader(r *http.Request, conn io.Writer) { } // Convert OCICNI port bindings into Inspect-formatted port bindings. -func makeInspectPortBindings(bindings []ocicni.PortMapping) map[string][]define.InspectHostPort { - portBindings := make(map[string][]define.InspectHostPort) +func makeInspectPortBindings(bindings []ocicni.PortMapping, expose map[uint16][]string) map[string][]define.InspectHostPort { + portBindings := make(map[string][]define.InspectHostPort, len(bindings)) for _, port := range bindings { key := fmt.Sprintf("%d/%s", port.ContainerPort, port.Protocol) hostPorts := portBindings[key] @@ -309,6 +309,15 @@ func makeInspectPortBindings(bindings []ocicni.PortMapping) map[string][]define. }) portBindings[key] = hostPorts } + // add exposed ports without host port information to match docker + for port, protocols := range expose { + for _, protocol := range protocols { + key := fmt.Sprintf("%d/%s", port, protocol) + if _, ok := portBindings[key]; !ok { + portBindings[key] = nil + } + } + } return portBindings } diff --git a/pkg/api/handlers/compat/containers_logs.go b/pkg/api/handlers/compat/containers_logs.go index 656e2c627..a7cfe09ea 100644 --- a/pkg/api/handlers/compat/containers_logs.go +++ b/pkg/api/handlers/compat/containers_logs.go @@ -63,7 +63,7 @@ func LogsFromContainer(w http.ResponseWriter, r *http.Request) { var since time.Time if _, found := r.URL.Query()["since"]; found { - since, err = util.ParseInputTime(query.Since) + since, err = util.ParseInputTime(query.Since, true) if err != nil { utils.BadRequest(w, "since", query.Since, err) return @@ -73,7 +73,7 @@ func LogsFromContainer(w http.ResponseWriter, r *http.Request) { var until time.Time if _, found := r.URL.Query()["until"]; found { if query.Until != "0" { - until, err = util.ParseInputTime(query.Until) + until, err = util.ParseInputTime(query.Until, false) if err != nil { utils.BadRequest(w, "until", query.Until, err) return @@ -152,9 +152,7 @@ func LogsFromContainer(w http.ResponseWriter, r *http.Request) { } frame.WriteString(line.Msg) - // Log lines in the compat layer require adding EOL - // https://github.com/containers/podman/issues/8058 - if !utils.IsLibpodRequest(r) { + if !line.Partial() { frame.WriteString("\n") } diff --git a/pkg/bindings/connection.go b/pkg/bindings/connection.go index cd118cbb2..4127ad2f0 100644 --- a/pkg/bindings/connection.go +++ b/pkg/bindings/connection.go @@ -56,7 +56,7 @@ func NewConnection(ctx context.Context, uri string) (context.Context, error) { return NewConnectionWithIdentity(ctx, uri, "") } -// NewConnection takes a URI as a string and returns a context with the +// NewConnectionWithIdentity takes a URI as a string and returns a context with the // Connection embedded as a value. This context needs to be passed to each // endpoint to work correctly. // @@ -149,6 +149,7 @@ func pingNewConnection(ctx context.Context) error { if err != nil { return err } + defer response.Body.Close() if response.StatusCode == http.StatusOK { versionHdr := response.Header.Get("Libpod-API-Version") @@ -338,7 +339,7 @@ func (c *Connection) DoRequest(httpBody io.Reader, httpMethod, endpoint string, req.Header.Set(key, val) } // Give the Do three chances in the case of a comm/service hiccup - for i := 0; i < 3; i++ { + for i := 1; i <= 3; i++ { response, err = c.Client.Do(req) // nolint if err == nil { break @@ -358,7 +359,7 @@ func FiltersToString(filters map[string][]string) (string, error) { return jsoniter.MarshalToString(lowerCaseKeys) } -// IsInformation returns true if the response code is 1xx +// IsInformational returns true if the response code is 1xx func (h *APIResponse) IsInformational() bool { return h.Response.StatusCode/100 == 1 } diff --git a/pkg/bindings/containers/archive.go b/pkg/bindings/containers/archive.go index 52b73662b..876f5340b 100644 --- a/pkg/bindings/containers/archive.go +++ b/pkg/bindings/containers/archive.go @@ -27,6 +27,7 @@ func Stat(ctx context.Context, nameOrID string, path string) (*entities.Containe if err != nil { return nil, err } + defer response.Body.Close() var finalErr error if response.StatusCode == http.StatusNotFound { @@ -53,7 +54,9 @@ func CopyFromArchive(ctx context.Context, nameOrID string, path string, reader i return CopyFromArchiveWithOptions(ctx, nameOrID, path, reader, nil) } -// CopyFromArchiveWithOptions FIXME: remove this function and make CopyFromArchive accept the option as the last parameter in podman 4.0 +// CopyFromArchiveWithOptions copy files into container +// +// FIXME: remove this function and make CopyFromArchive accept the option as the last parameter in podman 4.0 func CopyFromArchiveWithOptions(ctx context.Context, nameOrID string, path string, reader io.Reader, options *CopyOptions) (entities.ContainerCopyFunc, error) { conn, err := bindings.GetClient(ctx) if err != nil { @@ -72,6 +75,7 @@ func CopyFromArchiveWithOptions(ctx context.Context, nameOrID string, path strin if err != nil { return err } + if response.StatusCode != http.StatusOK { return errors.New(response.Status) } @@ -79,6 +83,7 @@ func CopyFromArchiveWithOptions(ctx context.Context, nameOrID string, path strin }, nil } +// CopyToArchive copy files from container func CopyToArchive(ctx context.Context, nameOrID string, path string, writer io.Writer) (entities.ContainerCopyFunc, error) { conn, err := bindings.GetClient(ctx) if err != nil { @@ -91,11 +96,14 @@ func CopyToArchive(ctx context.Context, nameOrID string, path string, writer io. if err != nil { return nil, err } + if response.StatusCode != http.StatusOK { + defer response.Body.Close() return nil, response.Process(nil) } return func() error { + defer response.Body.Close() _, err := io.Copy(writer, response.Body) return err }, nil diff --git a/pkg/bindings/containers/attach.go b/pkg/bindings/containers/attach.go index 01c14d350..6efbcb57b 100644 --- a/pkg/bindings/containers/attach.go +++ b/pkg/bindings/containers/attach.go @@ -134,7 +134,9 @@ func Attach(ctx context.Context, nameOrID string, stdin io.Reader, stdout io.Wri if err != nil { return err } + if !(response.IsSuccess() || response.IsInformational()) { + defer response.Body.Close() return response.Process(nil) } @@ -207,7 +209,7 @@ func Attach(ctx context.Context, nameOrID string, stdin io.Reader, stdout io.Wri } } } else { - logrus.Debugf("Copying standard streams of container in non-terminal mode") + logrus.Debugf("Copying standard streams of container %q in non-terminal mode", ctnr.ID) for { // Read multiplexed channels and write to appropriate stream fd, l, err := DemuxHeader(socket, buffer) @@ -324,6 +326,8 @@ func resizeTTY(ctx context.Context, endpoint string, height *int, width *int) er if err != nil { return err } + defer rsp.Body.Close() + return rsp.Process(nil) } @@ -407,6 +411,7 @@ func ExecStartAndAttach(ctx context.Context, sessionID string, options *ExecStar if err != nil { return err } + defer resp.Body.Close() respStruct := new(define.InspectExecSession) if err := resp.Process(respStruct); err != nil { @@ -477,6 +482,8 @@ func ExecStartAndAttach(ctx context.Context, sessionID string, options *ExecStar if err != nil { return err } + defer response.Body.Close() + if !(response.IsSuccess() || response.IsInformational()) { return response.Process(nil) } diff --git a/pkg/bindings/containers/checkpoint.go b/pkg/bindings/containers/checkpoint.go index 440bf707d..7f7080f13 100644 --- a/pkg/bindings/containers/checkpoint.go +++ b/pkg/bindings/containers/checkpoint.go @@ -27,6 +27,8 @@ func Checkpoint(ctx context.Context, nameOrID string, options *CheckpointOptions if err != nil { return nil, err } + defer response.Body.Close() + return &report, response.Process(&report) } @@ -54,5 +56,7 @@ func Restore(ctx context.Context, nameOrID string, options *RestoreOptions) (*en if err != nil { return nil, err } + defer response.Body.Close() + return &report, response.Process(&report) } diff --git a/pkg/bindings/containers/commit.go b/pkg/bindings/containers/commit.go index 8ae61322e..a4adebb1f 100644 --- a/pkg/bindings/containers/commit.go +++ b/pkg/bindings/containers/commit.go @@ -28,5 +28,7 @@ func Commit(ctx context.Context, nameOrID string, options *CommitOptions) (handl if err != nil { return id, err } + defer response.Body.Close() + return id, response.Process(&id) } diff --git a/pkg/bindings/containers/containers.go b/pkg/bindings/containers/containers.go index bc7b0c8c9..aafb83f65 100644 --- a/pkg/bindings/containers/containers.go +++ b/pkg/bindings/containers/containers.go @@ -42,6 +42,8 @@ func List(ctx context.Context, options *ListOptions) ([]entities.ListContainer, if err != nil { return containers, err } + defer response.Body.Close() + return containers, response.Process(&containers) } @@ -66,6 +68,8 @@ func Prune(ctx context.Context, options *PruneOptions) ([]*reports.PruneReport, if err != nil { return nil, err } + defer response.Body.Close() + return reports, response.Process(&reports) } @@ -90,6 +94,8 @@ func Remove(ctx context.Context, nameOrID string, options *RemoveOptions) error if err != nil { return err } + defer response.Body.Close() + return response.Process(nil) } @@ -113,6 +119,8 @@ func Inspect(ctx context.Context, nameOrID string, options *InspectOptions) (*de if err != nil { return nil, err } + defer response.Body.Close() + inspect := define.InspectContainerData{} return &inspect, response.Process(&inspect) } @@ -136,6 +144,8 @@ func Kill(ctx context.Context, nameOrID string, options *KillOptions) error { if err != nil { return err } + defer response.Body.Close() + return response.Process(nil) } @@ -154,6 +164,8 @@ func Pause(ctx context.Context, nameOrID string, options *PauseOptions) error { if err != nil { return err } + defer response.Body.Close() + return response.Process(nil) } @@ -176,6 +188,8 @@ func Restart(ctx context.Context, nameOrID string, options *RestartOptions) erro if err != nil { return err } + defer response.Body.Close() + return response.Process(nil) } @@ -199,6 +213,8 @@ func Start(ctx context.Context, nameOrID string, options *StartOptions) error { if err != nil { return err } + defer response.Body.Close() + return response.Process(nil) } @@ -231,6 +247,7 @@ func Stats(ctx context.Context, containers []string, options *StatsOptions) (cha go func() { defer close(statsChan) + defer response.Body.Close() dec := json.NewDecoder(response.Body) doStream := true @@ -245,6 +262,7 @@ func Stats(ctx context.Context, containers []string, options *StatsOptions) (cha default: // fall through and do some work } + var report entities.ContainerStatsReport if err := dec.Decode(&report); err != nil { report = entities.ContainerStatsReport{Error: err} @@ -279,6 +297,7 @@ func Top(ctx context.Context, nameOrID string, options *TopOptions) ([]string, e if err != nil { return nil, err } + defer response.Body.Close() body := handlers.ContainerTopOKBody{} if err = response.Process(&body); err != nil { @@ -311,6 +330,8 @@ func Unpause(ctx context.Context, nameOrID string, options *UnpauseOptions) erro if err != nil { return err } + defer response.Body.Close() + return response.Process(nil) } @@ -334,6 +355,8 @@ func Wait(ctx context.Context, nameOrID string, options *WaitOptions) (int32, er if err != nil { return exitCode, err } + defer response.Body.Close() + return exitCode, response.Process(&exitCode) } @@ -353,6 +376,8 @@ func Exists(ctx context.Context, nameOrID string, options *ExistsOptions) (bool, if err != nil { return false, err } + defer response.Body.Close() + return response.IsSuccess(), nil } @@ -374,6 +399,8 @@ func Stop(ctx context.Context, nameOrID string, options *StopOptions) error { if err != nil { return err } + defer response.Body.Close() + return response.Process(nil) } @@ -393,6 +420,8 @@ func Export(ctx context.Context, nameOrID string, w io.Writer, options *ExportOp if err != nil { return err } + defer response.Body.Close() + if response.StatusCode/100 == 2 { _, err = io.Copy(w, response.Body) return err @@ -416,6 +445,8 @@ func ContainerInit(ctx context.Context, nameOrID string, options *InitOptions) e if err != nil { return err } + defer response.Body.Close() + if response.StatusCode == http.StatusNotModified { return errors.Wrapf(define.ErrCtrStateInvalid, "container %s has already been created in runtime", nameOrID) } @@ -435,5 +466,7 @@ func ShouldRestart(ctx context.Context, nameOrID string, options *ShouldRestartO if err != nil { return false, err } + defer response.Body.Close() + return response.IsSuccess(), nil } diff --git a/pkg/bindings/containers/create.go b/pkg/bindings/containers/create.go index 3efa9643d..c0b9538a6 100644 --- a/pkg/bindings/containers/create.go +++ b/pkg/bindings/containers/create.go @@ -30,5 +30,7 @@ func CreateWithSpec(ctx context.Context, s *specgen.SpecGenerator, options *Crea if err != nil { return ccr, err } + defer response.Body.Close() + return ccr, response.Process(&ccr) } diff --git a/pkg/bindings/containers/diff.go b/pkg/bindings/containers/diff.go index 7d20ae530..e4ec49809 100644 --- a/pkg/bindings/containers/diff.go +++ b/pkg/bindings/containers/diff.go @@ -26,6 +26,8 @@ func Diff(ctx context.Context, nameOrID string, options *DiffOptions) ([]archive if err != nil { return nil, err } + defer response.Body.Close() + var changes []archive.Change return changes, response.Process(&changes) } diff --git a/pkg/bindings/containers/exec.go b/pkg/bindings/containers/exec.go index 5ae6d1d71..12b31aba3 100644 --- a/pkg/bindings/containers/exec.go +++ b/pkg/bindings/containers/exec.go @@ -39,6 +39,7 @@ func ExecCreate(ctx context.Context, nameOrID string, config *handlers.ExecCreat if err != nil { return "", err } + defer resp.Body.Close() respStruct := new(handlers.ExecCreateResponse) if err := resp.Process(respStruct); err != nil { @@ -66,6 +67,7 @@ func ExecInspect(ctx context.Context, sessionID string, options *ExecInspectOpti if err != nil { return nil, err } + defer resp.Body.Close() respStruct := new(define.InspectExecSession) if err := resp.Process(respStruct); err != nil { @@ -103,6 +105,7 @@ func ExecStart(ctx context.Context, sessionID string, options *ExecStartOptions) if err != nil { return err } + defer resp.Body.Close() return resp.Process(nil) } diff --git a/pkg/bindings/containers/healthcheck.go b/pkg/bindings/containers/healthcheck.go index d6b721615..0e65a5a46 100644 --- a/pkg/bindings/containers/healthcheck.go +++ b/pkg/bindings/containers/healthcheck.go @@ -26,5 +26,7 @@ func RunHealthCheck(ctx context.Context, nameOrID string, options *HealthCheckOp if err != nil { return nil, err } + defer response.Body.Close() + return &status, response.Process(&status) } diff --git a/pkg/bindings/containers/logs.go b/pkg/bindings/containers/logs.go index a3100c697..67db94487 100644 --- a/pkg/bindings/containers/logs.go +++ b/pkg/bindings/containers/logs.go @@ -33,6 +33,7 @@ func Logs(ctx context.Context, nameOrID string, options *LogOptions, stdoutChan, if err != nil { return err } + defer response.Body.Close() buffer := make([]byte, 1024) for { diff --git a/pkg/bindings/containers/mount.go b/pkg/bindings/containers/mount.go index bb5c3bd67..c07998fd3 100644 --- a/pkg/bindings/containers/mount.go +++ b/pkg/bindings/containers/mount.go @@ -25,6 +25,8 @@ func Mount(ctx context.Context, nameOrID string, options *MountOptions) (string, if err != nil { return path, err } + defer response.Body.Close() + return path, response.Process(&path) } @@ -43,6 +45,8 @@ func Unmount(ctx context.Context, nameOrID string, options *UnmountOptions) erro if err != nil { return err } + defer response.Body.Close() + return response.Process(nil) } @@ -61,5 +65,7 @@ func GetMountedContainerPaths(ctx context.Context, options *MountedContainerPath if err != nil { return mounts, err } + defer response.Body.Close() + return mounts, response.Process(&mounts) } diff --git a/pkg/bindings/containers/rename.go b/pkg/bindings/containers/rename.go index 60d7fda73..172d7838a 100644 --- a/pkg/bindings/containers/rename.go +++ b/pkg/bindings/containers/rename.go @@ -24,5 +24,7 @@ func Rename(ctx context.Context, nameOrID string, options *RenameOptions) error if err != nil { return err } + defer response.Body.Close() + return response.Process(nil) } diff --git a/pkg/bindings/errors.go b/pkg/bindings/errors.go index 3339062a5..9c311d912 100644 --- a/pkg/bindings/errors.go +++ b/pkg/bindings/errors.go @@ -20,6 +20,8 @@ func handleError(data []byte) error { return e } +// Process drains the response body, and processes the HTTP status code +// Note: Closing the response.Body is left to the caller func (h APIResponse) Process(unmarshalInto interface{}) error { data, err := ioutil.ReadAll(h.Response.Body) if err != nil { diff --git a/pkg/bindings/generate/generate.go b/pkg/bindings/generate/generate.go index 7c904a6a8..742956515 100644 --- a/pkg/bindings/generate/generate.go +++ b/pkg/bindings/generate/generate.go @@ -26,10 +26,15 @@ func Systemd(ctx context.Context, nameOrID string, options *SystemdOptions) (*en if err != nil { return nil, err } + defer response.Body.Close() + report := &entities.GenerateSystemdReport{} return report, response.Process(&report.Units) } +// Kube generate Kubernetes YAML (v1 specification) +// +// Note: Caller is responsible for closing returned reader func Kube(ctx context.Context, nameOrIDs []string, options *KubeOptions) (*entities.GenerateKubeReport, error) { if options == nil { options = new(KubeOptions) diff --git a/pkg/bindings/images/diff.go b/pkg/bindings/images/diff.go index 79b0df8c9..671b73089 100644 --- a/pkg/bindings/images/diff.go +++ b/pkg/bindings/images/diff.go @@ -23,6 +23,8 @@ func Diff(ctx context.Context, nameOrID string, options *DiffOptions) ([]archive if err != nil { return nil, err } + defer response.Body.Close() + var changes []archive.Change return changes, response.Process(&changes) } diff --git a/pkg/bindings/images/images.go b/pkg/bindings/images/images.go index 8680d6baa..959481e0d 100644 --- a/pkg/bindings/images/images.go +++ b/pkg/bindings/images/images.go @@ -27,6 +27,8 @@ func Exists(ctx context.Context, nameOrID string, options *ExistsOptions) (bool, if err != nil { return false, err } + defer response.Body.Close() + return response.IsSuccess(), nil } @@ -49,6 +51,8 @@ func List(ctx context.Context, options *ListOptions) ([]*entities.ImageSummary, if err != nil { return imageSummary, err } + defer response.Body.Close() + return imageSummary, response.Process(&imageSummary) } @@ -71,6 +75,8 @@ func GetImage(ctx context.Context, nameOrID string, options *GetOptions) (*entit if err != nil { return &inspectedData, err } + defer response.Body.Close() + return &inspectedData, response.Process(&inspectedData) } @@ -92,6 +98,8 @@ func Tree(ctx context.Context, nameOrID string, options *TreeOptions) (*entities if err != nil { return nil, err } + defer response.Body.Close() + return &report, response.Process(&report) } @@ -110,6 +118,8 @@ func History(ctx context.Context, nameOrID string, options *HistoryOptions) ([]* if err != nil { return history, err } + defer response.Body.Close() + return history, response.Process(&history) } @@ -123,6 +133,8 @@ func Load(ctx context.Context, r io.Reader) (*entities.ImageLoadReport, error) { if err != nil { return nil, err } + defer response.Body.Close() + return &report, response.Process(&report) } @@ -147,6 +159,7 @@ func Export(ctx context.Context, nameOrIDs []string, w io.Writer, options *Expor if err != nil { return err } + defer response.Body.Close() if response.StatusCode/100 == 2 || response.StatusCode/100 == 3 { _, err = io.Copy(w, response.Body) @@ -176,8 +189,9 @@ func Prune(ctx context.Context, options *PruneOptions) ([]*reports.PruneReport, if err != nil { return deleted, err } - err = response.Process(&deleted) - return deleted, err + defer response.Body.Close() + + return deleted, response.Process(&deleted) } // Tag adds an additional name to locally-stored image. Both the tag and repo parameters are required. @@ -197,6 +211,8 @@ func Tag(ctx context.Context, nameOrID, tag, repo string, options *TagOptions) e if err != nil { return err } + defer response.Body.Close() + return response.Process(nil) } @@ -217,10 +233,12 @@ func Untag(ctx context.Context, nameOrID, tag, repo string, options *UntagOption if err != nil { return err } + defer response.Body.Close() + return response.Process(nil) } -// Imports adds the given image to the local image store. This can be done by file and the given reader +// Import adds the given image to the local image store. This can be done by file and the given reader // or via the url parameter. Additional metadata can be associated with the image by using the changes and // message parameters. The image can also be tagged given a reference. One of url OR r must be provided. func Import(ctx context.Context, r io.Reader, options *ImportOptions) (*entities.ImageImportReport, error) { @@ -243,6 +261,8 @@ func Import(ctx context.Context, r io.Reader, options *ImportOptions) (*entities if err != nil { return nil, err } + defer response.Body.Close() + return &report, response.Process(&report) } @@ -269,8 +289,8 @@ func Push(ctx context.Context, source string, destination string, options *PushO if err != nil { return err } - //SkipTLSVerify is special. We need to delete the param added by - //toparams and change the key and flip the bool + // SkipTLSVerify is special. We need to delete the param added by + // toparams and change the key and flip the bool if options.SkipTLSVerify != nil { params.Del("SkipTLSVerify") params.Set("tlsVerify", strconv.FormatBool(!options.GetSkipTLSVerify())) @@ -282,6 +302,7 @@ func Push(ctx context.Context, source string, destination string, options *PushO if err != nil { return err } + defer response.Body.Close() return response.Process(err) } @@ -317,6 +338,7 @@ func Search(ctx context.Context, term string, options *SearchOptions) ([]entitie if err != nil { return nil, err } + defer response.Body.Close() results := []entities.ImageSearchReport{} if err := response.Process(&results); err != nil { diff --git a/pkg/bindings/images/rm.go b/pkg/bindings/images/rm.go index e45e583f4..461eb7729 100644 --- a/pkg/bindings/images/rm.go +++ b/pkg/bindings/images/rm.go @@ -36,6 +36,8 @@ func Remove(ctx context.Context, images []string, options *RemoveOptions) (*enti if err != nil { return nil, []error{err} } + defer response.Body.Close() + if err := response.Process(&report); err != nil { return nil, []error{err} } diff --git a/pkg/bindings/manifests/manifests.go b/pkg/bindings/manifests/manifests.go index 268ce3b19..6aa4961f1 100644 --- a/pkg/bindings/manifests/manifests.go +++ b/pkg/bindings/manifests/manifests.go @@ -46,10 +46,12 @@ func Create(ctx context.Context, names, images []string, options *CreateOptions) if err != nil { return "", err } + defer response.Body.Close() + return idr.ID, response.Process(&idr) } -// Exists returns true if a given maifest list exists +// Exists returns true if a given manifest list exists func Exists(ctx context.Context, name string, options *ExistsOptions) (bool, error) { conn, err := bindings.GetClient(ctx) if err != nil { @@ -59,6 +61,8 @@ func Exists(ctx context.Context, name string, options *ExistsOptions) (bool, err if err != nil { return false, err } + defer response.Body.Close() + return response.IsSuccess(), nil } @@ -77,6 +81,8 @@ func Inspect(ctx context.Context, name string, options *InspectOptions) (*manife if err != nil { return nil, err } + defer response.Body.Close() + return &list, response.Process(&list) } @@ -100,6 +106,8 @@ func Add(ctx context.Context, name string, options *AddOptions) (string, error) if err != nil { return "", err } + defer response.Body.Close() + return idr.ID, response.Process(&idr) } @@ -121,6 +129,8 @@ func Remove(ctx context.Context, name, digest string, options *RemoveOptions) (s if err != nil { return "", err } + defer response.Body.Close() + return idr.ID, response.Process(&idr) } @@ -145,18 +155,20 @@ func Push(ctx context.Context, name, destination string, options *images.PushOpt if err != nil { return "", err } - //SkipTLSVerify is special. We need to delete the param added by - //toparams and change the key and flip the bool + // SkipTLSVerify is special. We need to delete the param added by + // toparams and change the key and flip the bool if options.SkipTLSVerify != nil { params.Del("SkipTLSVerify") params.Set("tlsVerify", strconv.FormatBool(!options.GetSkipTLSVerify())) } params.Set("image", name) params.Set("destination", destination) - _, err = conn.DoRequest(nil, http.MethodPost, "/manifests/%s/push", params, nil, name) + response, err := conn.DoRequest(nil, http.MethodPost, "/manifests/%s/push", params, nil, name) if err != nil { return "", err } + defer response.Body.Close() + return idr.ID, err } @@ -179,5 +191,6 @@ func Push(ctx context.Context, name, destination string, options *images.PushOpt // if err != nil { // return "", err // } +// defer response.Body.Close() // return idr.ID, response.Process(&idr) //} diff --git a/pkg/bindings/network/network.go b/pkg/bindings/network/network.go index 17451c273..59207aa8d 100644 --- a/pkg/bindings/network/network.go +++ b/pkg/bindings/network/network.go @@ -34,6 +34,8 @@ func Create(ctx context.Context, options *CreateOptions) (*entities.NetworkCreat if err != nil { return nil, err } + defer response.Body.Close() + return &report, response.Process(&report) } @@ -53,6 +55,8 @@ func Inspect(ctx context.Context, nameOrID string, options *InspectOptions) ([]e if err != nil { return nil, err } + defer response.Body.Close() + return reports, response.Process(&reports[0]) } @@ -76,6 +80,8 @@ func Remove(ctx context.Context, nameOrID string, options *RemoveOptions) ([]*en if err != nil { return nil, err } + defer response.Body.Close() + return reports, response.Process(&reports) } @@ -99,6 +105,8 @@ func List(ctx context.Context, options *ListOptions) ([]*entities.NetworkListRep if err != nil { return netList, err } + defer response.Body.Close() + return netList, response.Process(&netList) } @@ -133,6 +141,8 @@ func Disconnect(ctx context.Context, networkName string, ContainerNameOrID strin if err != nil { return err } + defer response.Body.Close() + return response.Process(nil) } @@ -166,6 +176,8 @@ func Connect(ctx context.Context, networkName string, ContainerNameOrID string, if err != nil { return err } + defer response.Body.Close() + return response.Process(nil) } @@ -179,6 +191,8 @@ func Exists(ctx context.Context, nameOrID string, options *ExistsOptions) (bool, if err != nil { return false, err } + defer response.Body.Close() + return response.IsSuccess(), nil } @@ -203,5 +217,7 @@ func Prune(ctx context.Context, options *PruneOptions) ([]*entities.NetworkPrune if err != nil { return nil, err } + defer response.Body.Close() + return prunedNetworks, response.Process(&prunedNetworks) } diff --git a/pkg/bindings/play/play.go b/pkg/bindings/play/play.go index a45508fed..89a6f9b65 100644 --- a/pkg/bindings/play/play.go +++ b/pkg/bindings/play/play.go @@ -50,6 +50,8 @@ func Kube(ctx context.Context, path string, options *KubeOptions) (*entities.Pla if err != nil { return nil, err } + defer response.Body.Close() + if err := response.Process(&report); err != nil { return nil, err } diff --git a/pkg/bindings/pods/pods.go b/pkg/bindings/pods/pods.go index eb7b273cf..9d3ff322e 100644 --- a/pkg/bindings/pods/pods.go +++ b/pkg/bindings/pods/pods.go @@ -34,6 +34,8 @@ func CreatePodFromSpec(ctx context.Context, s *specgen.PodSpecGenerator, options if err != nil { return nil, err } + defer response.Body.Close() + return &pcr, response.Process(&pcr) } @@ -47,6 +49,8 @@ func Exists(ctx context.Context, nameOrID string, options *ExistsOptions) (bool, if err != nil { return false, err } + defer response.Body.Close() + return response.IsSuccess(), nil } @@ -67,6 +71,8 @@ func Inspect(ctx context.Context, nameOrID string, options *InspectOptions) (*en if err != nil { return nil, err } + defer response.Body.Close() + return &report, response.Process(&report) } @@ -91,6 +97,8 @@ func Kill(ctx context.Context, nameOrID string, options *KillOptions) (*entities if err != nil { return nil, err } + defer response.Body.Close() + return &report, response.Process(&report) } @@ -109,6 +117,8 @@ func Pause(ctx context.Context, nameOrID string, options *PauseOptions) (*entiti if err != nil { return nil, err } + defer response.Body.Close() + return &report, response.Process(&report) } @@ -128,6 +138,8 @@ func Prune(ctx context.Context, options *PruneOptions) ([]*entities.PodPruneRepo if err != nil { return nil, err } + defer response.Body.Close() + return reports, response.Process(&reports) } @@ -152,6 +164,8 @@ func List(ctx context.Context, options *ListOptions) ([]*entities.ListPodsReport if err != nil { return podsReports, err } + defer response.Body.Close() + return podsReports, response.Process(&podsReports) } @@ -170,6 +184,8 @@ func Restart(ctx context.Context, nameOrID string, options *RestartOptions) (*en if err != nil { return nil, err } + defer response.Body.Close() + return &report, response.Process(&report) } @@ -192,6 +208,8 @@ func Remove(ctx context.Context, nameOrID string, options *RemoveOptions) (*enti if err != nil { return nil, err } + defer response.Body.Close() + return &report, response.Process(&report) } @@ -210,6 +228,8 @@ func Start(ctx context.Context, nameOrID string, options *StartOptions) (*entiti if err != nil { return nil, err } + defer response.Body.Close() + if response.StatusCode == http.StatusNotModified { report.Id = nameOrID return &report, nil @@ -236,6 +256,8 @@ func Stop(ctx context.Context, nameOrID string, options *StopOptions) (*entities if err != nil { return nil, err } + defer response.Body.Close() + if response.StatusCode == http.StatusNotModified { report.Id = nameOrID return &report, nil @@ -261,6 +283,7 @@ func Top(ctx context.Context, nameOrID string, options *TopOptions) ([]string, e if err != nil { return nil, err } + defer response.Body.Close() body := handlers.PodTopOKBody{} if err = response.Process(&body); err != nil { @@ -293,6 +316,8 @@ func Unpause(ctx context.Context, nameOrID string, options *UnpauseOptions) (*en if err != nil { return nil, err } + defer response.Body.Close() + return &report, response.Process(&report) } @@ -318,5 +343,7 @@ func Stats(ctx context.Context, namesOrIDs []string, options *StatsOptions) ([]* if err != nil { return nil, err } + defer response.Body.Close() + return reports, response.Process(&reports) } diff --git a/pkg/bindings/secrets/secrets.go b/pkg/bindings/secrets/secrets.go index 091d38e56..b741d3e5c 100644 --- a/pkg/bindings/secrets/secrets.go +++ b/pkg/bindings/secrets/secrets.go @@ -22,6 +22,8 @@ func List(ctx context.Context, options *ListOptions) ([]*entities.SecretInfoRepo if err != nil { return secrs, err } + defer response.Body.Close() + return secrs, response.Process(&secrs) } @@ -38,6 +40,8 @@ func Inspect(ctx context.Context, nameOrID string, options *InspectOptions) (*en if err != nil { return inspect, err } + defer response.Body.Close() + return inspect, response.Process(&inspect) } @@ -52,6 +56,8 @@ func Remove(ctx context.Context, nameOrID string) error { if err != nil { return err } + defer response.Body.Close() + return response.Process(nil) } @@ -74,5 +80,7 @@ func Create(ctx context.Context, reader io.Reader, options *CreateOptions) (*ent if err != nil { return nil, err } + defer response.Body.Close() + return create, response.Process(&create) } diff --git a/pkg/bindings/system/info.go b/pkg/bindings/system/info.go index 244f9643e..8a307a4ca 100644 --- a/pkg/bindings/system/info.go +++ b/pkg/bindings/system/info.go @@ -9,12 +9,7 @@ import ( ) // Info returns information about the libpod environment and its stores -func Info(ctx context.Context, options *InfoOptions) (*define.Info, error) { - if options == nil { - options = new(InfoOptions) - } - _ = options - info := define.Info{} +func Info(ctx context.Context, _ *InfoOptions) (*define.Info, error) { conn, err := bindings.GetClient(ctx) if err != nil { return nil, err @@ -23,5 +18,8 @@ func Info(ctx context.Context, options *InfoOptions) (*define.Info, error) { if err != nil { return nil, err } + defer response.Body.Close() + + info := define.Info{} return &info, response.Process(&info) } diff --git a/pkg/bindings/system/system.go b/pkg/bindings/system/system.go index 310bcef15..719cde52e 100644 --- a/pkg/bindings/system/system.go +++ b/pkg/bindings/system/system.go @@ -31,6 +31,8 @@ func Events(ctx context.Context, eventChan chan entities.Event, cancelChan chan if err != nil { return err } + defer response.Body.Close() + if cancelChan != nil { go func() { <-cancelChan @@ -75,6 +77,8 @@ func Prune(ctx context.Context, options *PruneOptions) (*entities.SystemPruneRep if err != nil { return nil, err } + defer response.Body.Close() + return &report, response.Process(&report) } @@ -101,6 +105,7 @@ func Version(ctx context.Context, options *VersionOptions) (*entities.SystemVers if err != nil { return nil, err } + defer response.Body.Close() if err = response.Process(&component); err != nil { return nil, err @@ -141,5 +146,7 @@ func DiskUsage(ctx context.Context, options *DiskOptions) (*entities.SystemDfRep if err != nil { return nil, err } + defer response.Body.Close() + return &report, response.Process(&report) } diff --git a/pkg/bindings/test/attach_test.go b/pkg/bindings/test/attach_test.go index fbdf18d44..5c3ec48e4 100644 --- a/pkg/bindings/test/attach_test.go +++ b/pkg/bindings/test/attach_test.go @@ -81,10 +81,9 @@ var _ = Describe("Podman containers attach", func() { tickTock := time.NewTimer(2 * time.Second) go func() { <-tickTock.C - timeout := uint(5) - err := containers.Stop(bt.conn, ctnr.ID, new(containers.StopOptions).WithTimeout(timeout)) + err := containers.Stop(bt.conn, ctnr.ID, new(containers.StopOptions).WithTimeout(uint(5))) if err != nil { - GinkgoWriter.Write([]byte(err.Error())) + fmt.Fprint(GinkgoWriter, err.Error()) } }() diff --git a/pkg/bindings/test/common_test.go b/pkg/bindings/test/common_test.go index 9bac4b620..91ebe21fc 100644 --- a/pkg/bindings/test/common_test.go +++ b/pkg/bindings/test/common_test.go @@ -8,6 +8,7 @@ import ( "os/exec" "path/filepath" "strings" + "time" "github.com/containers/podman/v3/libpod/define" . "github.com/containers/podman/v3/pkg/bindings" @@ -150,11 +151,21 @@ func createTempDirInTempDir() (string, error) { } func (b *bindingTest) startAPIService() *gexec.Session { - var ( - cmd []string - ) - cmd = append(cmd, "--log-level=debug", "--events-backend=file", "system", "service", "--timeout=0", b.sock) - return b.runPodman(cmd) + cmd := []string{"--log-level=debug", "--events-backend=file", "system", "service", "--timeout=0", b.sock} + session := b.runPodman(cmd) + + sock := strings.TrimPrefix(b.sock, "unix://") + for i := 0; i < 10; i++ { + if _, err := os.Stat(sock); err != nil { + if !os.IsNotExist(err) { + break + } + time.Sleep(time.Second) + continue + } + break + } + return session } func (b *bindingTest) cleanup() { diff --git a/pkg/bindings/test/resource_test.go b/pkg/bindings/test/resource_test.go new file mode 100644 index 000000000..b12d1ccd6 --- /dev/null +++ b/pkg/bindings/test/resource_test.go @@ -0,0 +1,116 @@ +package test_bindings + +import ( + "context" + "fmt" + "io/fs" + "os" + "os/exec" + "path/filepath" + "reflect" + "strconv" + "syscall" + + "github.com/containers/podman/v3/pkg/bindings" + "github.com/containers/podman/v3/pkg/bindings/containers" + "github.com/containers/podman/v3/pkg/bindings/images" + "github.com/containers/podman/v3/pkg/bindings/pods" + "github.com/containers/podman/v3/pkg/bindings/system" + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" +) + +var _ = Describe("Verify Podman resources", func() { + var ( + bt *bindingTest + s *Session + ) + + BeforeEach(func() { + bt = newBindingTest() + s = bt.startAPIService() + err := bt.NewConnection() + Expect(err).ShouldNot(HaveOccurred()) + }) + + AfterEach(func() { + s.Kill() + bt.cleanup() + }) + + It("no leaked connections", func() { + conn, err := bindings.NewConnection(context.Background(), bt.sock) + Expect(err).ShouldNot(HaveOccurred()) + + // Record details on open file descriptors before using API + buffer := lsof() + + // Record open fd from /proc + start, err := readProc() + Expect(err).ShouldNot(HaveOccurred()) + + // Run some operations + _, err = system.Info(conn, nil) + Expect(err).ShouldNot(HaveOccurred()) + _, err = images.List(conn, nil) + Expect(err).ShouldNot(HaveOccurred()) + _, err = containers.List(conn, nil) + Expect(err).ShouldNot(HaveOccurred()) + _, err = pods.List(conn, nil) + Expect(err).ShouldNot(HaveOccurred()) + + podman, _ := bindings.GetClient(conn) + podman.Client.CloseIdleConnections() + + // Record open fd from /proc + finished, err := readProc() + Expect(err).ShouldNot(HaveOccurred()) + if !reflect.DeepEqual(finished, start) { + fmt.Fprintf(GinkgoWriter, "Open FDs:\nlsof Before:\n%s\n", buffer) + + // Record details on open file descriptors after using API + buffer := lsof() + fmt.Fprintf(GinkgoWriter, "lsof After:\n%s\n", buffer) + + // We know test has failed. Easier to let ginkgo format output. + Expect(finished).Should(Equal(start)) + } + }) +}) + +func lsof() string { + lsof := exec.Command("lsof", "+E", "-p", strconv.Itoa(os.Getpid())) + buffer, err := lsof.Output() + Expect(err).ShouldNot(HaveOccurred()) + return string(buffer) +} + +func readProc() ([]string, error) { + syscall.Sync() + + names := make([]string, 0) + err := filepath.WalkDir(fmt.Sprintf("/proc/%d/fd", os.Getpid()), + func(path string, d fs.DirEntry, err error) error { + name := path + " -> " + + switch { + case d.IsDir(): + return nil + case err != nil: + name += err.Error() + case d.Type()&fs.ModeSymlink != 0: + n, err := os.Readlink(path) + if err != nil && !os.IsNotExist(err) { + return err + } + if n == "" { + n = d.Type().String() + } + name += n + } + names = append(names, name) + return nil + }) + return names, err +} diff --git a/pkg/bindings/volumes/volumes.go b/pkg/bindings/volumes/volumes.go index fb58a1d1f..56cf13ade 100644 --- a/pkg/bindings/volumes/volumes.go +++ b/pkg/bindings/volumes/volumes.go @@ -33,6 +33,8 @@ func Create(ctx context.Context, config entities.VolumeCreateOptions, options *C if err != nil { return nil, err } + defer response.Body.Close() + return &v, response.Process(&v) } @@ -53,6 +55,8 @@ func Inspect(ctx context.Context, nameOrID string, options *InspectOptions) (*en if err != nil { return &inspect, err } + defer response.Body.Close() + return &inspect, response.Process(&inspect) } @@ -74,6 +78,8 @@ func List(ctx context.Context, options *ListOptions) ([]*entities.VolumeListRepo if err != nil { return vols, err } + defer response.Body.Close() + return vols, response.Process(&vols) } @@ -94,6 +100,8 @@ func Prune(ctx context.Context, options *PruneOptions) ([]*reports.PruneReport, if err != nil { return nil, err } + defer response.Body.Close() + return pruned, response.Process(&pruned) } @@ -112,6 +120,8 @@ func Remove(ctx context.Context, nameOrID string, options *RemoveOptions) error if err != nil { return err } + defer response.Body.Close() + return response.Process(nil) } @@ -125,5 +135,7 @@ func Exists(ctx context.Context, nameOrID string, options *ExistsOptions) (bool, if err != nil { return false, err } + defer response.Body.Close() + return response.IsSuccess(), nil } diff --git a/pkg/domain/entities/generate.go b/pkg/domain/entities/generate.go index 3ec713edf..8a437061f 100644 --- a/pkg/domain/entities/generate.go +++ b/pkg/domain/entities/generate.go @@ -35,6 +35,8 @@ type GenerateKubeOptions struct { } // GenerateKubeReport +// +// FIXME: Podman4.0 should change io.Reader to io.ReaderCloser type GenerateKubeReport struct { // Reader - the io.Reader to reader the generated YAML file. Reader io.Reader diff --git a/pkg/domain/infra/tunnel/containers.go b/pkg/domain/infra/tunnel/containers.go index b638bfe24..81ddce42f 100644 --- a/pkg/domain/infra/tunnel/containers.go +++ b/pkg/domain/infra/tunnel/containers.go @@ -404,11 +404,11 @@ func (ic *ContainerEngine) ContainerLogs(_ context.Context, nameOrIDs []string, return err case line := <-stdoutCh: if opts.StdoutWriter != nil { - _, _ = io.WriteString(opts.StdoutWriter, line+"\n") + _, _ = io.WriteString(opts.StdoutWriter, line) } case line := <-stderrCh: if opts.StderrWriter != nil { - _, _ = io.WriteString(opts.StderrWriter, line+"\n") + _, _ = io.WriteString(opts.StderrWriter, line) } } } diff --git a/pkg/domain/infra/tunnel/generate.go b/pkg/domain/infra/tunnel/generate.go index 0e768b30b..3d3cd52be 100644 --- a/pkg/domain/infra/tunnel/generate.go +++ b/pkg/domain/infra/tunnel/generate.go @@ -16,6 +16,9 @@ func (ic *ContainerEngine) GenerateSystemd(ctx context.Context, nameOrID string, return generate.Systemd(ic.ClientCtx, nameOrID, options) } +// GenerateKube Kubernetes YAML (v1 specification) for nameOrIDs +// +// Note: Caller is responsible for closing returned Reader func (ic *ContainerEngine) GenerateKube(ctx context.Context, nameOrIDs []string, opts entities.GenerateKubeOptions) (*entities.GenerateKubeReport, error) { options := new(generate.KubeOptions).WithService(opts.Service) return generate.Kube(ic.ClientCtx, nameOrIDs, options) diff --git a/pkg/machine/fcos.go b/pkg/machine/fcos.go index 49ec01e67..85cedcd5a 100644 --- a/pkg/machine/fcos.go +++ b/pkg/machine/fcos.go @@ -24,8 +24,8 @@ type FcosDownload struct { Download } -func NewFcosDownloader(vmType, vmName string) (DistributionDownload, error) { - info, err := getFCOSDownload() +func NewFcosDownloader(vmType, vmName, imageStream string) (DistributionDownload, error) { + info, err := getFCOSDownload(imageStream) if err != nil { return nil, err } diff --git a/pkg/machine/fcos_amd64.go b/pkg/machine/fcos_amd64.go index 36676405a..4e2e86d3e 100644 --- a/pkg/machine/fcos_amd64.go +++ b/pkg/machine/fcos_amd64.go @@ -8,16 +8,26 @@ import ( "github.com/coreos/stream-metadata-go/fedoracoreos" "github.com/coreos/stream-metadata-go/stream" + "github.com/pkg/errors" "github.com/sirupsen/logrus" ) // This should get Exported and stay put as it will apply to all fcos downloads // getFCOS parses fedoraCoreOS's stream and returns the image download URL and the release version -func getFCOSDownload() (*fcosDownloadInfo, error) { +func getFCOSDownload(imageStream string) (*fcosDownloadInfo, error) { var ( fcosstable stream.Stream + streamType string ) - streamurl := fedoracoreos.GetStreamURL(fedoracoreos.StreamNext) + switch imageStream { + case "testing", "": + streamType = fedoracoreos.StreamNext + case "stable": + streamType = fedoracoreos.StreamStable + default: + return nil, errors.Errorf("invalid stream %s: valid streams are `testing` and `stable`", imageStream) + } + streamurl := fedoracoreos.GetStreamURL(streamType) resp, err := http.Get(streamurl.String()) if err != nil { return nil, err diff --git a/pkg/machine/fcos_arm64.go b/pkg/machine/fcos_arm64.go index f5cd5a505..f45522be0 100644 --- a/pkg/machine/fcos_arm64.go +++ b/pkg/machine/fcos_arm64.go @@ -13,7 +13,7 @@ const aarchBaseURL = "https://fedorapeople.org/groups/fcos-images/builds/latest/ // Total hack until automation is possible. // We need a proper json file at least to automate -func getFCOSDownload() (*fcosDownloadInfo, error) { +func getFCOSDownload(imageStream string) (*fcosDownloadInfo, error) { meta := Build{} resp, err := http.Get(aarchBaseURL + "meta.json") if err != nil { diff --git a/pkg/machine/qemu/machine.go b/pkg/machine/qemu/machine.go index a92892957..871436618 100644 --- a/pkg/machine/qemu/machine.go +++ b/pkg/machine/qemu/machine.go @@ -138,29 +138,29 @@ func (v *MachineVM) Init(opts machine.InitOptions) error { jsonFile := filepath.Join(vmConfigDir, v.Name) + ".json" v.IdentityPath = filepath.Join(sshDir, v.Name) - // The user has provided an alternate image which can be a file path - // or URL. - if len(opts.ImagePath) > 0 { - g, err := machine.NewGenericDownloader(vmtype, v.Name, opts.ImagePath) + switch opts.ImagePath { + case "testing", "stable", "": + // Get image as usual + dd, err := machine.NewFcosDownloader(vmtype, v.Name, opts.ImagePath) if err != nil { return err } - v.ImagePath = g.Get().LocalUncompressedFile - if err := g.DownloadImage(); err != nil { + v.ImagePath = dd.Get().LocalUncompressedFile + if err := dd.DownloadImage(); err != nil { return err } - } else { - // Get the image as usual - dd, err := machine.NewFcosDownloader(vmtype, v.Name) + default: + // The user has provided an alternate image which can be a file path + // or URL. + g, err := machine.NewGenericDownloader(vmtype, v.Name, opts.ImagePath) if err != nil { return err } - v.ImagePath = dd.Get().LocalUncompressedFile - if err := dd.DownloadImage(); err != nil { + v.ImagePath = g.Get().LocalUncompressedFile + if err := g.DownloadImage(); err != nil { return err } } - // Add arch specific options including image location v.CmdLine = append(v.CmdLine, v.addArchOptions()...) diff --git a/pkg/specgen/generate/namespaces.go b/pkg/specgen/generate/namespaces.go index 1d7373093..80790dcc1 100644 --- a/pkg/specgen/generate/namespaces.go +++ b/pkg/specgen/generate/namespaces.go @@ -242,7 +242,7 @@ func namespaceOptions(ctx context.Context, s *specgen.SpecGenerator, rt *libpod. } toReturn = append(toReturn, libpod.WithNetNSFrom(netCtr)) case specgen.Slirp: - portMappings, err := createPortMappings(ctx, s, imageData) + portMappings, expose, err := createPortMappings(ctx, s, imageData) if err != nil { return nil, err } @@ -250,15 +250,15 @@ func namespaceOptions(ctx context.Context, s *specgen.SpecGenerator, rt *libpod. if s.NetNS.Value != "" { val = fmt.Sprintf("slirp4netns:%s", s.NetNS.Value) } - toReturn = append(toReturn, libpod.WithNetNS(portMappings, postConfigureNetNS, val, nil)) + toReturn = append(toReturn, libpod.WithNetNS(portMappings, expose, postConfigureNetNS, val, nil)) case specgen.Private: fallthrough case specgen.Bridge: - portMappings, err := createPortMappings(ctx, s, imageData) + portMappings, expose, err := createPortMappings(ctx, s, imageData) if err != nil { return nil, err } - toReturn = append(toReturn, libpod.WithNetNS(portMappings, postConfigureNetNS, "bridge", s.CNINetworks)) + toReturn = append(toReturn, libpod.WithNetNS(portMappings, expose, postConfigureNetNS, "bridge", s.CNINetworks)) } if s.UseImageHosts { diff --git a/pkg/specgen/generate/ports.go b/pkg/specgen/generate/ports.go index bd64080b1..a300f8014 100644 --- a/pkg/specgen/generate/ports.go +++ b/pkg/specgen/generate/ports.go @@ -254,17 +254,15 @@ func ParsePortMapping(portMappings []types.PortMapping) ([]ocicni.PortMapping, m } // Make final port mappings for the container -func createPortMappings(ctx context.Context, s *specgen.SpecGenerator, imageData *libimage.ImageData) ([]ocicni.PortMapping, error) { +func createPortMappings(ctx context.Context, s *specgen.SpecGenerator, imageData *libimage.ImageData) ([]ocicni.PortMapping, map[uint16][]string, error) { finalMappings, containerPortValidate, hostPortValidate, err := ParsePortMapping(s.PortMappings) if err != nil { - return nil, err + return nil, nil, err } - // If not publishing exposed ports, or if we are publishing and there is - // nothing to publish - then just return the port mappings we've made so - // far. - if !s.PublishExposedPorts || (len(s.Expose) == 0 && imageData == nil) { - return finalMappings, nil + // No exposed ports so return the port mappings we've made so far. + if len(s.Expose) == 0 && imageData == nil { + return finalMappings, nil, nil } logrus.Debugf("Adding exposed ports") @@ -273,7 +271,7 @@ func createPortMappings(ctx context.Context, s *specgen.SpecGenerator, imageData if imageData != nil { expose, err = GenExposedPorts(imageData.Config.ExposedPorts) if err != nil { - return nil, err + return nil, nil, err } } @@ -289,11 +287,11 @@ func createPortMappings(ctx context.Context, s *specgen.SpecGenerator, imageData // Validate protocol first protocols, err := checkProtocol(proto, false) if err != nil { - return nil, errors.Wrapf(err, "error validating protocols for exposed port %d", port) + return nil, nil, errors.Wrapf(err, "error validating protocols for exposed port %d", port) } if port == 0 { - return nil, errors.Errorf("cannot expose 0 as it is not a valid port number") + return nil, nil, errors.Errorf("cannot expose 0 as it is not a valid port number") } // Check to see if the port is already present in existing @@ -317,6 +315,11 @@ func createPortMappings(ctx context.Context, s *specgen.SpecGenerator, imageData } } + // If not publishing exposed ports return mappings and exposed ports. + if !s.PublishExposedPorts { + return finalMappings, toExpose, nil + } + // We now have a final list of ports that we want exposed. // Let's find empty, unallocated host ports for them. for port, protocols := range toExpose { @@ -332,7 +335,7 @@ func createPortMappings(ctx context.Context, s *specgen.SpecGenerator, imageData // unfortunate for the UDP case. candidate, err := utils.GetRandomPort() if err != nil { - return nil, err + return nil, nil, err } // Check if the host port is already bound @@ -363,12 +366,12 @@ func createPortMappings(ctx context.Context, s *specgen.SpecGenerator, imageData } if tries == 0 && hostPort == 0 { // We failed to find an open port. - return nil, errors.Errorf("failed to find an open port to expose container port %d on the host", port) + return nil, nil, errors.Errorf("failed to find an open port to expose container port %d on the host", port) } } } - return finalMappings, nil + return finalMappings, nil, nil } // Check a string to ensure it is a comma-separated set of valid protocols diff --git a/pkg/systemd/generate/common.go b/pkg/systemd/generate/common.go index f2092c0ae..49465fb30 100644 --- a/pkg/systemd/generate/common.go +++ b/pkg/systemd/generate/common.go @@ -8,9 +8,9 @@ import ( "github.com/pkg/errors" ) -// minTimeoutStopSec is the minimal stop timeout for generated systemd units -// without --new. Once exceeded, processes of the services are killed and the -// cgroup(s) are cleaned up. +// minTimeoutStopSec is the minimal stop timeout for generated systemd units. +// Once exceeded, processes of the services are killed and the cgroup(s) are +// cleaned up. const minTimeoutStopSec = 60 // validateRestartPolicy checks that the user-provided policy is valid. @@ -71,11 +71,12 @@ func filterCommonContainerFlags(command []string, argCount int) []string { case s == "--rm": // Boolean flags support --flag and --flag={true,false}. continue - case s == "--sdnotify", s == "--cgroups": + case s == "--sdnotify", s == "--cgroups", s == "--cidfile": i++ continue case strings.HasPrefix(s, "--rm="), - strings.HasPrefix(s, "--cgroups="): + strings.HasPrefix(s, "--cgroups="), + strings.HasPrefix(s, "--cidfile="): continue } processed = append(processed, s) diff --git a/pkg/systemd/generate/common_test.go b/pkg/systemd/generate/common_test.go index 3e2ac015f..80abebb26 100644 --- a/pkg/systemd/generate/common_test.go +++ b/pkg/systemd/generate/common_test.go @@ -103,12 +103,12 @@ func TestFilterCommonContainerFlags(t *testing.T) { }, { []string{"podman", "run", "--cidfile", "foo", "alpine"}, - []string{"podman", "run", "--cidfile", "foo", "alpine"}, + []string{"podman", "run", "alpine"}, 1, }, { []string{"podman", "run", "--cidfile=foo", "alpine"}, - []string{"podman", "run", "--cidfile=foo", "alpine"}, + []string{"podman", "run", "alpine"}, 1, }, { diff --git a/pkg/systemd/generate/containers.go b/pkg/systemd/generate/containers.go index 66cf5ca44..931f13972 100644 --- a/pkg/systemd/generate/containers.go +++ b/pkg/systemd/generate/containers.go @@ -16,7 +16,6 @@ import ( "github.com/pkg/errors" "github.com/sirupsen/logrus" "github.com/spf13/pflag" - "golang.org/x/sys/unix" ) // containerInfo contains data required for generating a container's systemd @@ -33,8 +32,6 @@ type containerInfo struct { // StopTimeout sets the timeout Podman waits before killing the container // during service stop. StopTimeout uint - // KillSignal of the container. - KillSignal string // RestartPolicy of the systemd unit (e.g., no, on-failure, always). RestartPolicy string // PIDFile of the service. Required for forking services. Must point to the @@ -105,9 +102,6 @@ Environment={{{{- range $index, $value := .ExtraEnvs -}}}}{{{{if $index}}}} {{{{ {{{{- end}}}} Restart={{{{.RestartPolicy}}}} TimeoutStopSec={{{{.TimeoutStopSec}}}} -{{{{- if .KillSignal}}}} -KillSignal={{{{.KillSignal}}}} -{{{{- end}}}} {{{{- if .ExecStartPre}}}} ExecStartPre={{{{.ExecStartPre}}}} {{{{- end}}}} @@ -190,13 +184,6 @@ func generateContainerInfo(ctr *libpod.Container, options entities.GenerateSyste containerEnv: envs, } - // Set a custom kill signal for non SIGTERM (already default in - // systemd) signals. - stopSignal := ctr.StopSignal() - if stopSignal != uint(unix.SIGTERM) { - info.KillSignal = fmt.Sprintf("%d", stopSignal) - } - return &info, nil } @@ -246,9 +233,10 @@ func executeContainerTemplate(info *containerInfo, options entities.GenerateSyst info.Type = "notify" info.NotifyAccess = "all" info.PIDFile = "" - info.ContainerIDFile = "" - info.ExecStop = "" - info.ExecStopPost = "" + info.ContainerIDFile = "%t/%n.ctr-id" + info.ExecStartPre = "/bin/rm -f {{{{.ContainerIDFile}}}}" + info.ExecStop = "{{{{.Executable}}}} stop --ignore --cidfile={{{{.ContainerIDFile}}}}" + info.ExecStopPost = "{{{{.Executable}}}} rm -f --ignore --cidfile={{{{.ContainerIDFile}}}}" // The create command must at least have three arguments: // /usr/bin/podman run $IMAGE index := 0 @@ -271,6 +259,7 @@ func executeContainerTemplate(info *containerInfo, options entities.GenerateSyst } startCommand = append(startCommand, "run", + "--cidfile={{{{.ContainerIDFile}}}}", "--cgroups=no-conmon", "--rm", ) @@ -372,15 +361,7 @@ func executeContainerTemplate(info *containerInfo, options entities.GenerateSyst info.ExecStart = strings.Join(startCommand, " ") } - info.TimeoutStopSec = info.StopTimeout - - // For units without --new add an additional 60 seconds to the stop - // timeout to make sure that Podman stop has enough time to properly - // shutdown and cleanup the container before systemd starts to nuke - // everything in the cgroup. - if !options.New { - info.TimeoutStopSec += minTimeoutStopSec - } + info.TimeoutStopSec = minTimeoutStopSec + info.StopTimeout if info.PodmanVersion == "" { info.PodmanVersion = version.Version.String() diff --git a/pkg/systemd/generate/containers_test.go b/pkg/systemd/generate/containers_test.go index ef3bbb5ae..c60c301cc 100644 --- a/pkg/systemd/generate/containers_test.go +++ b/pkg/systemd/generate/containers_test.go @@ -129,8 +129,11 @@ RequiresMountsFor=/var/run/containers/storage [Service] Environment=PODMAN_SYSTEMD_UNIT=%n Restart=always -TimeoutStopSec=10 -ExecStart=/usr/bin/podman container run --cgroups=no-conmon --rm --sdnotify=conmon -d --replace --name jadda-jadda --hostname hello-world awesome-image:latest command arg1 ... argN "foo=arg \"with \" space" +TimeoutStopSec=70 +ExecStartPre=/bin/rm -f %t/%n.ctr-id +ExecStart=/usr/bin/podman container run --cidfile=%t/%n.ctr-id --cgroups=no-conmon --rm --sdnotify=conmon -d --replace --name jadda-jadda --hostname hello-world awesome-image:latest command arg1 ... argN "foo=arg \"with \" space" +ExecStop=/usr/bin/podman stop --ignore --cidfile=%t/%n.ctr-id +ExecStopPost=/usr/bin/podman rm -f --ignore --cidfile=%t/%n.ctr-id Type=notify NotifyAccess=all @@ -151,8 +154,11 @@ RequiresMountsFor=/var/run/containers/storage [Service] Environment=PODMAN_SYSTEMD_UNIT=%n Restart=always -TimeoutStopSec=10 -ExecStart=/usr/bin/podman container run --cgroups=no-conmon --rm -d --replace --sdnotify=container --name jadda-jadda --hostname hello-world awesome-image:latest command arg1 ... argN "foo=arg \"with \" space" +TimeoutStopSec=70 +ExecStartPre=/bin/rm -f %t/%n.ctr-id +ExecStart=/usr/bin/podman container run --cidfile=%t/%n.ctr-id --cgroups=no-conmon --rm -d --replace --sdnotify=container --name jadda-jadda --hostname hello-world awesome-image:latest command arg1 ... argN "foo=arg \"with \" space" +ExecStop=/usr/bin/podman stop --ignore --cidfile=%t/%n.ctr-id +ExecStopPost=/usr/bin/podman rm -f --ignore --cidfile=%t/%n.ctr-id Type=notify NotifyAccess=all @@ -173,8 +179,11 @@ RequiresMountsFor=/var/run/containers/storage [Service] Environment=PODMAN_SYSTEMD_UNIT=%n Restart=always -TimeoutStopSec=10 -ExecStart=/usr/bin/podman run --cgroups=no-conmon --rm --sdnotify=conmon --replace -d --name jadda-jadda --hostname hello-world awesome-image:latest command arg1 ... argN +TimeoutStopSec=70 +ExecStartPre=/bin/rm -f %t/%n.ctr-id +ExecStart=/usr/bin/podman run --cidfile=%t/%n.ctr-id --cgroups=no-conmon --rm --sdnotify=conmon --replace -d --name jadda-jadda --hostname hello-world awesome-image:latest command arg1 ... argN +ExecStop=/usr/bin/podman stop --ignore --cidfile=%t/%n.ctr-id +ExecStopPost=/usr/bin/podman rm -f --ignore --cidfile=%t/%n.ctr-id Type=notify NotifyAccess=all @@ -195,8 +204,11 @@ RequiresMountsFor=/var/run/containers/storage [Service] Environment=PODMAN_SYSTEMD_UNIT=%n Restart=always -TimeoutStopSec=10 -ExecStart=/usr/bin/podman run --cgroups=no-conmon --rm --pod-id-file %t/pod-foobar.pod-id-file --sdnotify=conmon --replace -d --name jadda-jadda --hostname hello-world awesome-image:latest command arg1 ... argN +TimeoutStopSec=70 +ExecStartPre=/bin/rm -f %t/%n.ctr-id +ExecStart=/usr/bin/podman run --cidfile=%t/%n.ctr-id --cgroups=no-conmon --rm --pod-id-file %t/pod-foobar.pod-id-file --sdnotify=conmon --replace -d --name jadda-jadda --hostname hello-world awesome-image:latest command arg1 ... argN +ExecStop=/usr/bin/podman stop --ignore --cidfile=%t/%n.ctr-id +ExecStopPost=/usr/bin/podman rm -f --ignore --cidfile=%t/%n.ctr-id Type=notify NotifyAccess=all @@ -217,8 +229,11 @@ RequiresMountsFor=/var/run/containers/storage [Service] Environment=PODMAN_SYSTEMD_UNIT=%n Restart=always -TimeoutStopSec=10 -ExecStart=/usr/bin/podman run --cgroups=no-conmon --rm --sdnotify=conmon --replace --detach --name jadda-jadda --hostname hello-world awesome-image:latest command arg1 ... argN +TimeoutStopSec=70 +ExecStartPre=/bin/rm -f %t/%n.ctr-id +ExecStart=/usr/bin/podman run --cidfile=%t/%n.ctr-id --cgroups=no-conmon --rm --sdnotify=conmon --replace --detach --name jadda-jadda --hostname hello-world awesome-image:latest command arg1 ... argN +ExecStop=/usr/bin/podman stop --ignore --cidfile=%t/%n.ctr-id +ExecStopPost=/usr/bin/podman rm -f --ignore --cidfile=%t/%n.ctr-id Type=notify NotifyAccess=all @@ -239,8 +254,11 @@ RequiresMountsFor=/var/run/containers/storage [Service] Environment=PODMAN_SYSTEMD_UNIT=%n Restart=always -TimeoutStopSec=10 -ExecStart=/usr/bin/podman run --cgroups=no-conmon --rm --sdnotify=conmon -d awesome-image:latest +TimeoutStopSec=70 +ExecStartPre=/bin/rm -f %t/%n.ctr-id +ExecStart=/usr/bin/podman run --cidfile=%t/%n.ctr-id --cgroups=no-conmon --rm --sdnotify=conmon -d awesome-image:latest +ExecStop=/usr/bin/podman stop --ignore --cidfile=%t/%n.ctr-id +ExecStopPost=/usr/bin/podman rm -f --ignore --cidfile=%t/%n.ctr-id Type=notify NotifyAccess=all @@ -262,10 +280,13 @@ RequiresMountsFor=/var/run/containers/storage [Service] Environment=PODMAN_SYSTEMD_UNIT=%n Restart=always -TimeoutStopSec=42 -ExecStart=/usr/bin/podman run --cgroups=no-conmon --rm --sdnotify=conmon ` + +TimeoutStopSec=102 +ExecStartPre=/bin/rm -f %t/%n.ctr-id +ExecStart=/usr/bin/podman run --cidfile=%t/%n.ctr-id --cgroups=no-conmon --rm --sdnotify=conmon ` + detachparam + ` awesome-image:latest +ExecStop=/usr/bin/podman stop --ignore --cidfile=%t/%n.ctr-id +ExecStopPost=/usr/bin/podman rm -f --ignore --cidfile=%t/%n.ctr-id Type=notify NotifyAccess=all @@ -288,8 +309,11 @@ RequiresMountsFor=/var/run/containers/storage [Service] Environment=PODMAN_SYSTEMD_UNIT=%n Restart=always -TimeoutStopSec=42 -ExecStart=/usr/bin/podman run --cgroups=no-conmon --rm --sdnotify=conmon -d --replace --name test -p 80:80 awesome-image:latest somecmd --detach=false +TimeoutStopSec=102 +ExecStartPre=/bin/rm -f %t/%n.ctr-id +ExecStart=/usr/bin/podman run --cidfile=%t/%n.ctr-id --cgroups=no-conmon --rm --sdnotify=conmon -d --replace --name test -p 80:80 awesome-image:latest somecmd --detach=false +ExecStop=/usr/bin/podman stop --ignore --cidfile=%t/%n.ctr-id +ExecStopPost=/usr/bin/podman rm -f --ignore --cidfile=%t/%n.ctr-id Type=notify NotifyAccess=all @@ -310,8 +334,11 @@ RequiresMountsFor=/var/run/containers/storage [Service] Environment=PODMAN_SYSTEMD_UNIT=%n Restart=always -TimeoutStopSec=42 -ExecStart=/usr/bin/podman --events-backend none --runroot /root run --cgroups=no-conmon --rm --sdnotify=conmon -d awesome-image:latest +TimeoutStopSec=102 +ExecStartPre=/bin/rm -f %t/%n.ctr-id +ExecStart=/usr/bin/podman --events-backend none --runroot /root run --cidfile=%t/%n.ctr-id --cgroups=no-conmon --rm --sdnotify=conmon -d awesome-image:latest +ExecStop=/usr/bin/podman stop --ignore --cidfile=%t/%n.ctr-id +ExecStopPost=/usr/bin/podman rm -f --ignore --cidfile=%t/%n.ctr-id Type=notify NotifyAccess=all @@ -332,8 +359,11 @@ RequiresMountsFor=/var/run/containers/storage [Service] Environment=PODMAN_SYSTEMD_UNIT=%n Restart=always -TimeoutStopSec=10 -ExecStart=/usr/bin/podman container run --cgroups=no-conmon --rm --sdnotify=conmon -d awesome-image:latest +TimeoutStopSec=70 +ExecStartPre=/bin/rm -f %t/%n.ctr-id +ExecStart=/usr/bin/podman container run --cidfile=%t/%n.ctr-id --cgroups=no-conmon --rm --sdnotify=conmon -d awesome-image:latest +ExecStop=/usr/bin/podman stop --ignore --cidfile=%t/%n.ctr-id +ExecStopPost=/usr/bin/podman rm -f --ignore --cidfile=%t/%n.ctr-id Type=notify NotifyAccess=all @@ -354,8 +384,11 @@ RequiresMountsFor=/var/run/containers/storage [Service] Environment=PODMAN_SYSTEMD_UNIT=%n Restart=always -TimeoutStopSec=10 -ExecStart=/usr/bin/podman run --cgroups=no-conmon --rm --sdnotify=conmon -d --replace --name test --log-driver=journald --log-opt=tag={{.Name}} awesome-image:latest +TimeoutStopSec=70 +ExecStartPre=/bin/rm -f %t/%n.ctr-id +ExecStart=/usr/bin/podman run --cidfile=%t/%n.ctr-id --cgroups=no-conmon --rm --sdnotify=conmon -d --replace --name test --log-driver=journald --log-opt=tag={{.Name}} awesome-image:latest +ExecStop=/usr/bin/podman stop --ignore --cidfile=%t/%n.ctr-id +ExecStopPost=/usr/bin/podman rm -f --ignore --cidfile=%t/%n.ctr-id Type=notify NotifyAccess=all @@ -376,8 +409,11 @@ RequiresMountsFor=/var/run/containers/storage [Service] Environment=PODMAN_SYSTEMD_UNIT=%n Restart=always -TimeoutStopSec=10 -ExecStart=/usr/bin/podman run --cgroups=no-conmon --rm --sdnotify=conmon -d --replace --name test awesome-image:latest sh -c "kill $$$$ && echo %%\\" +TimeoutStopSec=70 +ExecStartPre=/bin/rm -f %t/%n.ctr-id +ExecStart=/usr/bin/podman run --cidfile=%t/%n.ctr-id --cgroups=no-conmon --rm --sdnotify=conmon -d --replace --name test awesome-image:latest sh -c "kill $$$$ && echo %%\\" +ExecStop=/usr/bin/podman stop --ignore --cidfile=%t/%n.ctr-id +ExecStopPost=/usr/bin/podman rm -f --ignore --cidfile=%t/%n.ctr-id Type=notify NotifyAccess=all @@ -398,8 +434,11 @@ RequiresMountsFor=/var/run/containers/storage [Service] Environment=PODMAN_SYSTEMD_UNIT=%n Restart=always -TimeoutStopSec=10 -ExecStart=/usr/bin/podman run --cgroups=no-conmon --rm --sdnotify=conmon -d --conmon-pidfile=foo --cidfile=foo awesome-image:latest podman run --cgroups=foo --conmon-pidfile=foo --cidfile=foo alpine +TimeoutStopSec=70 +ExecStartPre=/bin/rm -f %t/%n.ctr-id +ExecStart=/usr/bin/podman run --cidfile=%t/%n.ctr-id --cgroups=no-conmon --rm --sdnotify=conmon -d --conmon-pidfile=foo awesome-image:latest podman run --cgroups=foo --conmon-pidfile=foo --cidfile=foo alpine +ExecStop=/usr/bin/podman stop --ignore --cidfile=%t/%n.ctr-id +ExecStopPost=/usr/bin/podman rm -f --ignore --cidfile=%t/%n.ctr-id Type=notify NotifyAccess=all @@ -420,8 +459,11 @@ RequiresMountsFor=/var/run/containers/storage [Service] Environment=PODMAN_SYSTEMD_UNIT=%n Restart=always -TimeoutStopSec=10 -ExecStart=/usr/bin/podman run --cgroups=no-conmon --rm --pod-id-file %t/pod-foobar.pod-id-file --sdnotify=conmon -d --conmon-pidfile=foo --cidfile=foo awesome-image:latest podman run --cgroups=foo --conmon-pidfile=foo --cidfile=foo --pod-id-file /tmp/pod-foobar.pod-id-file alpine +TimeoutStopSec=70 +ExecStartPre=/bin/rm -f %t/%n.ctr-id +ExecStart=/usr/bin/podman run --cidfile=%t/%n.ctr-id --cgroups=no-conmon --rm --pod-id-file %t/pod-foobar.pod-id-file --sdnotify=conmon -d --conmon-pidfile=foo awesome-image:latest podman run --cgroups=foo --conmon-pidfile=foo --cidfile=foo --pod-id-file /tmp/pod-foobar.pod-id-file alpine +ExecStop=/usr/bin/podman stop --ignore --cidfile=%t/%n.ctr-id +ExecStopPost=/usr/bin/podman rm -f --ignore --cidfile=%t/%n.ctr-id Type=notify NotifyAccess=all @@ -443,8 +485,11 @@ RequiresMountsFor=/var/run/containers/storage Environment=PODMAN_SYSTEMD_UNIT=%n Environment=FOO=abc "BAR=my test" USER=%%a Restart=always -TimeoutStopSec=10 -ExecStart=/usr/bin/podman run --cgroups=no-conmon --rm --sdnotify=conmon -d --env FOO --env=BAR --env=MYENV=2 -e USER awesome-image:latest +TimeoutStopSec=70 +ExecStartPre=/bin/rm -f %t/%n.ctr-id +ExecStart=/usr/bin/podman run --cidfile=%t/%n.ctr-id --cgroups=no-conmon --rm --sdnotify=conmon -d --env FOO --env=BAR --env=MYENV=2 -e USER awesome-image:latest +ExecStop=/usr/bin/podman stop --ignore --cidfile=%t/%n.ctr-id +ExecStopPost=/usr/bin/podman rm -f --ignore --cidfile=%t/%n.ctr-id Type=notify NotifyAccess=all diff --git a/pkg/systemd/generate/pods.go b/pkg/systemd/generate/pods.go index d49828884..1b92649e8 100644 --- a/pkg/systemd/generate/pods.go +++ b/pkg/systemd/generate/pods.go @@ -323,7 +323,7 @@ func executePodTemplate(info *podInfo, options entities.GenerateSystemdOptions) info.ExecStop = "{{{{.Executable}}}} {{{{if .RootFlags}}}}{{{{ .RootFlags}}}} {{{{end}}}}pod stop --ignore --pod-id-file {{{{.PodIDFile}}}} {{{{if (ge .StopTimeout 0)}}}}-t {{{{.StopTimeout}}}}{{{{end}}}}" info.ExecStopPost = "{{{{.Executable}}}} {{{{if .RootFlags}}}}{{{{ .RootFlags}}}} {{{{end}}}}pod rm --ignore -f --pod-id-file {{{{.PodIDFile}}}}" } - info.TimeoutStopSec = info.StopTimeout + info.TimeoutStopSec = minTimeoutStopSec + info.StopTimeout if info.PodmanVersion == "" { info.PodmanVersion = version.Version.String() diff --git a/pkg/systemd/generate/pods_test.go b/pkg/systemd/generate/pods_test.go index 49a4ed23f..4b8a9ffd5 100644 --- a/pkg/systemd/generate/pods_test.go +++ b/pkg/systemd/generate/pods_test.go @@ -54,7 +54,7 @@ Before=container-1.service container-2.service [Service] Environment=PODMAN_SYSTEMD_UNIT=%n Restart=always -TimeoutStopSec=42 +TimeoutStopSec=102 ExecStart=/usr/bin/podman start jadda-jadda-infra ExecStop=/usr/bin/podman stop -t 42 jadda-jadda-infra ExecStopPost=/usr/bin/podman stop -t 42 jadda-jadda-infra @@ -82,7 +82,7 @@ Before=container-1.service container-2.service [Service] Environment=PODMAN_SYSTEMD_UNIT=%n Restart=on-failure -TimeoutStopSec=10 +TimeoutStopSec=70 ExecStartPre=/bin/rm -f %t/pod-123abc.pid %t/pod-123abc.pod-id ExecStartPre=/usr/bin/podman pod create --infra-conmon-pidfile %t/pod-123abc.pid --pod-id-file %t/pod-123abc.pod-id --name foo "bar=arg with space" --replace ExecStart=/usr/bin/podman pod start --pod-id-file %t/pod-123abc.pod-id @@ -110,7 +110,7 @@ Before=container-1.service container-2.service [Service] Environment=PODMAN_SYSTEMD_UNIT=%n Restart=on-failure -TimeoutStopSec=10 +TimeoutStopSec=70 ExecStartPre=/bin/rm -f %t/pod-123abc.pid %t/pod-123abc.pod-id ExecStartPre=/usr/bin/podman --events-backend none --runroot /root pod create --infra-conmon-pidfile %t/pod-123abc.pid --pod-id-file %t/pod-123abc.pod-id --name foo "bar=arg with space" --replace ExecStart=/usr/bin/podman --events-backend none --runroot /root pod start --pod-id-file %t/pod-123abc.pod-id @@ -138,7 +138,7 @@ Before=container-1.service container-2.service [Service] Environment=PODMAN_SYSTEMD_UNIT=%n Restart=on-failure -TimeoutStopSec=10 +TimeoutStopSec=70 ExecStartPre=/bin/rm -f %t/pod-123abc.pid %t/pod-123abc.pod-id ExecStartPre=/usr/bin/podman pod create --infra-conmon-pidfile %t/pod-123abc.pid --pod-id-file %t/pod-123abc.pod-id --name foo --replace ExecStart=/usr/bin/podman pod start --pod-id-file %t/pod-123abc.pod-id @@ -166,7 +166,7 @@ Before=container-1.service container-2.service [Service] Environment=PODMAN_SYSTEMD_UNIT=%n Restart=on-failure -TimeoutStopSec=10 +TimeoutStopSec=70 ExecStartPre=/bin/rm -f %t/pod-123abc.pid %t/pod-123abc.pod-id ExecStartPre=/usr/bin/podman pod create --infra-conmon-pidfile %t/pod-123abc.pid --pod-id-file %t/pod-123abc.pod-id --name foo --label key={{someval}} --replace ExecStart=/usr/bin/podman pod start --pod-id-file %t/pod-123abc.pod-id diff --git a/pkg/util/utils.go b/pkg/util/utils.go index 63fad0286..208d815d9 100644 --- a/pkg/util/utils.go +++ b/pkg/util/utils.go @@ -520,7 +520,7 @@ func WriteStorageConfigFile(storageOpts *stypes.StoreOptions, storageConf string // ParseInputTime takes the users input and to determine if it is valid and // returns a time format and error. The input is compared to known time formats // or a duration which implies no-duration -func ParseInputTime(inputTime string) (time.Time, error) { +func ParseInputTime(inputTime string, since bool) (time.Time, error) { timeFormats := []string{time.RFC3339Nano, time.RFC3339, "2006-01-02T15:04:05", "2006-01-02T15:04:05.999999999", "2006-01-02Z07:00", "2006-01-02"} // iterate the supported time formats @@ -542,7 +542,10 @@ func ParseInputTime(inputTime string) (time.Time, error) { if err != nil { return time.Time{}, errors.Errorf("unable to interpret time value") } - return time.Now().Add(-duration), nil + if since { + return time.Now().Add(-duration), nil + } + return time.Now().Add(duration), nil } // OpenExclusiveFile opens a file for writing and ensure it doesn't already exist diff --git a/pkg/util/utils_test.go b/pkg/util/utils_test.go index 62de7509f..3d74d4c78 100644 --- a/pkg/util/utils_test.go +++ b/pkg/util/utils_test.go @@ -303,7 +303,7 @@ func TestPeriodAndQuotaToCores(t *testing.T) { } func TestParseInputTime(t *testing.T) { - tm, err := ParseInputTime("1.5") + tm, err := ParseInputTime("1.5", true) if err != nil { t.Errorf("expected error to be nil but was: %v", err) } diff --git a/test/e2e/commit_test.go b/test/e2e/commit_test.go index 0a368b10f..fbd4068f8 100644 --- a/test/e2e/commit_test.go +++ b/test/e2e/commit_test.go @@ -329,4 +329,40 @@ var _ = Describe("Podman commit", func() { session.WaitWithDefaultTimeout() Expect(session.OutputToString()).To(Not(ContainSubstring(secretsString))) }) + + It("podman commit adds exposed ports", func() { + name := "testcon" + s := podmanTest.Podman([]string{"run", "--name", name, "-p", "8080:80", ALPINE, "true"}) + s.WaitWithDefaultTimeout() + Expect(s).Should(Exit(0)) + + newImageName := "newimage" + c := podmanTest.Podman([]string{"commit", name, newImageName}) + c.WaitWithDefaultTimeout() + Expect(c).Should(Exit(0)) + + inspect := podmanTest.Podman([]string{"inspect", newImageName}) + inspect.WaitWithDefaultTimeout() + Expect(inspect).Should(Exit(0)) + images := inspect.InspectImageJSON() + Expect(images).To(HaveLen(1)) + Expect(images[0].Config.ExposedPorts).To(HaveKey("80/tcp")) + + name = "testcon2" + s = podmanTest.Podman([]string{"run", "--name", name, "-d", nginx}) + s.WaitWithDefaultTimeout() + Expect(s).Should(Exit(0)) + + newImageName = "newimage2" + c = podmanTest.Podman([]string{"commit", name, newImageName}) + c.WaitWithDefaultTimeout() + Expect(c).Should(Exit(0)) + + inspect = podmanTest.Podman([]string{"inspect", newImageName}) + inspect.WaitWithDefaultTimeout() + Expect(inspect).Should(Exit(0)) + images = inspect.InspectImageJSON() + Expect(images).To(HaveLen(1)) + Expect(images[0].Config.ExposedPorts).To(HaveKey("80/tcp")) + }) }) diff --git a/test/e2e/container_inspect_test.go b/test/e2e/container_inspect_test.go index 9a95a275a..7d05b09fb 100644 --- a/test/e2e/container_inspect_test.go +++ b/test/e2e/container_inspect_test.go @@ -3,6 +3,7 @@ package integration import ( "os" + "github.com/containers/podman/v3/libpod/define" "github.com/containers/podman/v3/pkg/annotations" . "github.com/containers/podman/v3/test/utils" . "github.com/onsi/ginkgo" @@ -43,4 +44,28 @@ var _ = Describe("Podman container inspect", func() { Expect(data[0].Config.Annotations[annotations.ContainerManager]). To(Equal(annotations.ContainerManagerLibpod)) }) + + It("podman inspect shows exposed ports", func() { + name := "testcon" + session := podmanTest.Podman([]string{"run", "-d", "--stop-timeout", "0", "--expose", "8080/udp", "--name", name, ALPINE, "sleep", "inf"}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + data := podmanTest.InspectContainer(name) + + Expect(data).To(HaveLen(1)) + Expect(data[0].NetworkSettings.Ports). + To(Equal(map[string][]define.InspectHostPort{"8080/udp": nil})) + }) + + It("podman inspect shows exposed ports on image", func() { + name := "testcon" + session := podmanTest.Podman([]string{"run", "-d", "--expose", "8080", "--name", name, nginx}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + + data := podmanTest.InspectContainer(name) + Expect(data).To(HaveLen(1)) + Expect(data[0].NetworkSettings.Ports). + To(Equal(map[string][]define.InspectHostPort{"80/tcp": nil, "8080/tcp": nil})) + }) }) diff --git a/test/e2e/events_test.go b/test/e2e/events_test.go index e2a169383..46ea10c56 100644 --- a/test/e2e/events_test.go +++ b/test/e2e/events_test.go @@ -184,6 +184,19 @@ var _ = Describe("Podman events", func() { Expect(result.OutputToString()).To(ContainSubstring(name2)) Expect(result.OutputToString()).To(ContainSubstring(name3)) + // string duration in 10 seconds + untilT := time.Now().Add(time.Second * 9) + result = podmanTest.Podman([]string{"events", "--since", "30s", "--until", "10s"}) + result.Wait(11) + Expect(result).Should(Exit(0)) + tEnd := time.Now() + outDur := tEnd.Sub(untilT) + diff := outDur.Seconds() > 0 + Expect(diff).To(Equal(true)) + Expect(result.OutputToString()).To(ContainSubstring(name1)) + Expect(result.OutputToString()).To(ContainSubstring(name2)) + Expect(result.OutputToString()).To(ContainSubstring(name3)) + wg.Wait() }) }) diff --git a/test/e2e/logs_test.go b/test/e2e/logs_test.go index 0a973b802..71d30f063 100644 --- a/test/e2e/logs_test.go +++ b/test/e2e/logs_test.go @@ -145,7 +145,7 @@ var _ = Describe("Podman logs", func() { results := podmanTest.Podman([]string{"logs", "--until", "10m", cid}) results.WaitWithDefaultTimeout() Expect(results).To(Exit(0)) - Expect(len(results.OutputToStringArray())).To(Equal(0)) + Expect(len(results.OutputToStringArray())).To(Equal(3)) }) It("until time NOW: "+log, func() { diff --git a/test/e2e/run_test.go b/test/e2e/run_test.go index 6a2e2ed8d..846da283d 100644 --- a/test/e2e/run_test.go +++ b/test/e2e/run_test.go @@ -1331,10 +1331,10 @@ USER mail`, BB) } curCgroupsBytes, err := ioutil.ReadFile("/proc/self/cgroup") - Expect(err).To(BeNil()) - var curCgroups string = string(curCgroupsBytes) + Expect(err).ShouldNot(HaveOccurred()) + var curCgroups = string(curCgroupsBytes) fmt.Printf("Output:\n%s\n", curCgroups) - Expect(curCgroups).To(Not(Equal(""))) + Expect(curCgroups).ToNot(Equal("")) ctrName := "testctr" container := podmanTest.Podman([]string{"run", "--name", ctrName, "-d", "--cgroups=disabled", ALPINE, "top"}) @@ -1345,14 +1345,14 @@ USER mail`, BB) inspectOut := podmanTest.InspectContainer(ctrName) Expect(len(inspectOut)).To(Equal(1)) pid := inspectOut[0].State.Pid - Expect(pid).To(Not(Equal(0))) + Expect(pid).ToNot(Equal(0)) Expect(inspectOut[0].HostConfig.CgroupParent).To(Equal("")) ctrCgroupsBytes, err := ioutil.ReadFile(fmt.Sprintf("/proc/%d/cgroup", pid)) - Expect(err).To(BeNil()) - var ctrCgroups string = string(ctrCgroupsBytes) + Expect(err).ShouldNot(HaveOccurred()) + var ctrCgroups = string(ctrCgroupsBytes) fmt.Printf("Output\n:%s\n", ctrCgroups) - Expect(curCgroups).To(Equal(ctrCgroups)) + Expect(ctrCgroups).To(Equal(curCgroups)) }) It("podman run with cgroups=enabled makes cgroups", func() { diff --git a/test/e2e/volume_create_test.go b/test/e2e/volume_create_test.go index d9c805f46..3be1486d8 100644 --- a/test/e2e/volume_create_test.go +++ b/test/e2e/volume_create_test.go @@ -79,6 +79,50 @@ var _ = Describe("Podman volume create", func() { Expect(check.OutputToString()).To(ContainSubstring("hello")) }) + It("podman create and import volume", func() { + if podmanTest.RemoteTest { + Skip("Volume export check does not work with a remote client") + } + + session := podmanTest.Podman([]string{"volume", "create", "my_vol"}) + session.WaitWithDefaultTimeout() + volName := session.OutputToString() + Expect(session).Should(Exit(0)) + + session = podmanTest.Podman([]string{"run", "--volume", volName + ":/data", ALPINE, "sh", "-c", "echo hello >> " + "/data/test"}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + + session = podmanTest.Podman([]string{"volume", "export", volName, "--output=hello.tar"}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + + session = podmanTest.Podman([]string{"volume", "create", "my_vol2"}) + session.WaitWithDefaultTimeout() + volName = session.OutputToString() + Expect(session).Should(Exit(0)) + + session = podmanTest.Podman([]string{"volume", "import", "my_vol2", "hello.tar"}) + session.WaitWithDefaultTimeout() + volName = session.OutputToString() + Expect(session).Should(Exit(0)) + + session = podmanTest.Podman([]string{"run", "--volume", "my_vol2:/data", ALPINE, "cat", "/data/test"}) + session.WaitWithDefaultTimeout() + Expect(session.OutputToString()).To(ContainSubstring("hello")) + }) + + It("podman import volume should fail", func() { + // try import on volume or source which does not exists + if podmanTest.RemoteTest { + Skip("Volume export check does not work with a remote client") + } + + session := podmanTest.Podman([]string{"volume", "import", "notfound", "notfound.tar"}) + session.WaitWithDefaultTimeout() + Expect(session).To(ExitWithError()) + }) + It("podman create volume with bad volume option", func() { session := podmanTest.Podman([]string{"volume", "create", "--opt", "badOpt=bad"}) session.WaitWithDefaultTimeout() diff --git a/test/system/130-kill.bats b/test/system/130-kill.bats index 3770eac27..d85f0a6a9 100644 --- a/test/system/130-kill.bats +++ b/test/system/130-kill.bats @@ -33,7 +33,7 @@ load helpers exec 5<$fifo # First container emits READY when ready; wait for it. - read -t 10 -u 5 ready + read -t 60 -u 5 ready is "$ready" "READY" "first log message from container" # Helper function: send the given signal, verify that it's received. @@ -42,7 +42,7 @@ load helpers local signum=${2:-$1} # e.g. if signal=HUP, we expect to see '1' run_podman kill -s $signal $cid - read -t 10 -u 5 actual || die "Timed out: no ACK for kill -s $signal" + read -t 60 -u 5 actual || die "Timed out: no ACK for kill -s $signal" is "$actual" "got: $signum" "Signal $signal handled by container" } diff --git a/test/system/160-volumes.bats b/test/system/160-volumes.bats index 9a852db89..f6dc3f0af 100644 --- a/test/system/160-volumes.bats +++ b/test/system/160-volumes.bats @@ -186,6 +186,22 @@ EOF } +# Podman volume import test +@test "podman volume import test" { + skip_if_remote "volumes import is not applicable on podman-remote" + run_podman volume create my_vol + run_podman run --rm -v my_vol:/data $IMAGE sh -c "echo hello >> /data/test" + run_podman volume create my_vol2 + run_podman volume export my_vol --output=hello.tar + # we want to use `run_podman volume export my_vol` but run_podman is wrapping EOF + cat hello.tar | run_podman volume import my_vol2 - + run_podman run --rm -v my_vol2:/data $IMAGE sh -c "cat /data/test" + is "$output" "hello" "output from second container" + run_podman volume rm my_vol + run_podman volume rm my_vol2 +} + + # Confirm that container sees the correct id @test "podman volume with --userns=keep-id" { is_rootless || skip "only meaningful when run rootless" diff --git a/test/system/250-systemd.bats b/test/system/250-systemd.bats index 37e5fa2f9..5d4ae4cb1 100644 --- a/test/system/250-systemd.bats +++ b/test/system/250-systemd.bats @@ -46,11 +46,20 @@ function service_setup() { # Helper to stop a systemd service running a container function service_cleanup() { + local status=$1 run systemctl stop "$SERVICE_NAME" if [ $status -ne 0 ]; then die "Error stopping systemd unit $SERVICE_NAME, output: $output" fi + if [[ -z "$status" ]]; then + run systemctl is-active "$SERVICE_NAME" + if [ $status -ne 0 ]; then + die "Error checking stauts of systemd unit $SERVICE_NAME, output: $output" + fi + is "$output" "$status" "$SERVICE_NAME not in expected state" + fi + rm -f "$UNIT_FILE" systemctl daemon-reload } @@ -60,7 +69,8 @@ function service_cleanup() { @test "podman generate - systemd - basic" { cname=$(random_string) # See #7407 for --pull=always. - run_podman create --pull=always --name $cname --label "io.containers.autoupdate=registry" $IMAGE top + run_podman create --pull=always --name $cname --label "io.containers.autoupdate=registry" $IMAGE \ + sh -c "trap 'echo Received SIGTERM, finishing; exit' SIGTERM; echo WAITING; while :; do sleep 0.1; done" # Start systemd service to run this container service_setup @@ -68,7 +78,7 @@ function service_cleanup() { # Give container time to start; make sure output looks top-like sleep 2 run_podman logs $cname - is "$output" ".*Load average:.*" "running container 'top'-like output" + is "$output" ".*WAITING.*" "running is waiting for signal" # Exercise `podman auto-update`. # TODO: this will at least run auto-update code but won't perform an update @@ -77,7 +87,8 @@ function service_cleanup() { run_podman auto-update # All good. Stop service, clean up. - service_cleanup + # Also make sure the service is in the `inactive` state (see #11304). + service_cleanup inactive } @test "podman autoupdate local" { @@ -125,17 +136,4 @@ function service_cleanup() { service_cleanup } -@test "podman generate systemd - stop-signal" { - cname=$(random_string) - run_podman create --name $cname --stop-signal=42 $IMAGE - run_podman generate systemd --new $cname - is "$output" ".*KillSignal=42.*" "KillSignal is set" - - # Regression test for #11304: systemd wants a custom stop-signal. - run_podman rm -f $cname - run_podman create --name $cname --systemd=true $IMAGE systemd - run_podman generate systemd --new $cname - is "$output" ".*KillSignal=37.*" "KillSignal is set" -} - # vim: filetype=sh diff --git a/test/system/330-corrupt-images.bats b/test/system/330-corrupt-images.bats index 2ee5eee9c..eeffff3ec 100644 --- a/test/system/330-corrupt-images.bats +++ b/test/system/330-corrupt-images.bats @@ -13,7 +13,8 @@ if [ -z "${PODMAN_CORRUPT_TEST_WORKDIR}" ]; then export PODMAN_CORRUPT_TEST_WORKDIR=$(mktemp -d --tmpdir=${BATS_TMPDIR:-${TMPDIR:-/tmp}} podman_corrupt_test.XXXXXX) fi -PODMAN_CORRUPT_TEST_IMAGE_FQIN=quay.io/libpod/alpine@sha256:634a8f35b5f16dcf4aaa0822adc0b1964bb786fca12f6831de8ddc45e5986a00 +PODMAN_CORRUPT_TEST_IMAGE_CANONICAL_FQIN=quay.io/libpod/alpine@sha256:634a8f35b5f16dcf4aaa0822adc0b1964bb786fca12f6831de8ddc45e5986a00 +PODMAN_CORRUPT_TEST_IMAGE_TAGGED_FQIN=${PODMAN_CORRUPT_TEST_IMAGE_CANONICAL_FQIN%%@sha256:*}:test PODMAN_CORRUPT_TEST_IMAGE_ID=961769676411f082461f9ef46626dd7a2d1e2b2a38e6a44364bcbecf51e66dd4 # All tests in this file (and ONLY in this file) run with a custom rootdir @@ -59,7 +60,7 @@ function _corrupt_image_test() { run_podman load -i ${PODMAN_CORRUPT_TEST_WORKDIR}/img.tar # "podman load" restores it without a tag, which (a) causes rmi-by-name # to fail, and (b) causes "podman images" to exit 0 instead of 125 - run_podman tag ${PODMAN_CORRUPT_TEST_IMAGE_ID} ${PODMAN_CORRUPT_TEST_IMAGE_FQIN} + run_podman tag ${PODMAN_CORRUPT_TEST_IMAGE_ID} ${PODMAN_CORRUPT_TEST_IMAGE_TAGGED_FQIN} # shortcut variable name local id=${PODMAN_CORRUPT_TEST_IMAGE_ID} @@ -91,9 +92,9 @@ function _corrupt_image_test() { @test "podman corrupt images - initialize" { # Pull once, save cached copy. - run_podman pull $PODMAN_CORRUPT_TEST_IMAGE_FQIN + run_podman pull $PODMAN_CORRUPT_TEST_IMAGE_CANONICAL_FQIN run_podman save -o ${PODMAN_CORRUPT_TEST_WORKDIR}/img.tar \ - $PODMAN_CORRUPT_TEST_IMAGE_FQIN + $PODMAN_CORRUPT_TEST_IMAGE_CANONICAL_FQIN } # END first "test" does a one-time pull of our desired image @@ -104,8 +105,8 @@ function _corrupt_image_test() { _corrupt_image_test "rmi -f ${PODMAN_CORRUPT_TEST_IMAGE_ID}" } -@test "podman corrupt images - rmi -f <image-name>" { - _corrupt_image_test "rmi -f ${PODMAN_CORRUPT_TEST_IMAGE_FQIN}" +@test "podman corrupt images - rmi -f <image-tagged-name>" { + _corrupt_image_test "rmi -f ${PODMAN_CORRUPT_TEST_IMAGE_TAGGED_FQIN}" } @test "podman corrupt images - rmi -f -a" { diff --git a/vendor/github.com/containers/common/libimage/image.go b/vendor/github.com/containers/common/libimage/image.go index c47e63339..b4623a870 100644 --- a/vendor/github.com/containers/common/libimage/image.go +++ b/vendor/github.com/containers/common/libimage/image.go @@ -448,14 +448,24 @@ func (i *Image) removeRecursive(ctx context.Context, rmMap map[string]*RemoveIma return parent.removeRecursive(ctx, rmMap, processedIDs, "", options) } +var errTagDigest = errors.New("tag by digest not supported") + // Tag the image with the specified name and store it in the local containers // storage. The name is normalized according to the rules of NormalizeName. func (i *Image) Tag(name string) error { + if strings.HasPrefix(name, "sha256:") { // ambiguous input + return errors.Wrap(errTagDigest, name) + } + ref, err := NormalizeName(name) if err != nil { return errors.Wrapf(err, "error normalizing name %q", name) } + if _, isDigested := ref.(reference.Digested); isDigested { + return errors.Wrap(errTagDigest, name) + } + logrus.Debugf("Tagging image %s with %q", i.ID(), ref.String()) if i.runtime.eventChannel != nil { defer i.runtime.writeEvent(&Event{ID: i.ID(), Name: name, Time: time.Now(), Type: EventTypeImageTag}) @@ -480,7 +490,7 @@ var errUntagDigest = errors.New("untag by digest not supported") // the local containers storage. The name is normalized according to the rules // of NormalizeName. func (i *Image) Untag(name string) error { - if strings.HasPrefix(name, "sha256:") { + if strings.HasPrefix(name, "sha256:") { // ambiguous input return errors.Wrap(errUntagDigest, name) } @@ -488,6 +498,17 @@ func (i *Image) Untag(name string) error { if err != nil { return errors.Wrapf(err, "error normalizing name %q", name) } + + // FIXME: this is breaking Podman CI but must be re-enabled once + // c/storage supports alterting the digests of an image. Then, + // Podman will do the right thing. + // + // !!! Also make sure to re-enable the tests !!! + // + // if _, isDigested := ref.(reference.Digested); isDigested { + // return errors.Wrap(errUntagDigest, name) + // } + name = ref.String() logrus.Debugf("Untagging %q from image %s", ref.String(), i.ID()) diff --git a/vendor/github.com/containers/common/pkg/auth/auth.go b/vendor/github.com/containers/common/pkg/auth/auth.go index 093da0299..0934b155f 100644 --- a/vendor/github.com/containers/common/pkg/auth/auth.go +++ b/vendor/github.com/containers/common/pkg/auth/auth.go @@ -104,7 +104,6 @@ func Login(ctx context.Context, systemContext *types.SystemContext, opts *LoginO return errors.Wrap(err, "get credentials for repository") } } else { - // nolint: staticcheck authConfig, err = config.GetCredentials(systemContext, registry) if err != nil { return errors.Wrap(err, "get credentials") @@ -321,7 +320,6 @@ func Logout(systemContext *types.SystemContext, opts *LogoutOptions, args []stri return errors.Wrap(err, "get credentials for repository") } } else { - // nolint: staticcheck authConfig, err = config.GetCredentials(systemContext, registry) if err != nil { return errors.Wrap(err, "get credentials") diff --git a/vendor/github.com/containers/common/pkg/config/config.go b/vendor/github.com/containers/common/pkg/config/config.go index 008cfb642..e554bac70 100644 --- a/vendor/github.com/containers/common/pkg/config/config.go +++ b/vendor/github.com/containers/common/pkg/config/config.go @@ -274,6 +274,9 @@ type EngineConfig struct { // MachineEnabled indicates if Podman is running in a podman-machine VM MachineEnabled bool `toml:"machine_enabled,omitempty"` + // MachineImage is the image used when creating a podman-machine VM + MachineImage string `toml:"machine_image,omitempty"` + // MultiImageArchive - if true, the container engine allows for storing // archives (e.g., of the docker-archive transport) with multiple // images. By default, Podman creates single-image archives. @@ -691,8 +694,8 @@ func (c *Config) Validate() error { } func (c *EngineConfig) findRuntime() string { - // Search for crun first followed by runc and kata - for _, name := range []string{"crun", "runc", "kata"} { + // Search for crun first followed by runc, kata, runsc + for _, name := range []string{"crun", "runc", "kata", "runsc"} { for _, v := range c.OCIRuntimes[name] { if _, err := os.Stat(v); err == nil { return name diff --git a/vendor/github.com/containers/common/pkg/config/containers.conf b/vendor/github.com/containers/common/pkg/config/containers.conf index a83aa9407..0068a9a17 100644 --- a/vendor/github.com/containers/common/pkg/config/containers.conf +++ b/vendor/github.com/containers/common/pkg/config/containers.conf @@ -61,7 +61,7 @@ default_capabilities = [ # A list of sysctls to be set in containers by default, # specified as "name=value", -# for example:"net.ipv4.ping_group_range = 0 0". +# for example:"net.ipv4.ping_group_range=0 0". # default_sysctls = [ "net.ipv4.ping_group_range=0 0", @@ -381,6 +381,10 @@ default_sysctls = [ # #machine_enabled = false +# The image used when creating a podman-machine VM. +# +#machine_image = "testing" + # MultiImageArchive - if true, the container engine allows for storing archives # (e.g., of the docker-archive transport) with multiple images. By default, # Podman creates single-image archives. diff --git a/vendor/github.com/containers/common/pkg/config/default.go b/vendor/github.com/containers/common/pkg/config/default.go index a16dd0e02..66531a2ba 100644 --- a/vendor/github.com/containers/common/pkg/config/default.go +++ b/vendor/github.com/containers/common/pkg/config/default.go @@ -105,8 +105,6 @@ const ( DefaultApparmorProfile = apparmor.Profile // SystemdCgroupsManager represents systemd native cgroup manager SystemdCgroupsManager = "systemd" - // DefaultLogDriver is the default type of log files - DefaultLogDriver = "k8s-file" // DefaultLogSizeMax is the default value for the maximum log size // allowed for a container. Negative values mean that no limit is imposed. DefaultLogSizeMax = -1 @@ -339,6 +337,7 @@ func defaultConfigFromMemory() (*EngineConfig, error) { // constants. c.LockType = "shm" c.MachineEnabled = false + c.MachineImage = "testing" c.ChownCopiedFiles = true @@ -549,6 +548,7 @@ func (c *Config) LogDriver() string { return c.Containers.LogDriver } +// MachineEnabled returns if podman is running inside a VM or not func (c *Config) MachineEnabled() bool { return c.Engine.MachineEnabled } @@ -558,3 +558,9 @@ func (c *Config) MachineEnabled() bool { func (c *Config) RootlessNetworking() string { return c.Containers.RootlessNetworking } + +// MachineImage returns the image to be +// used when creating a podman-machine VM +func (c *Config) MachineImage() string { + return c.Engine.MachineImage +} diff --git a/vendor/github.com/containers/common/pkg/config/nosystemd.go b/vendor/github.com/containers/common/pkg/config/nosystemd.go index 6e39a6ccd..2a3b6fb35 100644 --- a/vendor/github.com/containers/common/pkg/config/nosystemd.go +++ b/vendor/github.com/containers/common/pkg/config/nosystemd.go @@ -1,7 +1,12 @@ -// +build !systemd +// +build !systemd !cgo package config +const ( + // DefaultLogDriver is the default type of log files + DefaultLogDriver = "k8s-file" +) + func defaultCgroupManager() string { return CgroupfsCgroupsManager } diff --git a/vendor/github.com/containers/common/pkg/config/systemd.go b/vendor/github.com/containers/common/pkg/config/systemd.go index ed014126b..fab3ea437 100644 --- a/vendor/github.com/containers/common/pkg/config/systemd.go +++ b/vendor/github.com/containers/common/pkg/config/systemd.go @@ -1,4 +1,4 @@ -// +build systemd +// +build systemd,cgo package config @@ -9,11 +9,19 @@ import ( "github.com/containers/common/pkg/cgroupv2" "github.com/containers/storage/pkg/unshare" + "github.com/coreos/go-systemd/v22/sdjournal" ) var ( - systemdOnce sync.Once - usesSystemd bool + systemdOnce sync.Once + usesSystemd bool + journaldOnce sync.Once + usesJournald bool +) + +const ( + // DefaultLogDriver is the default type of log files + DefaultLogDriver = "journald" ) func defaultCgroupManager() string { @@ -29,20 +37,17 @@ func defaultCgroupManager() string { } func defaultEventsLogger() string { - if useSystemd() { + if useJournald() { return "journald" } return "file" } func defaultLogDriver() string { - // If we decide to change the default for logdriver, it should be done here. - if useSystemd() { - return DefaultLogDriver + if useJournald() { + return "journald" } - - return DefaultLogDriver - + return "k8s-file" } func useSystemd() bool { @@ -56,3 +61,19 @@ func useSystemd() bool { }) return usesSystemd } + +func useJournald() bool { + journaldOnce.Do(func() { + if !useSystemd() { + return + } + journal, err := sdjournal.NewJournal() + if err != nil { + return + } + journal.Close() + usesJournald = true + return + }) + return usesJournald +} diff --git a/vendor/github.com/containers/common/pkg/parse/parse.go b/vendor/github.com/containers/common/pkg/parse/parse.go index 1a25957d6..02e670c50 100644 --- a/vendor/github.com/containers/common/pkg/parse/parse.go +++ b/vendor/github.com/containers/common/pkg/parse/parse.go @@ -5,6 +5,7 @@ package parse import ( "os" + "path" "path/filepath" "strings" @@ -155,7 +156,7 @@ func ValidateVolumeCtrDir(ctrDir string) error { if ctrDir == "" { return errors.New("container directory cannot be empty") } - if !filepath.IsAbs(ctrDir) { + if !path.IsAbs(ctrDir) { return errors.Errorf("invalid container path %q, must be an absolute path", ctrDir) } return nil diff --git a/vendor/github.com/containers/common/version/version.go b/vendor/github.com/containers/common/version/version.go index 1e9e48f33..572fe9bbd 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.42.1" +const Version = "0.43.2" diff --git a/vendor/github.com/fsnotify/fsnotify/.mailmap b/vendor/github.com/fsnotify/fsnotify/.mailmap new file mode 100644 index 000000000..a04f2907f --- /dev/null +++ b/vendor/github.com/fsnotify/fsnotify/.mailmap @@ -0,0 +1,2 @@ +Chris Howey <howeyc@gmail.com> <chris@howey.me> +Nathan Youngman <git@nathany.com> <4566+nathany@users.noreply.github.com> diff --git a/vendor/github.com/fsnotify/fsnotify/.travis.yml b/vendor/github.com/fsnotify/fsnotify/.travis.yml deleted file mode 100644 index a9c30165c..000000000 --- a/vendor/github.com/fsnotify/fsnotify/.travis.yml +++ /dev/null @@ -1,36 +0,0 @@ -sudo: false -language: go - -go: - - "stable" - - "1.11.x" - - "1.10.x" - - "1.9.x" - -matrix: - include: - - go: "stable" - env: GOLINT=true - allow_failures: - - go: tip - fast_finish: true - - -before_install: - - if [ ! -z "${GOLINT}" ]; then go get -u golang.org/x/lint/golint; fi - -script: - - go test --race ./... - -after_script: - - test -z "$(gofmt -s -l -w . | tee /dev/stderr)" - - if [ ! -z "${GOLINT}" ]; then echo running golint; golint --set_exit_status ./...; else echo skipping golint; fi - - go vet ./... - -os: - - linux - - osx - - windows - -notifications: - email: false diff --git a/vendor/github.com/fsnotify/fsnotify/AUTHORS b/vendor/github.com/fsnotify/fsnotify/AUTHORS index 5ab5d41c5..6cbabe5ef 100644 --- a/vendor/github.com/fsnotify/fsnotify/AUTHORS +++ b/vendor/github.com/fsnotify/fsnotify/AUTHORS @@ -4,35 +4,44 @@ # You can update this list using the following command: # -# $ git shortlog -se | awk '{print $2 " " $3 " " $4}' +# $ (head -n10 AUTHORS && git shortlog -se | sed -E 's/^\s+[0-9]+\t//') | tee AUTHORS # Please keep the list sorted. Aaron L <aaron@bettercoder.net> Adrien Bustany <adrien@bustany.org> +Alexey Kazakov <alkazako@redhat.com> Amit Krishnan <amit.krishnan@oracle.com> Anmol Sethi <me@anmol.io> Bjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com> +Brian Goff <cpuguy83@gmail.com> Bruno Bigras <bigras.bruno@gmail.com> Caleb Spare <cespare@gmail.com> Case Nelson <case@teammating.com> -Chris Howey <chris@howey.me> <howeyc@gmail.com> +Chris Howey <howeyc@gmail.com> Christoffer Buchholz <christoffer.buchholz@gmail.com> Daniel Wagner-Hall <dawagner@gmail.com> Dave Cheney <dave@cheney.net> +Eric Lin <linxiulei@gmail.com> Evan Phoenix <evan@fallingsnow.net> Francisco Souza <f@souza.cc> +Gautam Dey <gautam.dey77@gmail.com> Hari haran <hariharan.uno@gmail.com> -John C Barstow +Ichinose Shogo <shogo82148@gmail.com> +Johannes Ebke <johannes@ebke.org> +John C Barstow <jbowtie@amathaine.com> Kelvin Fo <vmirage@gmail.com> Ken-ichirou MATSUZAWA <chamas@h4.dion.ne.jp> Matt Layher <mdlayher@gmail.com> +Matthias Stone <matthias@bellstone.ca> Nathan Youngman <git@nathany.com> Nickolai Zeldovich <nickolai@csail.mit.edu> +Oliver Bristow <evilumbrella+github@gmail.com> Patrick <patrick@dropbox.com> Paul Hammond <paul@paulhammond.org> Pawel Knap <pawelknap88@gmail.com> Pieter Droogendijk <pieter@binky.org.uk> +Pratik Shinde <pratikshinde320@gmail.com> Pursuit92 <JoshChase@techpursuit.net> Riku Voipio <riku.voipio@linaro.org> Rob Figueiredo <robfig@gmail.com> @@ -41,6 +50,7 @@ Slawek Ligus <root@ooz.ie> Soge Zhang <zhssoge@gmail.com> Tiffany Jernigan <tiffany.jernigan@intel.com> Tilak Sharma <tilaks@google.com> +Tobias Klauser <tobias.klauser@gmail.com> Tom Payne <twpayne@gmail.com> Travis Cline <travis.cline@gmail.com> Tudor Golubenco <tudor.g@gmail.com> diff --git a/vendor/github.com/fsnotify/fsnotify/CHANGELOG.md b/vendor/github.com/fsnotify/fsnotify/CHANGELOG.md index be4d7ea2c..a438fe4b4 100644 --- a/vendor/github.com/fsnotify/fsnotify/CHANGELOG.md +++ b/vendor/github.com/fsnotify/fsnotify/CHANGELOG.md @@ -1,6 +1,28 @@ # Changelog -## v1.4.7 / 2018-01-09 +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [Unreleased] + +## [1.5.1] - 2021-08-24 + +* Revert Add AddRaw to not follow symlinks + +## [1.5.0] - 2021-08-20 + +* Go: Increase minimum required version to Go 1.12 [#381](https://github.com/fsnotify/fsnotify/pull/381) +* Feature: Add AddRaw method which does not follow symlinks when adding a watch [#289](https://github.com/fsnotify/fsnotify/pull/298) +* Windows: Follow symlinks by default like on all other systems [#289](https://github.com/fsnotify/fsnotify/pull/289) +* CI: Use GitHub Actions for CI and cover go 1.12-1.17 + [#378](https://github.com/fsnotify/fsnotify/pull/378) + [#381](https://github.com/fsnotify/fsnotify/pull/381) + [#385](https://github.com/fsnotify/fsnotify/pull/385) +* Go 1.14+: Fix unsafe pointer conversion [#325](https://github.com/fsnotify/fsnotify/pull/325) + +## [1.4.7] - 2018-01-09 * BSD/macOS: Fix possible deadlock on closing the watcher on kqueue (thanks @nhooyr and @glycerine) * Tests: Fix missing verb on format string (thanks @rchiossi) @@ -10,62 +32,62 @@ * Linux: Properly handle inotify's IN_Q_OVERFLOW event (thanks @zeldovich) * Docs: replace references to OS X with macOS -## v1.4.2 / 2016-10-10 +## [1.4.2] - 2016-10-10 * Linux: use InotifyInit1 with IN_CLOEXEC to stop leaking a file descriptor to a child process when using fork/exec [#178](https://github.com/fsnotify/fsnotify/pull/178) (thanks @pattyshack) -## v1.4.1 / 2016-10-04 +## [1.4.1] - 2016-10-04 * Fix flaky inotify stress test on Linux [#177](https://github.com/fsnotify/fsnotify/pull/177) (thanks @pattyshack) -## v1.4.0 / 2016-10-01 +## [1.4.0] - 2016-10-01 * add a String() method to Event.Op [#165](https://github.com/fsnotify/fsnotify/pull/165) (thanks @oozie) -## v1.3.1 / 2016-06-28 +## [1.3.1] - 2016-06-28 * Windows: fix for double backslash when watching the root of a drive [#151](https://github.com/fsnotify/fsnotify/issues/151) (thanks @brunoqc) -## v1.3.0 / 2016-04-19 +## [1.3.0] - 2016-04-19 * Support linux/arm64 by [patching](https://go-review.googlesource.com/#/c/21971/) x/sys/unix and switching to to it from syscall (thanks @suihkulokki) [#135](https://github.com/fsnotify/fsnotify/pull/135) -## v1.2.10 / 2016-03-02 +## [1.2.10] - 2016-03-02 * Fix golint errors in windows.go [#121](https://github.com/fsnotify/fsnotify/pull/121) (thanks @tiffanyfj) -## v1.2.9 / 2016-01-13 +## [1.2.9] - 2016-01-13 kqueue: Fix logic for CREATE after REMOVE [#111](https://github.com/fsnotify/fsnotify/pull/111) (thanks @bep) -## v1.2.8 / 2015-12-17 +## [1.2.8] - 2015-12-17 * kqueue: fix race condition in Close [#105](https://github.com/fsnotify/fsnotify/pull/105) (thanks @djui for reporting the issue and @ppknap for writing a failing test) * inotify: fix race in test * enable race detection for continuous integration (Linux, Mac, Windows) -## v1.2.5 / 2015-10-17 +## [1.2.5] - 2015-10-17 * inotify: use epoll_create1 for arm64 support (requires Linux 2.6.27 or later) [#100](https://github.com/fsnotify/fsnotify/pull/100) (thanks @suihkulokki) * inotify: fix path leaks [#73](https://github.com/fsnotify/fsnotify/pull/73) (thanks @chamaken) * kqueue: watch for rename events on subdirectories [#83](https://github.com/fsnotify/fsnotify/pull/83) (thanks @guotie) * kqueue: avoid infinite loops from symlinks cycles [#101](https://github.com/fsnotify/fsnotify/pull/101) (thanks @illicitonion) -## v1.2.1 / 2015-10-14 +## [1.2.1] - 2015-10-14 * kqueue: don't watch named pipes [#98](https://github.com/fsnotify/fsnotify/pull/98) (thanks @evanphx) -## v1.2.0 / 2015-02-08 +## [1.2.0] - 2015-02-08 * inotify: use epoll to wake up readEvents [#66](https://github.com/fsnotify/fsnotify/pull/66) (thanks @PieterD) * inotify: closing watcher should now always shut down goroutine [#63](https://github.com/fsnotify/fsnotify/pull/63) (thanks @PieterD) * kqueue: close kqueue after removing watches, fixes [#59](https://github.com/fsnotify/fsnotify/issues/59) -## v1.1.1 / 2015-02-05 +## [1.1.1] - 2015-02-05 * inotify: Retry read on EINTR [#61](https://github.com/fsnotify/fsnotify/issues/61) (thanks @PieterD) -## v1.1.0 / 2014-12-12 +## [1.1.0] - 2014-12-12 * kqueue: rework internals [#43](https://github.com/fsnotify/fsnotify/pull/43) * add low-level functions @@ -77,22 +99,22 @@ kqueue: Fix logic for CREATE after REMOVE [#111](https://github.com/fsnotify/fsn * kqueue: fix regression in rework causing subdirectories to be watched [#48](https://github.com/fsnotify/fsnotify/issues/48) * kqueue: cleanup internal watch before sending remove event [#51](https://github.com/fsnotify/fsnotify/issues/51) -## v1.0.4 / 2014-09-07 +## [1.0.4] - 2014-09-07 * kqueue: add dragonfly to the build tags. * Rename source code files, rearrange code so exported APIs are at the top. * Add done channel to example code. [#37](https://github.com/fsnotify/fsnotify/pull/37) (thanks @chenyukang) -## v1.0.3 / 2014-08-19 +## [1.0.3] - 2014-08-19 * [Fix] Windows MOVED_TO now translates to Create like on BSD and Linux. [#36](https://github.com/fsnotify/fsnotify/issues/36) -## v1.0.2 / 2014-08-17 +## [1.0.2] - 2014-08-17 * [Fix] Missing create events on macOS. [#14](https://github.com/fsnotify/fsnotify/issues/14) (thanks @zhsso) * [Fix] Make ./path and path equivalent. (thanks @zhsso) -## v1.0.0 / 2014-08-15 +## [1.0.0] - 2014-08-15 * [API] Remove AddWatch on Windows, use Add. * Improve documentation for exported identifiers. [#30](https://github.com/fsnotify/fsnotify/issues/30) @@ -146,51 +168,51 @@ kqueue: Fix logic for CREATE after REMOVE [#111](https://github.com/fsnotify/fsn * no tests for the current implementation * not fully implemented on Windows [#93](https://github.com/howeyc/fsnotify/issues/93#issuecomment-39285195) -## v0.9.3 / 2014-12-31 +## [0.9.3] - 2014-12-31 * kqueue: cleanup internal watch before sending remove event [#51](https://github.com/fsnotify/fsnotify/issues/51) -## v0.9.2 / 2014-08-17 +## [0.9.2] - 2014-08-17 * [Backport] Fix missing create events on macOS. [#14](https://github.com/fsnotify/fsnotify/issues/14) (thanks @zhsso) -## v0.9.1 / 2014-06-12 +## [0.9.1] - 2014-06-12 * Fix data race on kevent buffer (thanks @tilaks) [#98](https://github.com/howeyc/fsnotify/pull/98) -## v0.9.0 / 2014-01-17 +## [0.9.0] - 2014-01-17 * IsAttrib() for events that only concern a file's metadata [#79][] (thanks @abustany) * [Fix] kqueue: fix deadlock [#77][] (thanks @cespare) * [NOTICE] Development has moved to `code.google.com/p/go.exp/fsnotify` in preparation for inclusion in the Go standard library. -## v0.8.12 / 2013-11-13 +## [0.8.12] - 2013-11-13 * [API] Remove FD_SET and friends from Linux adapter -## v0.8.11 / 2013-11-02 +## [0.8.11] - 2013-11-02 * [Doc] Add Changelog [#72][] (thanks @nathany) * [Doc] Spotlight and double modify events on macOS [#62][] (reported by @paulhammond) -## v0.8.10 / 2013-10-19 +## [0.8.10] - 2013-10-19 * [Fix] kqueue: remove file watches when parent directory is removed [#71][] (reported by @mdwhatcott) * [Fix] kqueue: race between Close and readEvents [#70][] (reported by @bernerdschaefer) * [Doc] specify OS-specific limits in README (thanks @debrando) -## v0.8.9 / 2013-09-08 +## [0.8.9] - 2013-09-08 * [Doc] Contributing (thanks @nathany) * [Doc] update package path in example code [#63][] (thanks @paulhammond) * [Doc] GoCI badge in README (Linux only) [#60][] * [Doc] Cross-platform testing with Vagrant [#59][] (thanks @nathany) -## v0.8.8 / 2013-06-17 +## [0.8.8] - 2013-06-17 * [Fix] Windows: handle `ERROR_MORE_DATA` on Windows [#49][] (thanks @jbowtie) -## v0.8.7 / 2013-06-03 +## [0.8.7] - 2013-06-03 * [API] Make syscall flags internal * [Fix] inotify: ignore event changes @@ -198,74 +220,74 @@ kqueue: Fix logic for CREATE after REMOVE [#111](https://github.com/fsnotify/fsn * [Fix] tests on Windows * lower case error messages -## v0.8.6 / 2013-05-23 +## [0.8.6] - 2013-05-23 * kqueue: Use EVT_ONLY flag on Darwin * [Doc] Update README with full example -## v0.8.5 / 2013-05-09 +## [0.8.5] - 2013-05-09 * [Fix] inotify: allow monitoring of "broken" symlinks (thanks @tsg) -## v0.8.4 / 2013-04-07 +## [0.8.4] - 2013-04-07 * [Fix] kqueue: watch all file events [#40][] (thanks @ChrisBuchholz) -## v0.8.3 / 2013-03-13 +## [0.8.3] - 2013-03-13 * [Fix] inoitfy/kqueue memory leak [#36][] (reported by @nbkolchin) * [Fix] kqueue: use fsnFlags for watching a directory [#33][] (reported by @nbkolchin) -## v0.8.2 / 2013-02-07 +## [0.8.2] - 2013-02-07 * [Doc] add Authors * [Fix] fix data races for map access [#29][] (thanks @fsouza) -## v0.8.1 / 2013-01-09 +## [0.8.1] - 2013-01-09 * [Fix] Windows path separators * [Doc] BSD License -## v0.8.0 / 2012-11-09 +## [0.8.0] - 2012-11-09 * kqueue: directory watching improvements (thanks @vmirage) * inotify: add `IN_MOVED_TO` [#25][] (requested by @cpisto) * [Fix] kqueue: deleting watched directory [#24][] (reported by @jakerr) -## v0.7.4 / 2012-10-09 +## [0.7.4] - 2012-10-09 * [Fix] inotify: fixes from https://codereview.appspot.com/5418045/ (ugorji) * [Fix] kqueue: preserve watch flags when watching for delete [#21][] (reported by @robfig) * [Fix] kqueue: watch the directory even if it isn't a new watch (thanks @robfig) * [Fix] kqueue: modify after recreation of file -## v0.7.3 / 2012-09-27 +## [0.7.3] - 2012-09-27 * [Fix] kqueue: watch with an existing folder inside the watched folder (thanks @vmirage) * [Fix] kqueue: no longer get duplicate CREATE events -## v0.7.2 / 2012-09-01 +## [0.7.2] - 2012-09-01 * kqueue: events for created directories -## v0.7.1 / 2012-07-14 +## [0.7.1] - 2012-07-14 * [Fix] for renaming files -## v0.7.0 / 2012-07-02 +## [0.7.0] - 2012-07-02 * [Feature] FSNotify flags * [Fix] inotify: Added file name back to event path -## v0.6.0 / 2012-06-06 +## [0.6.0] - 2012-06-06 * kqueue: watch files after directory created (thanks @tmc) -## v0.5.1 / 2012-05-22 +## [0.5.1] - 2012-05-22 * [Fix] inotify: remove all watches before Close() -## v0.5.0 / 2012-05-03 +## [0.5.0] - 2012-05-03 * [API] kqueue: return errors during watch instead of sending over channel * kqueue: match symlink behavior on Linux @@ -273,22 +295,22 @@ kqueue: Fix logic for CREATE after REMOVE [#111](https://github.com/fsnotify/fsn * [Fix] kqueue: handle EINTR (reported by @robfig) * [Doc] Godoc example [#1][] (thanks @davecheney) -## v0.4.0 / 2012-03-30 +## [0.4.0] - 2012-03-30 * Go 1 released: build with go tool * [Feature] Windows support using winfsnotify * Windows does not have attribute change notifications * Roll attribute notifications into IsModify -## v0.3.0 / 2012-02-19 +## [0.3.0] - 2012-02-19 * kqueue: add files when watch directory -## v0.2.0 / 2011-12-30 +## [0.2.0] - 2011-12-30 * update to latest Go weekly code -## v0.1.0 / 2011-10-19 +## [0.1.0] - 2011-10-19 * kqueue: add watch on file creation to match inotify * kqueue: create file event diff --git a/vendor/github.com/fsnotify/fsnotify/README.md b/vendor/github.com/fsnotify/fsnotify/README.md index b2629e522..df57b1b28 100644 --- a/vendor/github.com/fsnotify/fsnotify/README.md +++ b/vendor/github.com/fsnotify/fsnotify/README.md @@ -12,9 +12,9 @@ Cross platform: Windows, Linux, BSD and macOS. | Adapter | OS | Status | | --------------------- | -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- | -| inotify | Linux 2.6.27 or later, Android\* | Supported [![Build Status](https://travis-ci.org/fsnotify/fsnotify.svg?branch=master)](https://travis-ci.org/fsnotify/fsnotify) | -| kqueue | BSD, macOS, iOS\* | Supported [![Build Status](https://travis-ci.org/fsnotify/fsnotify.svg?branch=master)](https://travis-ci.org/fsnotify/fsnotify) | -| ReadDirectoryChangesW | Windows | Supported [![Build Status](https://travis-ci.org/fsnotify/fsnotify.svg?branch=master)](https://travis-ci.org/fsnotify/fsnotify) | +| inotify | Linux 2.6.27 or later, Android\* | Supported | +| kqueue | BSD, macOS, iOS\* | Supported | +| ReadDirectoryChangesW | Windows | Supported | | FSEvents | macOS | [Planned](https://github.com/fsnotify/fsnotify/issues/11) | | FEN | Solaris 11 | [In Progress](https://github.com/fsnotify/fsnotify/issues/12) | | fanotify | Linux 2.6.37+ | [Planned](https://github.com/fsnotify/fsnotify/issues/114) | diff --git a/vendor/github.com/fsnotify/fsnotify/fen.go b/vendor/github.com/fsnotify/fsnotify/fen.go index ced39cb88..b3ac3d8f5 100644 --- a/vendor/github.com/fsnotify/fsnotify/fen.go +++ b/vendor/github.com/fsnotify/fsnotify/fen.go @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +//go:build solaris // +build solaris package fsnotify diff --git a/vendor/github.com/fsnotify/fsnotify/fsnotify.go b/vendor/github.com/fsnotify/fsnotify/fsnotify.go index 89cab046d..0f4ee52e8 100644 --- a/vendor/github.com/fsnotify/fsnotify/fsnotify.go +++ b/vendor/github.com/fsnotify/fsnotify/fsnotify.go @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +//go:build !plan9 // +build !plan9 // Package fsnotify provides a platform-independent interface for file system notifications. diff --git a/vendor/github.com/fsnotify/fsnotify/go.mod b/vendor/github.com/fsnotify/fsnotify/go.mod index ff11e13f2..54089e48b 100644 --- a/vendor/github.com/fsnotify/fsnotify/go.mod +++ b/vendor/github.com/fsnotify/fsnotify/go.mod @@ -2,4 +2,6 @@ module github.com/fsnotify/fsnotify go 1.13 -require golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9 +require golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c + +retract v1.5.0 diff --git a/vendor/github.com/fsnotify/fsnotify/go.sum b/vendor/github.com/fsnotify/fsnotify/go.sum index f60af9855..0f478630c 100644 --- a/vendor/github.com/fsnotify/fsnotify/go.sum +++ b/vendor/github.com/fsnotify/fsnotify/go.sum @@ -1,2 +1,2 @@ -golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9 h1:L2auWcuQIvxz9xSEqzESnV/QN/gNRXNApHi3fYwl2w0= -golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c h1:F1jZWGFhYfh0Ci55sIpILtKKK8p3i2/krTr0H1rg74I= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= diff --git a/vendor/github.com/fsnotify/fsnotify/inotify.go b/vendor/github.com/fsnotify/fsnotify/inotify.go index d9fd1b88a..eb87699b5 100644 --- a/vendor/github.com/fsnotify/fsnotify/inotify.go +++ b/vendor/github.com/fsnotify/fsnotify/inotify.go @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +//go:build linux // +build linux package fsnotify @@ -272,7 +273,7 @@ func (w *Watcher) readEvents() { if nameLen > 0 { // Point "bytes" at the first byte of the filename - bytes := (*[unix.PathMax]byte)(unsafe.Pointer(&buf[offset+unix.SizeofInotifyEvent])) + bytes := (*[unix.PathMax]byte)(unsafe.Pointer(&buf[offset+unix.SizeofInotifyEvent]))[:nameLen:nameLen] // The filename is padded with NULL bytes. TrimRight() gets rid of those. name += "/" + strings.TrimRight(string(bytes[0:nameLen]), "\000") } diff --git a/vendor/github.com/fsnotify/fsnotify/inotify_poller.go b/vendor/github.com/fsnotify/fsnotify/inotify_poller.go index b33f2b4d4..e9ff9439f 100644 --- a/vendor/github.com/fsnotify/fsnotify/inotify_poller.go +++ b/vendor/github.com/fsnotify/fsnotify/inotify_poller.go @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +//go:build linux // +build linux package fsnotify diff --git a/vendor/github.com/fsnotify/fsnotify/kqueue.go b/vendor/github.com/fsnotify/fsnotify/kqueue.go index 86e76a3d6..368f5b790 100644 --- a/vendor/github.com/fsnotify/fsnotify/kqueue.go +++ b/vendor/github.com/fsnotify/fsnotify/kqueue.go @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +//go:build freebsd || openbsd || netbsd || dragonfly || darwin // +build freebsd openbsd netbsd dragonfly darwin package fsnotify diff --git a/vendor/github.com/fsnotify/fsnotify/open_mode_bsd.go b/vendor/github.com/fsnotify/fsnotify/open_mode_bsd.go index 2306c4620..36cc3845b 100644 --- a/vendor/github.com/fsnotify/fsnotify/open_mode_bsd.go +++ b/vendor/github.com/fsnotify/fsnotify/open_mode_bsd.go @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +//go:build freebsd || openbsd || netbsd || dragonfly // +build freebsd openbsd netbsd dragonfly package fsnotify diff --git a/vendor/github.com/fsnotify/fsnotify/open_mode_darwin.go b/vendor/github.com/fsnotify/fsnotify/open_mode_darwin.go index 870c4d6d1..98cd8476f 100644 --- a/vendor/github.com/fsnotify/fsnotify/open_mode_darwin.go +++ b/vendor/github.com/fsnotify/fsnotify/open_mode_darwin.go @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +//go:build darwin // +build darwin package fsnotify diff --git a/vendor/github.com/fsnotify/fsnotify/windows.go b/vendor/github.com/fsnotify/fsnotify/windows.go index 09436f31d..c02b75f7c 100644 --- a/vendor/github.com/fsnotify/fsnotify/windows.go +++ b/vendor/github.com/fsnotify/fsnotify/windows.go @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +//go:build windows // +build windows package fsnotify diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux.go b/vendor/golang.org/x/sys/unix/ztypes_linux.go index 72887abe5..c9d7eb41e 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux.go @@ -1773,6 +1773,8 @@ const ( NFPROTO_NUMPROTO = 0xd ) +const SO_ORIGINAL_DST = 0x50 + type Nfgenmsg struct { Nfgen_family uint8 Version uint8 diff --git a/vendor/golang.org/x/sys/windows/types_windows.go b/vendor/golang.org/x/sys/windows/types_windows.go index 1f733398e..17f03312d 100644 --- a/vendor/golang.org/x/sys/windows/types_windows.go +++ b/vendor/golang.org/x/sys/windows/types_windows.go @@ -680,7 +680,7 @@ const ( WTD_CHOICE_CERT = 5 WTD_STATEACTION_IGNORE = 0x00000000 - WTD_STATEACTION_VERIFY = 0x00000010 + WTD_STATEACTION_VERIFY = 0x00000001 WTD_STATEACTION_CLOSE = 0x00000002 WTD_STATEACTION_AUTO_CACHE = 0x00000003 WTD_STATEACTION_AUTO_CACHE_FLUSH = 0x00000004 diff --git a/vendor/modules.txt b/vendor/modules.txt index c1cfbe76d..634930d17 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -94,7 +94,7 @@ github.com/containers/buildah/pkg/overlay github.com/containers/buildah/pkg/parse github.com/containers/buildah/pkg/rusage github.com/containers/buildah/util -# github.com/containers/common v0.42.1 +# github.com/containers/common v0.43.2 github.com/containers/common/libimage github.com/containers/common/libimage/manifests github.com/containers/common/pkg/apparmor @@ -337,7 +337,7 @@ github.com/docker/libnetwork/resolvconf/dns github.com/docker/libnetwork/types # github.com/dtylman/scp v0.0.0-20181017070807-f3000a34aef4 github.com/dtylman/scp -# github.com/fsnotify/fsnotify v1.4.9 +# github.com/fsnotify/fsnotify v1.5.1 github.com/fsnotify/fsnotify # github.com/fsouza/go-dockerclient v1.7.3 github.com/fsouza/go-dockerclient @@ -674,7 +674,7 @@ golang.org/x/net/proxy golang.org/x/net/trace # golang.org/x/sync v0.0.0-20210220032951-036812b2e83c golang.org/x/sync/semaphore -# golang.org/x/sys v0.0.0-20210616094352-59db8d763f22 +# golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c golang.org/x/sys/cpu golang.org/x/sys/execabs golang.org/x/sys/internal/unsafeheader |