mirror of
https://github.com/containers/podman
synced 2024-10-19 08:44:11 +00:00
Merge pull request #10119 from rhatdan/timeout
Add podman run --timeout option
This commit is contained in:
commit
f613a2a8d5
|
@ -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,
|
||||
|
|
|
@ -108,6 +108,7 @@ type ContainerCLIOpts struct {
|
|||
SubGIDName string
|
||||
Sysctl []string
|
||||
Systemd string
|
||||
Timeout uint
|
||||
TmpFS []string
|
||||
TTY bool
|
||||
Timezone string
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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")
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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))
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue