diff options
-rw-r--r-- | cmd/podman/generate/systemd.go | 44 | ||||
-rw-r--r-- | docs/source/markdown/podman-generate-systemd.1.md | 8 | ||||
-rw-r--r-- | pkg/api/handlers/libpod/generate.go | 3 | ||||
-rw-r--r-- | pkg/api/server/register_generate.go | 9 | ||||
-rw-r--r-- | pkg/bindings/generate/types.go | 2 | ||||
-rw-r--r-- | pkg/bindings/generate/types_systemd_options.go | 15 | ||||
-rw-r--r-- | pkg/domain/entities/generate.go | 2 | ||||
-rw-r--r-- | pkg/domain/infra/tunnel/generate.go | 14 | ||||
-rw-r--r-- | pkg/systemd/generate/containers.go | 17 | ||||
-rw-r--r-- | pkg/systemd/generate/pods.go | 6 | ||||
-rw-r--r-- | test/e2e/generate_systemd_test.go | 9 | ||||
-rw-r--r-- | test/system/250-systemd.bats | 2 |
12 files changed, 106 insertions, 25 deletions
diff --git a/cmd/podman/generate/systemd.go b/cmd/podman/generate/systemd.go index cdc103865..173b3656b 100644 --- a/cmd/podman/generate/systemd.go +++ b/cmd/podman/generate/systemd.go @@ -19,16 +19,19 @@ import ( ) const ( - restartPolicyFlagName = "restart-policy" - timeFlagName = "time" - newFlagName = "new" + startTimeoutFlagName = "start-timeout" + stopTimeoutFlagName = "stop-timeout" + stopTimeoutCompatFlagName = "time" + restartPolicyFlagName = "restart-policy" + newFlagName = "new" ) var ( files bool format string - systemdTimeout uint systemdRestart string + startTimeout uint + stopTimeout uint systemdOptions = entities.GenerateSystemdOptions{} systemdDescription = `Generate systemd units for a pod or container. The generated units can later be controlled via systemctl(1).` @@ -56,8 +59,17 @@ func init() { flags.BoolVarP(&files, "files", "f", false, "Generate .service files instead of printing to stdout") flags.BoolVar(&systemdOptions.TemplateUnitFile, "template", false, "Make it a template file and use %i and %I specifiers. Working only for containers") - flags.UintVarP(&systemdTimeout, timeFlagName, "t", containerConfig.Engine.StopTimeout, "Stop timeout override") - _ = systemdCmd.RegisterFlagCompletionFunc(timeFlagName, completion.AutocompleteNone) + flags.UintVarP(&startTimeout, startTimeoutFlagName, "", 0, "Start timeout override") + _ = systemdCmd.RegisterFlagCompletionFunc(startTimeoutFlagName, completion.AutocompleteNone) + + // NOTE: initially, there was only a --time/-t flag which mapped to + // stop-timeout. To remain backwards compatible create a hidden flag + // that maps to StopTimeout. + flags.UintVarP(&stopTimeout, stopTimeoutFlagName, "", containerConfig.Engine.StopTimeout, "Stop timeout override") + _ = systemdCmd.RegisterFlagCompletionFunc(stopTimeoutFlagName, completion.AutocompleteNone) + flags.UintVarP(&stopTimeout, stopTimeoutCompatFlagName, "t", containerConfig.Engine.StopTimeout, "Backwards alias for --stop-timeout") + _ = flags.MarkHidden("time") + flags.BoolVar(&systemdOptions.New, newFlagName, false, "Create a new container or pod instead of starting an existing one") flags.BoolVarP(&systemdOptions.NoHeader, "no-header", "", false, "Skip header generation") @@ -84,9 +96,6 @@ func init() { } func systemd(cmd *cobra.Command, args []string) error { - if cmd.Flags().Changed(timeFlagName) { - systemdOptions.StopTimeout = &systemdTimeout - } if cmd.Flags().Changed(restartPolicyFlagName) { systemdOptions.RestartPolicy = &systemdRestart } @@ -102,6 +111,23 @@ func systemd(cmd *cobra.Command, args []string) error { systemdOptions.New = true } + if cmd.Flags().Changed(startTimeoutFlagName) { + systemdOptions.StartTimeout = &startTimeout + } + setStopTimeout := 0 + if cmd.Flags().Changed(stopTimeoutFlagName) { + setStopTimeout++ + } + if cmd.Flags().Changed(stopTimeoutCompatFlagName) { + setStopTimeout++ + } + switch setStopTimeout { + case 1: + systemdOptions.StopTimeout = &stopTimeout + case 2: + return fmt.Errorf("%s and %s are redundant and cannot be used together", stopTimeoutFlagName, stopTimeoutCompatFlagName) + } + reports, err := registry.ContainerEngine().GenerateSystemd(registry.GetContext(), args[0], systemdOptions) if err != nil { return err diff --git a/docs/source/markdown/podman-generate-systemd.1.md b/docs/source/markdown/podman-generate-systemd.1.md index 356ac0629..7bd31797c 100644 --- a/docs/source/markdown/podman-generate-systemd.1.md +++ b/docs/source/markdown/podman-generate-systemd.1.md @@ -38,9 +38,13 @@ Note that `--new` only works on containers and pods created directly via Podman Do not generate the header including meta data such as the Podman version and the timestamp. -#### **--time**, **-t**=*value* +#### **--start-timeout** =*value* -Override the default stop timeout for the container with the given value. +Override the default start timeout for the container with the given value in seconds. + +#### **--stop-timeout** =*value* + +Override the default stop timeout for the container with the given value in seconds. #### **--restart-policy**=*policy* diff --git a/pkg/api/handlers/libpod/generate.go b/pkg/api/handlers/libpod/generate.go index 5205d875d..1411c680e 100644 --- a/pkg/api/handlers/libpod/generate.go +++ b/pkg/api/handlers/libpod/generate.go @@ -23,10 +23,12 @@ func GenerateSystemd(w http.ResponseWriter, r *http.Request) { TemplateUnitFile bool `schema:"templateUnitFile"` RestartPolicy *string `schema:"restartPolicy"` StopTimeout uint `schema:"stopTimeout"` + StartTimeout uint `schema:"startTimeout"` ContainerPrefix string `schema:"containerPrefix"` PodPrefix string `schema:"podPrefix"` Separator string `schema:"separator"` }{ + StartTimeout: 0, StopTimeout: util.DefaultContainerConfig().Engine.StopTimeout, ContainerPrefix: "container", PodPrefix: "pod", @@ -46,6 +48,7 @@ func GenerateSystemd(w http.ResponseWriter, r *http.Request) { NoHeader: query.NoHeader, TemplateUnitFile: query.TemplateUnitFile, RestartPolicy: query.RestartPolicy, + StartTimeout: &query.StartTimeout, StopTimeout: &query.StopTimeout, ContainerPrefix: query.ContainerPrefix, PodPrefix: query.PodPrefix, diff --git a/pkg/api/server/register_generate.go b/pkg/api/server/register_generate.go index e10c7029c..0e36394cf 100644 --- a/pkg/api/server/register_generate.go +++ b/pkg/api/server/register_generate.go @@ -37,10 +37,15 @@ func (s *APIServer) registerGenerateHandlers(r *mux.Router) error { // default: false // description: Do not generate the header including the Podman version and the timestamp. // - in: query - // name: time + // name: startTimeout + // type: integer + // default: 0 + // description: Start timeout in seconds. + // - in: query + // name: stopTimeout // type: integer // default: 10 - // description: Stop timeout override. + // description: Stop timeout in seconds. // - in: query // name: restartPolicy // default: on-failure diff --git a/pkg/bindings/generate/types.go b/pkg/bindings/generate/types.go index 6f2594604..092474e4a 100644 --- a/pkg/bindings/generate/types.go +++ b/pkg/bindings/generate/types.go @@ -20,6 +20,8 @@ type SystemdOptions struct { TemplateUnitFile *bool // RestartPolicy - systemd restart policy. RestartPolicy *string + // StartTimeout - time when starting the container. + StartTimeout *uint // StopTimeout - time when stopping the container. StopTimeout *uint // ContainerPrefix - systemd unit name prefix for containers diff --git a/pkg/bindings/generate/types_systemd_options.go b/pkg/bindings/generate/types_systemd_options.go index b26aa7fc2..d60f1d70e 100644 --- a/pkg/bindings/generate/types_systemd_options.go +++ b/pkg/bindings/generate/types_systemd_options.go @@ -92,6 +92,21 @@ func (o *SystemdOptions) GetRestartPolicy() string { return *o.RestartPolicy } +// WithStartTimeout set field StartTimeout to given value +func (o *SystemdOptions) WithStartTimeout(value uint) *SystemdOptions { + o.StartTimeout = &value + return o +} + +// GetStartTimeout returns value of field StartTimeout +func (o *SystemdOptions) GetStartTimeout() uint { + if o.StartTimeout == nil { + var z uint + return z + } + return *o.StartTimeout +} + // WithStopTimeout set field StopTimeout to given value func (o *SystemdOptions) WithStopTimeout(value uint) *SystemdOptions { o.StopTimeout = &value diff --git a/pkg/domain/entities/generate.go b/pkg/domain/entities/generate.go index dfb5bfc6c..7e80e5d2d 100644 --- a/pkg/domain/entities/generate.go +++ b/pkg/domain/entities/generate.go @@ -10,6 +10,8 @@ type GenerateSystemdOptions struct { New bool // RestartPolicy - systemd restart policy. RestartPolicy *string + // StartTimeout - time when starting the container. + StartTimeout *uint // StopTimeout - time when stopping the container. StopTimeout *uint // ContainerPrefix - systemd unit name prefix for containers diff --git a/pkg/domain/infra/tunnel/generate.go b/pkg/domain/infra/tunnel/generate.go index 3a35dd59c..d62a318d6 100644 --- a/pkg/domain/infra/tunnel/generate.go +++ b/pkg/domain/infra/tunnel/generate.go @@ -8,14 +8,18 @@ import ( ) func (ic *ContainerEngine) GenerateSystemd(ctx context.Context, nameOrID string, opts entities.GenerateSystemdOptions) (*entities.GenerateSystemdReport, error) { - options := new(generate.SystemdOptions).WithUseName(opts.Name).WithContainerPrefix(opts.ContainerPrefix).WithNew(opts.New).WithNoHeader(opts.NoHeader).WithTemplateUnitFile(opts.TemplateUnitFile) - options.WithPodPrefix(opts.PodPrefix).WithSeparator(opts.Separator) - if opts.RestartPolicy != nil { - options.WithRestartPolicy(*opts.RestartPolicy) + options := new(generate.SystemdOptions).WithUseName(opts.Name).WithContainerPrefix(opts.ContainerPrefix).WithNew(opts.New).WithNoHeader(opts.NoHeader).WithTemplateUnitFile(opts.TemplateUnitFile).WithPodPrefix(opts.PodPrefix).WithSeparator(opts.Separator) + + if opts.StartTimeout != nil { + options.WithStartTimeout(*opts.StartTimeout) } - if to := opts.StopTimeout; to != nil { + if opts.StopTimeout != nil { options.WithStopTimeout(*opts.StopTimeout) } + if opts.RestartPolicy != nil { + options.WithRestartPolicy(*opts.RestartPolicy) + } + return generate.Systemd(ic.ClientCtx, nameOrID, options) } diff --git a/pkg/systemd/generate/containers.go b/pkg/systemd/generate/containers.go index 95ff13371..2fdec5fb1 100644 --- a/pkg/systemd/generate/containers.go +++ b/pkg/systemd/generate/containers.go @@ -73,6 +73,8 @@ type containerInfo struct { ExecStartPre string // ExecStart of the unit. ExecStart string + // TimeoutStartSec of the unit. + TimeoutStartSec uint // TimeoutStopSec of the unit. TimeoutStopSec uint // ExecStop of the unit. @@ -109,6 +111,9 @@ Restart={{{{.RestartPolicy}}}} {{{{- if .StartLimitBurst}}}} StartLimitBurst={{{{.StartLimitBurst}}}} {{{{- end}}}} +{{{{- if ne .TimeoutStartSec 0}}}} +TimeoutStartSec={{{{.TimeoutStartSec}}}} +{{{{- end}}}} TimeoutStopSec={{{{.TimeoutStopSec}}}} {{{{- if .ExecStartPre}}}} ExecStartPre={{{{.ExecStartPre}}}} @@ -148,9 +153,14 @@ func ContainerUnit(ctr *libpod.Container, options entities.GenerateSystemdOption } func generateContainerInfo(ctr *libpod.Container, options entities.GenerateSystemdOptions) (*containerInfo, error) { - timeout := ctr.StopTimeout() + stopTimeout := ctr.StopTimeout() if options.StopTimeout != nil { - timeout = *options.StopTimeout + stopTimeout = *options.StopTimeout + } + + startTimeout := uint(0) + if options.StartTimeout != nil { + startTimeout = *options.StartTimeout } config := ctr.Config() @@ -185,7 +195,8 @@ func generateContainerInfo(ctr *libpod.Container, options entities.GenerateSyste ContainerNameOrID: nameOrID, RestartPolicy: define.DefaultRestartPolicy, PIDFile: conmonPidFile, - StopTimeout: timeout, + TimeoutStartSec: startTimeout, + StopTimeout: stopTimeout, GenerateTimestamp: true, CreateCommand: createCommand, RunRoot: runRoot, diff --git a/pkg/systemd/generate/pods.go b/pkg/systemd/generate/pods.go index 38f7e8e3e..f4cc31c8e 100644 --- a/pkg/systemd/generate/pods.go +++ b/pkg/systemd/generate/pods.go @@ -195,9 +195,9 @@ func generatePodInfo(pod *libpod.Pod, options entities.GenerateSystemdOptions) ( return nil, errors.Wrap(err, "could not find infra container") } - timeout := infraCtr.StopTimeout() + stopTimeout := infraCtr.StopTimeout() if options.StopTimeout != nil { - timeout = *options.StopTimeout + stopTimeout = *options.StopTimeout } config := infraCtr.Config() @@ -223,7 +223,7 @@ func generatePodInfo(pod *libpod.Pod, options entities.GenerateSystemdOptions) ( ServiceName: serviceName, InfraNameOrID: ctrNameOrID, PIDFile: conmonPidFile, - StopTimeout: timeout, + StopTimeout: stopTimeout, GenerateTimestamp: true, CreateCommand: createCommand, } diff --git a/test/e2e/generate_systemd_test.go b/test/e2e/generate_systemd_test.go index 121f09a11..e93482535 100644 --- a/test/e2e/generate_systemd_test.go +++ b/test/e2e/generate_systemd_test.go @@ -147,6 +147,15 @@ var _ = Describe("Podman generate systemd", func() { session := podmanTest.Podman([]string{"generate", "systemd", "--time", "5", "nginx"}) session.WaitWithDefaultTimeout() Expect(session).Should(Exit(0)) + Expect(session.OutputToString()).To(ContainSubstring("TimeoutStopSec=65")) + Expect(session.OutputToString()).ToNot(ContainSubstring("TimeoutStartSec=")) + Expect(session.OutputToString()).To(ContainSubstring("podman stop -t 5")) + + session = podmanTest.Podman([]string{"generate", "systemd", "--stop-timeout", "5", "--start-timeout", "123", "nginx"}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + Expect(session.OutputToString()).To(ContainSubstring("TimeoutStartSec=123")) + Expect(session.OutputToString()).To(ContainSubstring("TimeoutStopSec=65")) Expect(session.OutputToString()).To(ContainSubstring("podman stop -t 5")) }) diff --git a/test/system/250-systemd.bats b/test/system/250-systemd.bats index e997ab6f9..4757f7643 100644 --- a/test/system/250-systemd.bats +++ b/test/system/250-systemd.bats @@ -138,7 +138,7 @@ function service_cleanup() { } # Regression test for #11438 -@test "podman generate systemd - restart policy" { +@test "podman generate systemd - restart policy & timeouts" { cname=$(random_string) run_podman create --restart=always --name $cname $IMAGE run_podman generate systemd --new $cname |