summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmd/podman/containers/logs.go4
-rw-r--r--cmd/podman/generate/kube.go5
-rw-r--r--cmd/podman/machine/init.go3
-rw-r--r--cmd/podman/volumes/import.go97
-rw-r--r--docs/source/markdown/podman-machine-init.1.md4
-rw-r--r--docs/source/markdown/podman-volume-export.1.md2
-rw-r--r--docs/source/markdown/podman-volume-import.1.md35
-rw-r--r--docs/source/markdown/podman-volume-ls.1.md16
-rw-r--r--docs/source/markdown/podman-volume-prune.1.md6
-rw-r--r--docs/source/markdown/podman-volume.1.md1
-rw-r--r--docs/source/volume.rst2
-rw-r--r--go.mod6
-rw-r--r--go.sum15
-rw-r--r--libpod/container_commit.go5
-rw-r--r--libpod/container_config.go6
-rw-r--r--libpod/container_inspect.go2
-rw-r--r--libpod/container_log_linux.go45
-rw-r--r--libpod/container_log_unsupported.go4
-rw-r--r--libpod/events/filters.go4
-rw-r--r--libpod/events/journal_linux.go4
-rw-r--r--libpod/events/logfile.go2
-rw-r--r--libpod/logs/log.go12
-rw-r--r--libpod/networking_linux.go2
-rw-r--r--libpod/oci_conmon_linux.go8
-rw-r--r--libpod/options.go3
-rw-r--r--libpod/pod_api.go2
-rw-r--r--libpod/runtime_ctr.go11
-rw-r--r--libpod/runtime_pod_infra_linux.go3
-rw-r--r--libpod/util.go13
-rw-r--r--pkg/api/handlers/compat/containers_logs.go8
-rw-r--r--pkg/bindings/connection.go7
-rw-r--r--pkg/bindings/containers/archive.go10
-rw-r--r--pkg/bindings/containers/attach.go9
-rw-r--r--pkg/bindings/containers/checkpoint.go4
-rw-r--r--pkg/bindings/containers/commit.go2
-rw-r--r--pkg/bindings/containers/containers.go33
-rw-r--r--pkg/bindings/containers/create.go2
-rw-r--r--pkg/bindings/containers/diff.go2
-rw-r--r--pkg/bindings/containers/exec.go3
-rw-r--r--pkg/bindings/containers/healthcheck.go2
-rw-r--r--pkg/bindings/containers/logs.go1
-rw-r--r--pkg/bindings/containers/mount.go6
-rw-r--r--pkg/bindings/containers/rename.go2
-rw-r--r--pkg/bindings/errors.go2
-rw-r--r--pkg/bindings/generate/generate.go5
-rw-r--r--pkg/bindings/images/diff.go2
-rw-r--r--pkg/bindings/images/images.go32
-rw-r--r--pkg/bindings/images/rm.go2
-rw-r--r--pkg/bindings/manifests/manifests.go21
-rw-r--r--pkg/bindings/network/network.go16
-rw-r--r--pkg/bindings/play/play.go2
-rw-r--r--pkg/bindings/pods/pods.go27
-rw-r--r--pkg/bindings/secrets/secrets.go8
-rw-r--r--pkg/bindings/system/info.go10
-rw-r--r--pkg/bindings/system/system.go7
-rw-r--r--pkg/bindings/test/attach_test.go5
-rw-r--r--pkg/bindings/test/common_test.go21
-rw-r--r--pkg/bindings/test/resource_test.go116
-rw-r--r--pkg/bindings/volumes/volumes.go12
-rw-r--r--pkg/domain/entities/generate.go2
-rw-r--r--pkg/domain/infra/tunnel/containers.go4
-rw-r--r--pkg/domain/infra/tunnel/generate.go3
-rw-r--r--pkg/machine/fcos.go4
-rw-r--r--pkg/machine/fcos_amd64.go14
-rw-r--r--pkg/machine/fcos_arm64.go2
-rw-r--r--pkg/machine/qemu/machine.go24
-rw-r--r--pkg/specgen/generate/namespaces.go8
-rw-r--r--pkg/specgen/generate/ports.go29
-rw-r--r--pkg/systemd/generate/common.go11
-rw-r--r--pkg/systemd/generate/common_test.go4
-rw-r--r--pkg/systemd/generate/containers.go31
-rw-r--r--pkg/systemd/generate/containers_test.go105
-rw-r--r--pkg/systemd/generate/pods.go2
-rw-r--r--pkg/systemd/generate/pods_test.go10
-rw-r--r--pkg/util/utils.go7
-rw-r--r--pkg/util/utils_test.go2
-rw-r--r--test/e2e/commit_test.go36
-rw-r--r--test/e2e/container_inspect_test.go25
-rw-r--r--test/e2e/events_test.go13
-rw-r--r--test/e2e/logs_test.go2
-rw-r--r--test/e2e/run_test.go14
-rw-r--r--test/e2e/volume_create_test.go44
-rw-r--r--test/system/130-kill.bats4
-rw-r--r--test/system/160-volumes.bats16
-rw-r--r--test/system/250-systemd.bats30
-rw-r--r--test/system/330-corrupt-images.bats13
-rw-r--r--vendor/github.com/containers/common/libimage/image.go23
-rw-r--r--vendor/github.com/containers/common/pkg/auth/auth.go2
-rw-r--r--vendor/github.com/containers/common/pkg/config/config.go7
-rw-r--r--vendor/github.com/containers/common/pkg/config/containers.conf6
-rw-r--r--vendor/github.com/containers/common/pkg/config/default.go10
-rw-r--r--vendor/github.com/containers/common/pkg/config/nosystemd.go7
-rw-r--r--vendor/github.com/containers/common/pkg/config/systemd.go41
-rw-r--r--vendor/github.com/containers/common/pkg/parse/parse.go3
-rw-r--r--vendor/github.com/containers/common/version/version.go2
-rw-r--r--vendor/github.com/fsnotify/fsnotify/.mailmap2
-rw-r--r--vendor/github.com/fsnotify/fsnotify/.travis.yml36
-rw-r--r--vendor/github.com/fsnotify/fsnotify/AUTHORS16
-rw-r--r--vendor/github.com/fsnotify/fsnotify/CHANGELOG.md116
-rw-r--r--vendor/github.com/fsnotify/fsnotify/README.md6
-rw-r--r--vendor/github.com/fsnotify/fsnotify/fen.go1
-rw-r--r--vendor/github.com/fsnotify/fsnotify/fsnotify.go1
-rw-r--r--vendor/github.com/fsnotify/fsnotify/go.mod4
-rw-r--r--vendor/github.com/fsnotify/fsnotify/go.sum4
-rw-r--r--vendor/github.com/fsnotify/fsnotify/inotify.go3
-rw-r--r--vendor/github.com/fsnotify/fsnotify/inotify_poller.go1
-rw-r--r--vendor/github.com/fsnotify/fsnotify/kqueue.go1
-rw-r--r--vendor/github.com/fsnotify/fsnotify/open_mode_bsd.go1
-rw-r--r--vendor/github.com/fsnotify/fsnotify/open_mode_darwin.go1
-rw-r--r--vendor/github.com/fsnotify/fsnotify/windows.go1
-rw-r--r--vendor/golang.org/x/sys/unix/ztypes_linux.go2
-rw-r--r--vendor/golang.org/x/sys/windows/types_windows.go2
-rw-r--r--vendor/modules.txt6
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
diff --git a/go.mod b/go.mod
index f64b850a1..e9692fb3f 100644
--- a/go.mod
+++ b/go.mod
@@ -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
diff --git a/go.sum b/go.sum
index 359bfee73..a0c50d268 100644
--- a/go.sum
+++ b/go.sum
@@ -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