summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.cirrus.yml6
-rw-r--r--cmd/podman/common/create.go10
-rw-r--r--cmd/podman/common/create_opts.go1
-rw-r--r--cmd/podman/common/specgen.go1
-rw-r--r--cmd/podman/containers/stop.go3
-rw-r--r--cmd/podman/generate/systemd.go2
-rw-r--r--cmd/podman/utils/alias.go11
-rw-r--r--contrib/cirrus/lib.sh23
-rw-r--r--docs/source/markdown/podman-create.1.md6
-rw-r--r--docs/source/markdown/podman-run.1.md6
-rw-r--r--libpod/container_config.go2
-rw-r--r--libpod/container_inspect.go2
-rw-r--r--libpod/define/container_inspect.go4
-rw-r--r--libpod/oci_conmon_linux.go4
-rw-r--r--libpod/options.go13
-rw-r--r--pkg/api/handlers/compat/volumes.go16
-rw-r--r--pkg/specgen/generate/container_create.go3
-rw-r--r--pkg/specgen/specgen.go5
-rw-r--r--test/apiv2/30-volumes.at7
-rw-r--r--test/e2e/generate_systemd_test.go2
-rw-r--r--test/e2e/run_test.go3
-rw-r--r--test/system/030-run.bats23
22 files changed, 124 insertions, 29 deletions
diff --git a/.cirrus.yml b/.cirrus.yml
index f044b98ab..e56ba9086 100644
--- a/.cirrus.yml
+++ b/.cirrus.yml
@@ -26,11 +26,11 @@ env:
####
FEDORA_NAME: "fedora-34beta"
PRIOR_FEDORA_NAME: "fedora-33"
- UBUNTU_NAME: "ubuntu-2010"
- PRIOR_UBUNTU_NAME: "ubuntu-2004"
+ UBUNTU_NAME: "ubuntu-2104"
+ PRIOR_UBUNTU_NAME: "ubuntu-2010"
# Google-cloud VM Images
- IMAGE_SUFFIX: "c5032481331085312"
+ IMAGE_SUFFIX: "c6731272010596352"
FEDORA_CACHE_IMAGE_NAME: "fedora-${IMAGE_SUFFIX}"
PRIOR_FEDORA_CACHE_IMAGE_NAME: "prior-fedora-${IMAGE_SUFFIX}"
UBUNTU_CACHE_IMAGE_NAME: "ubuntu-${IMAGE_SUFFIX}"
diff --git a/cmd/podman/common/create.go b/cmd/podman/common/create.go
index d496ae308..c3d00d293 100644
--- a/cmd/podman/common/create.go
+++ b/cmd/podman/common/create.go
@@ -651,7 +651,7 @@ func DefineCreateFlags(cmd *cobra.Command, cf *ContainerCLIOpts) {
createFlags.UintVar(
&cf.StopTimeout,
stopTimeoutFlagName, containerConfig.Engine.StopTimeout,
- "Timeout (in seconds) to stop a container. Default is 10",
+ "Timeout (in seconds) that containers stopped by user command have to exit. If exceeded, the container will be forcibly stopped via SIGKILL.",
)
_ = cmd.RegisterFlagCompletionFunc(stopTimeoutFlagName, completion.AutocompleteNone)
@@ -697,6 +697,14 @@ func DefineCreateFlags(cmd *cobra.Command, cf *ContainerCLIOpts) {
)
_ = cmd.RegisterFlagCompletionFunc(systemdFlagName, AutocompleteSystemdFlag)
+ timeoutFlagName := "timeout"
+ createFlags.UintVar(
+ &cf.Timeout,
+ timeoutFlagName, 0,
+ "Maximum length of time a container is allowed to run. The container will be killed automatically after the time expires.",
+ )
+ _ = cmd.RegisterFlagCompletionFunc(timeoutFlagName, completion.AutocompleteNone)
+
tmpfsFlagName := "tmpfs"
createFlags.StringArrayVar(
&cf.TmpFS,
diff --git a/cmd/podman/common/create_opts.go b/cmd/podman/common/create_opts.go
index 983b9e5ca..ca36d751e 100644
--- a/cmd/podman/common/create_opts.go
+++ b/cmd/podman/common/create_opts.go
@@ -108,6 +108,7 @@ type ContainerCLIOpts struct {
SubGIDName string
Sysctl []string
Systemd string
+ Timeout uint
TmpFS []string
TTY bool
Timezone string
diff --git a/cmd/podman/common/specgen.go b/cmd/podman/common/specgen.go
index 310a07a00..f889a0169 100644
--- a/cmd/podman/common/specgen.go
+++ b/cmd/podman/common/specgen.go
@@ -641,6 +641,7 @@ func FillOutSpecGen(s *specgen.SpecGenerator, c *ContainerCLIOpts, args []string
}
s.Remove = c.Rm
s.StopTimeout = &c.StopTimeout
+ s.Timeout = c.Timeout
s.Timezone = c.Timezone
s.Umask = c.Umask
s.Secrets = c.Secrets
diff --git a/cmd/podman/containers/stop.go b/cmd/podman/containers/stop.go
index bed45f374..62ce9b036 100644
--- a/cmd/podman/containers/stop.go
+++ b/cmd/podman/containers/stop.go
@@ -72,7 +72,8 @@ func stopFlags(cmd *cobra.Command) {
_ = flags.MarkHidden("cidfile")
_ = flags.MarkHidden("ignore")
}
- flags.SetNormalizeFunc(utils.AliasFlags)
+
+ flags.SetNormalizeFunc(utils.TimeoutAliasFlags)
}
func init() {
diff --git a/cmd/podman/generate/systemd.go b/cmd/podman/generate/systemd.go
index 72b2e6335..8a8f5016a 100644
--- a/cmd/podman/generate/systemd.go
+++ b/cmd/podman/generate/systemd.go
@@ -74,7 +74,7 @@ func init() {
flags.StringVar(&format, formatFlagName, "", "Print the created units in specified format (json)")
_ = systemdCmd.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteFormat(nil))
- flags.SetNormalizeFunc(utils.AliasFlags)
+ flags.SetNormalizeFunc(utils.TimeoutAliasFlags)
}
func systemd(cmd *cobra.Command, args []string) error {
diff --git a/cmd/podman/utils/alias.go b/cmd/podman/utils/alias.go
index 8d089920b..306e610d9 100644
--- a/cmd/podman/utils/alias.go
+++ b/cmd/podman/utils/alias.go
@@ -17,8 +17,6 @@ func AliasFlags(f *pflag.FlagSet, name string) pflag.NormalizedName {
name = "health-timeout"
case "net":
name = "network"
- case "timeout":
- name = "time"
case "namespace":
name = "ns"
case "storage":
@@ -34,3 +32,12 @@ func AliasFlags(f *pflag.FlagSet, name string) pflag.NormalizedName {
}
return pflag.NormalizedName(name)
}
+
+// TimeoutAliasFlags is a function to handle backwards compatibility with old timeout flags
+func TimeoutAliasFlags(f *pflag.FlagSet, name string) pflag.NormalizedName {
+ switch name {
+ case "timeout":
+ name = "time"
+ }
+ return pflag.NormalizedName(name)
+}
diff --git a/contrib/cirrus/lib.sh b/contrib/cirrus/lib.sh
index 2cd28e34a..16eb6735a 100644
--- a/contrib/cirrus/lib.sh
+++ b/contrib/cirrus/lib.sh
@@ -10,27 +10,17 @@ set -a
# handling of the (otherwise) default shell setup is non-uniform. Rather
# than attempt to workaround differences, simply force-load/set required
# items every time this library is utilized.
-_waserrexit=0
-if [[ "$SHELLOPTS" =~ errexit ]]; then _waserrexit=1; fi
-set +e # Assumed in F33 for setting global vars
-if [[ -r "/etc/automation_environment" ]]; then
- source /etc/automation_environment
-else # prior to automation library v2.0, this was necessary
- source /etc/profile
- source /etc/environment
-fi
-if [[ -r "/etc/ci_environment" ]]; then source /etc/ci_environment; fi
USER="$(whoami)"
HOME="$(getent passwd $USER | cut -d : -f 6)"
# Some platforms set and make this read-only
[[ -n "$UID" ]] || \
UID=$(getent passwd $USER | cut -d : -f 3)
-if ((_waserrexit)); then set -e; fi
-# During VM Image build, the 'containers/automation' installation
-# was performed. The final step of installation sets the library
-# location $AUTOMATION_LIB_PATH in /etc/environment or in the
-# default shell profile depending on distribution.
+# Automation library installed at image-build time,
+# defining $AUTOMATION_LIB_PATH in this file.
+if [[ -r "/etc/automation_environment" ]]; then
+ source /etc/automation_environment
+fi
# shellcheck disable=SC2154
if [[ -n "$AUTOMATION_LIB_PATH" ]]; then
# shellcheck source=/usr/share/automation/lib/common_lib.sh
@@ -43,6 +33,9 @@ else
) > /dev/stderr
fi
+# Managed by setup_environment.sh; holds task-specific definitions.
+if [[ -r "/etc/ci_environment" ]]; then source /etc/ci_environment; fi
+
OS_RELEASE_ID="$(source /etc/os-release; echo $ID)"
# GCE image-name compatible string representation of distribution _major_ version
OS_RELEASE_VER="$(source /etc/os-release; echo $VERSION_ID | tr -d '.')"
diff --git a/docs/source/markdown/podman-create.1.md b/docs/source/markdown/podman-create.1.md
index c375f2417..ff3f86ec9 100644
--- a/docs/source/markdown/podman-create.1.md
+++ b/docs/source/markdown/podman-create.1.md
@@ -951,6 +951,12 @@ The `container_manage_cgroup` boolean must be enabled for this to be allowed on
`setsebool -P container_manage_cgroup true`
+#### **\-\-timeout**=*seconds*
+
+Maximimum time a container is allowed to run before conmon sends it the kill
+signal. By default containers will run until they exit or are stopped by
+`podman stop`.
+
#### **\-\-tmpfs**=*fs*
Create a tmpfs mount
diff --git a/docs/source/markdown/podman-run.1.md b/docs/source/markdown/podman-run.1.md
index 74bbf8809..a41938ff6 100644
--- a/docs/source/markdown/podman-run.1.md
+++ b/docs/source/markdown/podman-run.1.md
@@ -1024,6 +1024,12 @@ The **container_manage_cgroup** boolean must be enabled for this to be allowed o
setsebool -P container_manage_cgroup true
```
+#### **\-\-timeout**=*seconds*
+
+Maximimum time a container is allowed to run before conmon sends it the kill
+signal. By default containers will run until they exit or are stopped by
+`podman stop`.
+
#### **\-\-tmpfs**=*fs*
Create a tmpfs mount.
diff --git a/libpod/container_config.go b/libpod/container_config.go
index d0572fbc2..ede6b1aab 100644
--- a/libpod/container_config.go
+++ b/libpod/container_config.go
@@ -298,6 +298,8 @@ type ContainerMiscConfig struct {
StopSignal uint `json:"stopSignal,omitempty"`
// StopTimeout is the signal that will be used to stop the container
StopTimeout uint `json:"stopTimeout,omitempty"`
+ // Timeout is maximimum time a container will run before getting the kill signal
+ Timeout uint `json:"timeout,omitempty"`
// Time container was created
CreatedTime time.Time `json:"createdTime"`
// CgroupManager is the cgroup manager used to create this container.
diff --git a/libpod/container_inspect.go b/libpod/container_inspect.go
index 61cc43314..5b2103c92 100644
--- a/libpod/container_inspect.go
+++ b/libpod/container_inspect.go
@@ -304,6 +304,8 @@ func (c *Container) generateInspectContainerConfig(spec *spec.Spec) *define.Insp
ctrConfig.WorkingDir = spec.Process.Cwd
}
+ ctrConfig.StopTimeout = c.config.StopTimeout
+ ctrConfig.Timeout = c.config.Timeout
ctrConfig.OpenStdin = c.config.Stdin
ctrConfig.Image = c.config.RootfsImageName
ctrConfig.SystemdMode = c.config.Systemd
diff --git a/libpod/define/container_inspect.go b/libpod/define/container_inspect.go
index 1a38f5b0a..c236f35b0 100644
--- a/libpod/define/container_inspect.go
+++ b/libpod/define/container_inspect.go
@@ -64,6 +64,10 @@ type InspectContainerConfig struct {
Umask string `json:"Umask,omitempty"`
// Secrets are the secrets mounted in the container
Secrets []*InspectSecret `json:"Secrets,omitempty"`
+ // Timeout is time before container is killed by conmon
+ Timeout uint `json:"Timeout"`
+ // StopTimeout is time before container is stoped when calling stop
+ StopTimeout uint `json:"StopTimeout"`
}
// InspectRestartPolicy holds information about the container's restart policy.
diff --git a/libpod/oci_conmon_linux.go b/libpod/oci_conmon_linux.go
index c1acec977..1b1d4ad59 100644
--- a/libpod/oci_conmon_linux.go
+++ b/libpod/oci_conmon_linux.go
@@ -1024,6 +1024,10 @@ func (r *ConmonOCIRuntime) createOCIContainer(ctr *Container, restoreOptions *Co
args = append(args, "-i")
}
+ if ctr.config.Timeout > 0 {
+ args = append(args, fmt.Sprintf("--timeout=%d", ctr.config.Timeout))
+ }
+
if !r.enableKeyring {
args = append(args, "--no-new-keyring")
}
diff --git a/libpod/options.go b/libpod/options.go
index 103a9a80a..39415a817 100644
--- a/libpod/options.go
+++ b/libpod/options.go
@@ -769,6 +769,19 @@ func WithStopTimeout(timeout uint) CtrCreateOption {
}
}
+// WithTimeout sets the maximum time a container is allowed to run"
+func WithTimeout(timeout uint) CtrCreateOption {
+ return func(ctr *Container) error {
+ if ctr.valid {
+ return define.ErrCtrFinalized
+ }
+
+ ctr.config.Timeout = timeout
+
+ return nil
+ }
+}
+
// WithIDMappings sets the idmappings for the container
func WithIDMappings(idmappings storage.IDMappingOptions) CtrCreateOption {
return func(ctr *Container) error {
diff --git a/pkg/api/handlers/compat/volumes.go b/pkg/api/handlers/compat/volumes.go
index d86fc1e19..1ff1468e7 100644
--- a/pkg/api/handlers/compat/volumes.go
+++ b/pkg/api/handlers/compat/volumes.go
@@ -96,11 +96,17 @@ func CreateVolume(w http.ResponseWriter, r *http.Request) {
return
}
- // See if the volume exists already
- existingVolume, err := runtime.GetVolume(input.Name)
- if err != nil && errors.Cause(err) != define.ErrNoSuchVolume {
- utils.InternalServerError(w, err)
- return
+ var (
+ existingVolume *libpod.Volume
+ err error
+ )
+ if len(input.Name) != 0 {
+ // See if the volume exists already
+ existingVolume, err = runtime.GetVolume(input.Name)
+ if err != nil && errors.Cause(err) != define.ErrNoSuchVolume {
+ utils.InternalServerError(w, err)
+ return
+ }
}
// if using the compat layer and the volume already exists, we
diff --git a/pkg/specgen/generate/container_create.go b/pkg/specgen/generate/container_create.go
index 2f623bf10..277435ef1 100644
--- a/pkg/specgen/generate/container_create.go
+++ b/pkg/specgen/generate/container_create.go
@@ -325,6 +325,9 @@ func createContainerOptions(ctx context.Context, rt *libpod.Runtime, s *specgen.
if s.StopTimeout != nil {
options = append(options, libpod.WithStopTimeout(*s.StopTimeout))
}
+ if s.Timeout != 0 {
+ options = append(options, libpod.WithTimeout(s.Timeout))
+ }
if s.LogConfiguration != nil {
if len(s.LogConfiguration.Path) > 0 {
options = append(options, libpod.WithLogPath(s.LogConfiguration.Path))
diff --git a/pkg/specgen/specgen.go b/pkg/specgen/specgen.go
index e3d4b1436..fdcb7a0e0 100644
--- a/pkg/specgen/specgen.go
+++ b/pkg/specgen/specgen.go
@@ -83,6 +83,11 @@ type ContainerBasicConfig struct {
// instead.
// Optional.
StopTimeout *uint `json:"stop_timeout,omitempty"`
+ // Timeout is a maximum time in seconds the container will run before
+ // main process is sent SIGKILL.
+ // If 0 is used, signal will not be sent. Container can run indefinitely
+ // Optional.
+ Timeout uint `json:"timeout,omitempty"`
// LogConfiguration describes the logging for a container including
// driver, path, and options.
// Optional
diff --git a/test/apiv2/30-volumes.at b/test/apiv2/30-volumes.at
index 623e691e3..ed606134a 100644
--- a/test/apiv2/30-volumes.at
+++ b/test/apiv2/30-volumes.at
@@ -13,6 +13,13 @@ t POST libpod/volumes/create name=foo1 201 \
.CreatedAt~[0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\}.* \
.Labels={} \
.Options={}
+t POST volumes/create 201 \
+ .Name~[0-9a-f]\\{64\\}
+ .Driver=local \
+ .Mountpoint=$volumepath/~[0-9a-f]\\{64\\}/_data \
+ .CreatedAt~[0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\}.* \
+ .Labels={} \
+ .Options={}
t POST libpod/volumes/create 201
t POST libpod/volumes/create \
Name=foo2 \
diff --git a/test/e2e/generate_systemd_test.go b/test/e2e/generate_systemd_test.go
index 3a1da5d8c..75d778f10 100644
--- a/test/e2e/generate_systemd_test.go
+++ b/test/e2e/generate_systemd_test.go
@@ -242,7 +242,7 @@ var _ = Describe("Podman generate systemd", func() {
n.WaitWithDefaultTimeout()
Expect(n.ExitCode()).To(Equal(0))
- session := podmanTest.Podman([]string{"generate", "systemd", "--timeout", "42", "--name", "--new", "foo"})
+ session := podmanTest.Podman([]string{"generate", "systemd", "--time", "42", "--name", "--new", "foo"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
diff --git a/test/e2e/run_test.go b/test/e2e/run_test.go
index 93505d742..74bdfce2c 100644
--- a/test/e2e/run_test.go
+++ b/test/e2e/run_test.go
@@ -582,6 +582,9 @@ USER bin`, BB)
if _, err := os.Stat("/sys/fs/cgroup/io.stat"); os.IsNotExist(err) {
Skip("Kernel does not have io.stat")
}
+ if _, err := os.Stat("/sys/fs/cgroup/system.slice/io.bfq.weight"); os.IsNotExist(err) {
+ Skip("Kernel does not support BFQ IO scheduler")
+ }
session := podmanTest.Podman([]string{"run", "--rm", "--blkio-weight=15", ALPINE, "sh", "-c", "cat /sys/fs/cgroup/io.bfq.weight"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
diff --git a/test/system/030-run.bats b/test/system/030-run.bats
index b2999a9e7..c007a1557 100644
--- a/test/system/030-run.bats
+++ b/test/system/030-run.bats
@@ -668,4 +668,27 @@ json-file | f
is "$output" ".*HOME=/.*"
}
+@test "podman run --timeout - basic test" {
+ cid=timeouttest
+ t0=$SECONDS
+ run_podman 255 run --name $cid --timeout 10 $IMAGE sleep 60
+ t1=$SECONDS
+ # Confirm that container is stopped. Podman-remote unfortunately
+ # cannot tell the difference between "stopped" and "exited", and
+ # spits them out interchangeably, so we need to recognize either.
+ run_podman inspect --format '{{.State.Status}} {{.State.ExitCode}}' $cid
+ is "$output" "\\(stopped\|exited\\) \-1" \
+ "Status and exit code of stopped container"
+
+ # This operation should take
+ # exactly 10 seconds. Give it some leeway.
+ delta_t=$(( $t1 - $t0 ))
+ [ $delta_t -gt 8 ] ||\
+ die "podman stop: ran too quickly! ($delta_t seconds; expected >= 10)"
+ [ $delta_t -le 14 ] ||\
+ die "podman stop: took too long ($delta_t seconds; expected ~10)"
+
+ run_podman rm $cid
+}
+
# vim: filetype=sh