mirror of
https://github.com/containers/podman.git
synced 2025-05-17 15:18:43 +08:00
Handlers for generate systemd
with custom dependencies
This commit includes: * Handlers for generate systemd unit with manually defined dependencies such as: Wants=, After= and Requires= * The new unit and e2e tests for checking generated systemd units for container and pod with custom dependencies * Documented descriptions for custom dependencies options Signed-off-by: Eugene (Evgenii) Shubin <esendjer@gmail.com>
This commit is contained in:
@ -25,6 +25,9 @@ const (
|
||||
restartPolicyFlagName = "restart-policy"
|
||||
restartSecFlagName = "restart-sec"
|
||||
newFlagName = "new"
|
||||
wantsFlagName = "wants"
|
||||
afterFlagName = "after"
|
||||
requiresFlagName = "requires"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -97,6 +100,15 @@ func init() {
|
||||
flags.StringVar(&format, formatFlagName, "", "Print the created units in specified format (json)")
|
||||
_ = systemdCmd.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteFormat(nil))
|
||||
|
||||
flags.StringArrayVar(&systemdOptions.Wants, wantsFlagName, nil, "Add (weak) requirement dependencies to the generated unit file")
|
||||
_ = systemdCmd.RegisterFlagCompletionFunc(wantsFlagName, completion.AutocompleteNone)
|
||||
|
||||
flags.StringArrayVar(&systemdOptions.After, afterFlagName, nil, "Add dependencies order to the generated unit file")
|
||||
_ = systemdCmd.RegisterFlagCompletionFunc(afterFlagName, completion.AutocompleteNone)
|
||||
|
||||
flags.StringArrayVar(&systemdOptions.Requires, requiresFlagName, nil, "Similar to wants, but declares stronger requirement dependencies")
|
||||
_ = systemdCmd.RegisterFlagCompletionFunc(requiresFlagName, completion.AutocompleteNone)
|
||||
|
||||
flags.SetNormalizeFunc(utils.TimeoutAliasFlags)
|
||||
}
|
||||
|
||||
|
@ -68,6 +68,22 @@ Set the systemd unit name prefix for pods. The default is *pod*.
|
||||
|
||||
Set the systemd unit name separator between the name/id of a container/pod and the prefix. The default is *-*.
|
||||
|
||||
#### **--wants**=*dependency_name*
|
||||
|
||||
Add the systemd unit wants (`Wants=`) option, that this service is (weak) dependent on. This option may be specified more than once. This option does not influence the order in which services are started or stopped.
|
||||
|
||||
User-defined dependencies will be appended to the generated unit file, but any existing options such as needed or defined by default (e.g. `online.target`) will **not** be removed or overridden.
|
||||
|
||||
#### **--after**=*dependency_name*
|
||||
|
||||
Add the systemd unit after (`After=`) option, that ordering dependencies between the list of dependencies and this service. This option may be specified more than once.
|
||||
|
||||
User-defined dependencies will be appended to the generated unit file, but any existing options such as needed or defined by default (e.g. `online.target`) will **not** be removed or overridden.
|
||||
|
||||
#### **--requires**=*dependency_name*
|
||||
|
||||
Set the systemd unit requires (`Requires=`) option. Similar to wants, but declares a stronger requirement dependency.
|
||||
|
||||
#### **--template**
|
||||
|
||||
Add template specifiers to run multiple services from the systemd unit file.
|
||||
|
@ -17,17 +17,20 @@ func GenerateSystemd(w http.ResponseWriter, r *http.Request) {
|
||||
runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime)
|
||||
decoder := r.Context().Value(api.DecoderKey).(*schema.Decoder)
|
||||
query := struct {
|
||||
Name bool `schema:"useName"`
|
||||
New bool `schema:"new"`
|
||||
NoHeader bool `schema:"noHeader"`
|
||||
TemplateUnitFile bool `schema:"templateUnitFile"`
|
||||
RestartPolicy *string `schema:"restartPolicy"`
|
||||
RestartSec uint `schema:"restartSec"`
|
||||
StopTimeout uint `schema:"stopTimeout"`
|
||||
StartTimeout uint `schema:"startTimeout"`
|
||||
ContainerPrefix string `schema:"containerPrefix"`
|
||||
PodPrefix string `schema:"podPrefix"`
|
||||
Separator string `schema:"separator"`
|
||||
Name bool `schema:"useName"`
|
||||
New bool `schema:"new"`
|
||||
NoHeader bool `schema:"noHeader"`
|
||||
TemplateUnitFile bool `schema:"templateUnitFile"`
|
||||
RestartPolicy *string `schema:"restartPolicy"`
|
||||
RestartSec uint `schema:"restartSec"`
|
||||
StopTimeout uint `schema:"stopTimeout"`
|
||||
StartTimeout uint `schema:"startTimeout"`
|
||||
ContainerPrefix string `schema:"containerPrefix"`
|
||||
PodPrefix string `schema:"podPrefix"`
|
||||
Separator string `schema:"separator"`
|
||||
Wants []string `schema:"wants"`
|
||||
After []string `schema:"after"`
|
||||
Requires []string `schema:"requires"`
|
||||
}{
|
||||
StartTimeout: 0,
|
||||
StopTimeout: util.DefaultContainerConfig().Engine.StopTimeout,
|
||||
@ -55,6 +58,9 @@ func GenerateSystemd(w http.ResponseWriter, r *http.Request) {
|
||||
PodPrefix: query.PodPrefix,
|
||||
Separator: query.Separator,
|
||||
RestartSec: &query.RestartSec,
|
||||
Wants: query.Wants,
|
||||
After: query.After,
|
||||
Requires: query.Requires,
|
||||
}
|
||||
|
||||
report, err := containerEngine.GenerateSystemd(r.Context(), utils.GetName(r), options)
|
||||
|
@ -72,6 +72,27 @@ func (s *APIServer) registerGenerateHandlers(r *mux.Router) error {
|
||||
// type: integer
|
||||
// default: 0
|
||||
// description: Configures the time to sleep before restarting a service.
|
||||
// - in: query
|
||||
// name: wants
|
||||
// type: array
|
||||
// items:
|
||||
// type: string
|
||||
// default: []
|
||||
// description: Systemd Wants list for the container or pods.
|
||||
// - in: query
|
||||
// name: after
|
||||
// type: array
|
||||
// items:
|
||||
// type: string
|
||||
// default: []
|
||||
// description: Systemd After list for the container or pods.
|
||||
// - in: query
|
||||
// name: requires
|
||||
// type: array
|
||||
// items:
|
||||
// type: string
|
||||
// default: []
|
||||
// description: Systemd Requires list for the container or pods.
|
||||
// produces:
|
||||
// - application/json
|
||||
// responses:
|
||||
|
@ -32,4 +32,10 @@ type SystemdOptions struct {
|
||||
PodPrefix *string
|
||||
// Separator - systemd unit name separator between name/id and prefix
|
||||
Separator *string
|
||||
// Wants - systemd wants list for the container or pods
|
||||
Wants *[]string
|
||||
// After - systemd after list for the container or pods
|
||||
After *[]string
|
||||
// Requires - systemd requires list for the container or pods
|
||||
Requires *[]string
|
||||
}
|
||||
|
@ -181,3 +181,48 @@ func (o *SystemdOptions) GetSeparator() string {
|
||||
}
|
||||
return *o.Separator
|
||||
}
|
||||
|
||||
// WithWants set field Wants to given value
|
||||
func (o *SystemdOptions) WithWants(value []string) *SystemdOptions {
|
||||
o.Wants = &value
|
||||
return o
|
||||
}
|
||||
|
||||
// GetWants returns value of field Wants
|
||||
func (o *SystemdOptions) GetWants() []string {
|
||||
if o.Wants == nil {
|
||||
var z []string
|
||||
return z
|
||||
}
|
||||
return *o.Wants
|
||||
}
|
||||
|
||||
// WithAfter set field After to given value
|
||||
func (o *SystemdOptions) WithAfter(value []string) *SystemdOptions {
|
||||
o.After = &value
|
||||
return o
|
||||
}
|
||||
|
||||
// GetAfter returns value of field After
|
||||
func (o *SystemdOptions) GetAfter() []string {
|
||||
if o.After == nil {
|
||||
var z []string
|
||||
return z
|
||||
}
|
||||
return *o.After
|
||||
}
|
||||
|
||||
// WithRequires set field Requires to given value
|
||||
func (o *SystemdOptions) WithRequires(value []string) *SystemdOptions {
|
||||
o.Requires = &value
|
||||
return o
|
||||
}
|
||||
|
||||
// GetRequires returns value of field Requires
|
||||
func (o *SystemdOptions) GetRequires() []string {
|
||||
if o.Requires == nil {
|
||||
var z []string
|
||||
return z
|
||||
}
|
||||
return *o.Requires
|
||||
}
|
||||
|
@ -26,6 +26,12 @@ type GenerateSystemdOptions struct {
|
||||
NoHeader bool
|
||||
// TemplateUnitFile - make use of %i and %I to differentiate between the different instances of the unit
|
||||
TemplateUnitFile bool
|
||||
// Wants - systemd wants list for the container or pods
|
||||
Wants []string
|
||||
// After - systemd after list for the container or pods
|
||||
After []string
|
||||
// Requires - systemd requires list for the container or pods
|
||||
Requires []string
|
||||
}
|
||||
|
||||
// GenerateSystemdReport
|
||||
|
@ -8,7 +8,17 @@ 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).WithPodPrefix(opts.PodPrefix).WithSeparator(opts.Separator)
|
||||
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).
|
||||
WithWants(opts.Wants).
|
||||
WithAfter(opts.After).
|
||||
WithRequires(opts.Requires)
|
||||
|
||||
if opts.StartTimeout != nil {
|
||||
options.WithStartTimeout(*opts.StartTimeout)
|
||||
|
@ -94,6 +94,13 @@ type containerInfo struct {
|
||||
RunRoot string
|
||||
// Add %i and %I to description and execute parts
|
||||
IdentifySpecifier bool
|
||||
// Wants are the list of services that this service is (weak) dependent on. This
|
||||
// option does not influence the order in which services are started or stopped.
|
||||
Wants []string
|
||||
// After ordering dependencies between the list of services and this service.
|
||||
After []string
|
||||
// Similar to Wants, but declares a stronger requirement dependency.
|
||||
Requires []string
|
||||
}
|
||||
|
||||
const containerTemplate = headerTemplate + `
|
||||
@ -101,6 +108,19 @@ const containerTemplate = headerTemplate + `
|
||||
BindsTo={{{{- range $index, $value := .BoundToServices -}}}}{{{{if $index}}}} {{{{end}}}}{{{{ $value }}}}.service{{{{end}}}}
|
||||
After={{{{- range $index, $value := .BoundToServices -}}}}{{{{if $index}}}} {{{{end}}}}{{{{ $value }}}}.service{{{{end}}}}
|
||||
{{{{- end}}}}
|
||||
{{{{- if or .Wants .After .Requires }}}}
|
||||
|
||||
# User-defined dependencies
|
||||
{{{{- end}}}}
|
||||
{{{{- if .Wants}}}}
|
||||
Wants={{{{- range $index, $value := .Wants }}}}{{{{ if $index}}}} {{{{end}}}}{{{{ $value }}}}{{{{end}}}}
|
||||
{{{{- end}}}}
|
||||
{{{{- if .After}}}}
|
||||
After={{{{- range $index, $value := .After }}}}{{{{ if $index}}}} {{{{end}}}}{{{{ $value }}}}{{{{end}}}}
|
||||
{{{{- end}}}}
|
||||
{{{{- if .Requires}}}}
|
||||
Requires={{{{- range $index, $value := .Requires }}}}{{{{ if $index}}}} {{{{end}}}}{{{{ $value }}}}{{{{end}}}}
|
||||
{{{{- end}}}}
|
||||
|
||||
[Service]
|
||||
Environment={{{{.EnvVariable}}}}=%n{{{{- if (eq .IdentifySpecifier true) }}}}-%i{{{{- end}}}}
|
||||
@ -201,6 +221,9 @@ func generateContainerInfo(ctr *libpod.Container, options entities.GenerateSyste
|
||||
CreateCommand: createCommand,
|
||||
RunRoot: runRoot,
|
||||
containerEnv: envs,
|
||||
Wants: options.Wants,
|
||||
After: options.After,
|
||||
Requires: options.Requires,
|
||||
}
|
||||
|
||||
return &info, nil
|
||||
|
@ -87,6 +87,116 @@ ExecStopPost=/usr/bin/podman stop -t 10 foobar
|
||||
PIDFile=/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid
|
||||
Type=forking
|
||||
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
`
|
||||
|
||||
goodNameCustomWants := `# container-foobar.service
|
||||
# autogenerated by Podman CI
|
||||
|
||||
[Unit]
|
||||
Description=Podman container-foobar.service
|
||||
Documentation=man:podman-generate-systemd(1)
|
||||
Wants=network-online.target
|
||||
After=network-online.target
|
||||
RequiresMountsFor=/var/run/containers/storage
|
||||
|
||||
# User-defined dependencies
|
||||
Wants=a.service b.service c.target
|
||||
|
||||
[Service]
|
||||
Environment=PODMAN_SYSTEMD_UNIT=%n
|
||||
Restart=on-failure
|
||||
TimeoutStopSec=70
|
||||
ExecStart=/usr/bin/podman start foobar
|
||||
ExecStop=/usr/bin/podman stop -t 10 foobar
|
||||
ExecStopPost=/usr/bin/podman stop -t 10 foobar
|
||||
PIDFile=/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid
|
||||
Type=forking
|
||||
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
`
|
||||
|
||||
goodNameCustomAfter := `# container-foobar.service
|
||||
# autogenerated by Podman CI
|
||||
|
||||
[Unit]
|
||||
Description=Podman container-foobar.service
|
||||
Documentation=man:podman-generate-systemd(1)
|
||||
Wants=network-online.target
|
||||
After=network-online.target
|
||||
RequiresMountsFor=/var/run/containers/storage
|
||||
|
||||
# User-defined dependencies
|
||||
After=a.service b.service c.target
|
||||
|
||||
[Service]
|
||||
Environment=PODMAN_SYSTEMD_UNIT=%n
|
||||
Restart=on-failure
|
||||
TimeoutStopSec=70
|
||||
ExecStart=/usr/bin/podman start foobar
|
||||
ExecStop=/usr/bin/podman stop -t 10 foobar
|
||||
ExecStopPost=/usr/bin/podman stop -t 10 foobar
|
||||
PIDFile=/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid
|
||||
Type=forking
|
||||
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
`
|
||||
|
||||
goodNameCustomRequires := `# container-foobar.service
|
||||
# autogenerated by Podman CI
|
||||
|
||||
[Unit]
|
||||
Description=Podman container-foobar.service
|
||||
Documentation=man:podman-generate-systemd(1)
|
||||
Wants=network-online.target
|
||||
After=network-online.target
|
||||
RequiresMountsFor=/var/run/containers/storage
|
||||
|
||||
# User-defined dependencies
|
||||
Requires=a.service b.service c.target
|
||||
|
||||
[Service]
|
||||
Environment=PODMAN_SYSTEMD_UNIT=%n
|
||||
Restart=on-failure
|
||||
TimeoutStopSec=70
|
||||
ExecStart=/usr/bin/podman start foobar
|
||||
ExecStop=/usr/bin/podman stop -t 10 foobar
|
||||
ExecStopPost=/usr/bin/podman stop -t 10 foobar
|
||||
PIDFile=/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid
|
||||
Type=forking
|
||||
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
`
|
||||
|
||||
goodNameCustomDependencies := `# container-foobar.service
|
||||
# autogenerated by Podman CI
|
||||
|
||||
[Unit]
|
||||
Description=Podman container-foobar.service
|
||||
Documentation=man:podman-generate-systemd(1)
|
||||
Wants=network-online.target
|
||||
After=network-online.target
|
||||
RequiresMountsFor=/var/run/containers/storage
|
||||
|
||||
# User-defined dependencies
|
||||
Wants=a.service b.service c.target
|
||||
After=a.service b.service c.target
|
||||
Requires=a.service b.service c.target
|
||||
|
||||
[Service]
|
||||
Environment=PODMAN_SYSTEMD_UNIT=%n
|
||||
Restart=on-failure
|
||||
TimeoutStopSec=70
|
||||
ExecStart=/usr/bin/podman start foobar
|
||||
ExecStop=/usr/bin/podman stop -t 10 foobar
|
||||
ExecStopPost=/usr/bin/podman stop -t 10 foobar
|
||||
PIDFile=/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid
|
||||
Type=forking
|
||||
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
`
|
||||
@ -613,6 +723,84 @@ WantedBy=default.target
|
||||
false,
|
||||
false,
|
||||
},
|
||||
{"good with name and wants",
|
||||
containerInfo{
|
||||
Executable: "/usr/bin/podman",
|
||||
ServiceName: "container-foobar",
|
||||
ContainerNameOrID: "foobar",
|
||||
PIDFile: "/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid",
|
||||
StopTimeout: 10,
|
||||
PodmanVersion: "CI",
|
||||
Wants: []string{"a.service", "b.service", "c.target"},
|
||||
EnvVariable: define.EnvVariable,
|
||||
GraphRoot: "/var/lib/containers/storage",
|
||||
RunRoot: "/var/run/containers/storage",
|
||||
},
|
||||
goodNameCustomWants,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
},
|
||||
{"good with name and after",
|
||||
containerInfo{
|
||||
Executable: "/usr/bin/podman",
|
||||
ServiceName: "container-foobar",
|
||||
ContainerNameOrID: "foobar",
|
||||
PIDFile: "/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid",
|
||||
StopTimeout: 10,
|
||||
PodmanVersion: "CI",
|
||||
After: []string{"a.service", "b.service", "c.target"},
|
||||
EnvVariable: define.EnvVariable,
|
||||
GraphRoot: "/var/lib/containers/storage",
|
||||
RunRoot: "/var/run/containers/storage",
|
||||
},
|
||||
goodNameCustomAfter,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
},
|
||||
{"good with name and requires",
|
||||
containerInfo{
|
||||
Executable: "/usr/bin/podman",
|
||||
ServiceName: "container-foobar",
|
||||
ContainerNameOrID: "foobar",
|
||||
PIDFile: "/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid",
|
||||
StopTimeout: 10,
|
||||
PodmanVersion: "CI",
|
||||
Requires: []string{"a.service", "b.service", "c.target"},
|
||||
EnvVariable: define.EnvVariable,
|
||||
GraphRoot: "/var/lib/containers/storage",
|
||||
RunRoot: "/var/run/containers/storage",
|
||||
},
|
||||
goodNameCustomRequires,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
},
|
||||
{"good with name and dependencies",
|
||||
containerInfo{
|
||||
Executable: "/usr/bin/podman",
|
||||
ServiceName: "container-foobar",
|
||||
ContainerNameOrID: "foobar",
|
||||
PIDFile: "/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid",
|
||||
StopTimeout: 10,
|
||||
PodmanVersion: "CI",
|
||||
Wants: []string{"a.service", "b.service", "c.target"},
|
||||
After: []string{"a.service", "b.service", "c.target"},
|
||||
Requires: []string{"a.service", "b.service", "c.target"},
|
||||
EnvVariable: define.EnvVariable,
|
||||
GraphRoot: "/var/lib/containers/storage",
|
||||
RunRoot: "/var/run/containers/storage",
|
||||
},
|
||||
goodNameCustomDependencies,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
},
|
||||
{"good with name and bound to",
|
||||
containerInfo{
|
||||
Executable: "/usr/bin/podman",
|
||||
|
@ -83,10 +83,30 @@ type podInfo struct {
|
||||
RunRoot string
|
||||
// Add %i and %I to description and execute parts - this should not be used
|
||||
IdentifySpecifier bool
|
||||
// Wants are the list of services that this service is (weak) dependent on. This
|
||||
// option does not influence the order in which services are started or stopped.
|
||||
Wants []string
|
||||
// After ordering dependencies between the list of services and this service.
|
||||
After []string
|
||||
// Similar to Wants, but declares a stronger requirement dependency.
|
||||
Requires []string
|
||||
}
|
||||
|
||||
const podTemplate = headerTemplate + `Requires={{{{- range $index, $value := .RequiredServices -}}}}{{{{if $index}}}} {{{{end}}}}{{{{ $value }}}}.service{{{{end}}}}
|
||||
Before={{{{- range $index, $value := .RequiredServices -}}}}{{{{if $index}}}} {{{{end}}}}{{{{ $value }}}}.service{{{{end}}}}
|
||||
{{{{- if or .Wants .After .Requires }}}}
|
||||
|
||||
# User-defined dependencies
|
||||
{{{{- end}}}}
|
||||
{{{{- if .Wants}}}}
|
||||
Wants={{{{- range $index, $value := .Wants }}}}{{{{ if $index}}}} {{{{end}}}}{{{{ $value }}}}{{{{end}}}}
|
||||
{{{{- end}}}}
|
||||
{{{{- if .After}}}}
|
||||
After={{{{- range $index, $value := .After }}}}{{{{ if $index}}}} {{{{end}}}}{{{{ $value }}}}{{{{end}}}}
|
||||
{{{{- end}}}}
|
||||
{{{{- if .Requires}}}}
|
||||
Requires={{{{- range $index, $value := .Requires }}}}{{{{ if $index}}}} {{{{end}}}}{{{{ $value }}}}{{{{end}}}}
|
||||
{{{{- end}}}}
|
||||
|
||||
[Service]
|
||||
Environment={{{{.EnvVariable}}}}=%n
|
||||
|
@ -67,6 +67,121 @@ WantedBy=default.target
|
||||
podGood := serviceInfo + headerInfo + podContent
|
||||
podGoodNoHeaderInfo := serviceInfo + podContent
|
||||
|
||||
podGoodCustomWants := `# pod-123abc.service
|
||||
# autogenerated by Podman CI
|
||||
|
||||
[Unit]
|
||||
Description=Podman pod-123abc.service
|
||||
Documentation=man:podman-generate-systemd(1)
|
||||
Wants=network-online.target
|
||||
After=network-online.target
|
||||
RequiresMountsFor=/var/run/containers/storage
|
||||
Requires=container-1.service container-2.service
|
||||
Before=container-1.service container-2.service
|
||||
|
||||
# User-defined dependencies
|
||||
Wants=a.service b.service c.target
|
||||
|
||||
[Service]
|
||||
Environment=PODMAN_SYSTEMD_UNIT=%n
|
||||
Restart=on-failure
|
||||
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
|
||||
PIDFile=/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid
|
||||
Type=forking
|
||||
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
`
|
||||
podGoodCustomAfter := `# pod-123abc.service
|
||||
# autogenerated by Podman CI
|
||||
|
||||
[Unit]
|
||||
Description=Podman pod-123abc.service
|
||||
Documentation=man:podman-generate-systemd(1)
|
||||
Wants=network-online.target
|
||||
After=network-online.target
|
||||
RequiresMountsFor=/var/run/containers/storage
|
||||
Requires=container-1.service container-2.service
|
||||
Before=container-1.service container-2.service
|
||||
|
||||
# User-defined dependencies
|
||||
After=a.service b.service c.target
|
||||
|
||||
[Service]
|
||||
Environment=PODMAN_SYSTEMD_UNIT=%n
|
||||
Restart=on-failure
|
||||
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
|
||||
PIDFile=/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid
|
||||
Type=forking
|
||||
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
`
|
||||
podGoodCustomRequires := `# pod-123abc.service
|
||||
# autogenerated by Podman CI
|
||||
|
||||
[Unit]
|
||||
Description=Podman pod-123abc.service
|
||||
Documentation=man:podman-generate-systemd(1)
|
||||
Wants=network-online.target
|
||||
After=network-online.target
|
||||
RequiresMountsFor=/var/run/containers/storage
|
||||
Requires=container-1.service container-2.service
|
||||
Before=container-1.service container-2.service
|
||||
|
||||
# User-defined dependencies
|
||||
Requires=a.service b.service c.target
|
||||
|
||||
[Service]
|
||||
Environment=PODMAN_SYSTEMD_UNIT=%n
|
||||
Restart=on-failure
|
||||
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
|
||||
PIDFile=/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid
|
||||
Type=forking
|
||||
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
`
|
||||
podGoodCustomDependencies := `# pod-123abc.service
|
||||
# autogenerated by Podman CI
|
||||
|
||||
[Unit]
|
||||
Description=Podman pod-123abc.service
|
||||
Documentation=man:podman-generate-systemd(1)
|
||||
Wants=network-online.target
|
||||
After=network-online.target
|
||||
RequiresMountsFor=/var/run/containers/storage
|
||||
Requires=container-1.service container-2.service
|
||||
Before=container-1.service container-2.service
|
||||
|
||||
# User-defined dependencies
|
||||
Wants=a.service b.service c.target
|
||||
After=a.service b.service c.target
|
||||
Requires=a.service b.service c.target
|
||||
|
||||
[Service]
|
||||
Environment=PODMAN_SYSTEMD_UNIT=%n
|
||||
Restart=on-failure
|
||||
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
|
||||
PIDFile=/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid
|
||||
Type=forking
|
||||
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
`
|
||||
|
||||
podGoodRestartSec := `# pod-123abc.service
|
||||
# autogenerated by Podman CI
|
||||
|
||||
@ -232,6 +347,94 @@ WantedBy=default.target
|
||||
false,
|
||||
false,
|
||||
},
|
||||
{"pod",
|
||||
podInfo{
|
||||
Executable: "/usr/bin/podman",
|
||||
ServiceName: "pod-123abc",
|
||||
InfraNameOrID: "jadda-jadda-infra",
|
||||
PIDFile: "/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid",
|
||||
StopTimeout: 42,
|
||||
PodmanVersion: "CI",
|
||||
GraphRoot: "/var/lib/containers/storage",
|
||||
RunRoot: "/var/run/containers/storage",
|
||||
RequiredServices: []string{"container-1", "container-2"},
|
||||
Wants: []string{"a.service", "b.service", "c.target"},
|
||||
CreateCommand: []string{
|
||||
"podman", "pod", "create", "--name", "foo", "--wants", "a.service",
|
||||
"--wants", "b.service", "--wants", "c.target", "bar=arg with space"},
|
||||
},
|
||||
podGoodCustomWants,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
},
|
||||
{"pod",
|
||||
podInfo{
|
||||
Executable: "/usr/bin/podman",
|
||||
ServiceName: "pod-123abc",
|
||||
InfraNameOrID: "jadda-jadda-infra",
|
||||
PIDFile: "/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid",
|
||||
StopTimeout: 42,
|
||||
PodmanVersion: "CI",
|
||||
GraphRoot: "/var/lib/containers/storage",
|
||||
RunRoot: "/var/run/containers/storage",
|
||||
RequiredServices: []string{"container-1", "container-2"},
|
||||
After: []string{"a.service", "b.service", "c.target"},
|
||||
CreateCommand: []string{
|
||||
"podman", "pod", "create", "--name", "foo", "--after", "a.service",
|
||||
"--after", "b.service", "--after", "c.target", "bar=arg with space"},
|
||||
},
|
||||
podGoodCustomAfter,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
},
|
||||
{"pod",
|
||||
podInfo{
|
||||
Executable: "/usr/bin/podman",
|
||||
ServiceName: "pod-123abc",
|
||||
InfraNameOrID: "jadda-jadda-infra",
|
||||
PIDFile: "/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid",
|
||||
StopTimeout: 42,
|
||||
PodmanVersion: "CI",
|
||||
GraphRoot: "/var/lib/containers/storage",
|
||||
RunRoot: "/var/run/containers/storage",
|
||||
RequiredServices: []string{"container-1", "container-2"},
|
||||
Requires: []string{"a.service", "b.service", "c.target"},
|
||||
CreateCommand: []string{
|
||||
"podman", "pod", "create", "--name", "foo", "--requires", "a.service",
|
||||
"--requires", "b.service", "--requires", "c.target", "bar=arg with space"},
|
||||
},
|
||||
podGoodCustomRequires,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
},
|
||||
{"pod",
|
||||
podInfo{
|
||||
Executable: "/usr/bin/podman",
|
||||
ServiceName: "pod-123abc",
|
||||
InfraNameOrID: "jadda-jadda-infra",
|
||||
PIDFile: "/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid",
|
||||
StopTimeout: 42,
|
||||
PodmanVersion: "CI",
|
||||
GraphRoot: "/var/lib/containers/storage",
|
||||
RunRoot: "/var/run/containers/storage",
|
||||
RequiredServices: []string{"container-1", "container-2"},
|
||||
Wants: []string{"a.service", "b.service", "c.target"},
|
||||
After: []string{"a.service", "b.service", "c.target"},
|
||||
Requires: []string{"a.service", "b.service", "c.target"},
|
||||
CreateCommand: []string{
|
||||
"podman", "pod", "create", "--name", "foo", "--wants", "a.service",
|
||||
"--wants", "b.service", "--wants", "c.target", "--after", "a.service",
|
||||
"--after", "b.service", "--after", "c.target", "--requires", "a.service",
|
||||
"--requires", "b.service", "--requires", "c.target", "bar=arg with space"},
|
||||
},
|
||||
podGoodCustomDependencies,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
},
|
||||
{"pod restartSec",
|
||||
podInfo{
|
||||
Executable: "/usr/bin/podman",
|
||||
|
@ -159,6 +159,50 @@ var _ = Describe("Podman generate systemd", func() {
|
||||
Expect(session.OutputToString()).To(ContainSubstring("podman stop -t 5"))
|
||||
})
|
||||
|
||||
It("podman generate systemd with user-defined dependencies", func() {
|
||||
n := podmanTest.Podman([]string{"run", "--name", "nginx", "-dt", nginx})
|
||||
n.WaitWithDefaultTimeout()
|
||||
Expect(n).Should(Exit(0))
|
||||
|
||||
session := podmanTest.Podman([]string{"generate", "systemd", "--wants", "foobar.service", "nginx"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session).Should(Exit(0))
|
||||
|
||||
// The generated systemd unit should contain the User-defined Wants option
|
||||
Expect(session.OutputToString()).To(ContainSubstring("# User-defined dependencies"))
|
||||
Expect(session.OutputToString()).To(ContainSubstring("Wants=foobar.service"))
|
||||
|
||||
session = podmanTest.Podman([]string{"generate", "systemd", "--after", "foobar.service", "nginx"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session).Should(Exit(0))
|
||||
|
||||
// The generated systemd unit should contain the User-defined After option
|
||||
Expect(session.OutputToString()).To(ContainSubstring("# User-defined dependencies"))
|
||||
Expect(session.OutputToString()).To(ContainSubstring("After=foobar.service"))
|
||||
|
||||
session = podmanTest.Podman([]string{"generate", "systemd", "--requires", "foobar.service", "nginx"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session).Should(Exit(0))
|
||||
|
||||
// The generated systemd unit should contain the User-defined Requires option
|
||||
Expect(session.OutputToString()).To(ContainSubstring("# User-defined dependencies"))
|
||||
Expect(session.OutputToString()).To(ContainSubstring("Requires=foobar.service"))
|
||||
|
||||
session = podmanTest.Podman([]string{
|
||||
"generate", "systemd",
|
||||
"--wants", "foobar.service", "--wants", "barfoo.service",
|
||||
"--after", "foobar.service", "--after", "barfoo.service",
|
||||
"--requires", "foobar.service", "--requires", "barfoo.service", "nginx"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session).Should(Exit(0))
|
||||
|
||||
// The generated systemd unit should contain the User-defined Want, After, Requires options
|
||||
Expect(session.OutputToString()).To(ContainSubstring("# User-defined dependencies"))
|
||||
Expect(session.OutputToString()).To(ContainSubstring("Wants=foobar.service barfoo.service"))
|
||||
Expect(session.OutputToString()).To(ContainSubstring("After=foobar.service barfoo.service"))
|
||||
Expect(session.OutputToString()).To(ContainSubstring("Requires=foobar.service barfoo.service"))
|
||||
})
|
||||
|
||||
It("podman generate systemd pod --name", func() {
|
||||
n := podmanTest.Podman([]string{"pod", "create", "--name", "foo"})
|
||||
n.WaitWithDefaultTimeout()
|
||||
@ -213,6 +257,54 @@ var _ = Describe("Podman generate systemd", func() {
|
||||
Expect(session.OutputToString()).To(ContainSubstring("/container-foo-1.service"))
|
||||
})
|
||||
|
||||
It("podman generate systemd pod with user-defined dependencies", func() {
|
||||
n := podmanTest.Podman([]string{"pod", "create", "--name", "foo"})
|
||||
n.WaitWithDefaultTimeout()
|
||||
Expect(n).Should(Exit(0))
|
||||
|
||||
n = podmanTest.Podman([]string{"create", "--pod", "foo", "--name", "foo-1", "alpine", "top"})
|
||||
n.WaitWithDefaultTimeout()
|
||||
Expect(n).Should(Exit(0))
|
||||
|
||||
session := podmanTest.Podman([]string{"generate", "systemd", "--name", "--wants", "foobar.service", "foo"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session).Should(Exit(0))
|
||||
|
||||
// The generated systemd unit should contain the User-defined Wants option
|
||||
Expect(session.OutputToString()).To(ContainSubstring("# User-defined dependencies"))
|
||||
Expect(session.OutputToString()).To(ContainSubstring("Wants=foobar.service"))
|
||||
|
||||
session = podmanTest.Podman([]string{"generate", "systemd", "--name", "--after", "foobar.service", "foo"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session).Should(Exit(0))
|
||||
|
||||
// The generated systemd unit should contain the User-defined After option
|
||||
Expect(session.OutputToString()).To(ContainSubstring("# User-defined dependencies"))
|
||||
Expect(session.OutputToString()).To(ContainSubstring("After=foobar.service"))
|
||||
|
||||
session = podmanTest.Podman([]string{"generate", "systemd", "--name", "--requires", "foobar.service", "foo"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session).Should(Exit(0))
|
||||
|
||||
// The generated systemd unit should contain the User-defined Requires option
|
||||
Expect(session.OutputToString()).To(ContainSubstring("# User-defined dependencies"))
|
||||
Expect(session.OutputToString()).To(ContainSubstring("Requires=foobar.service"))
|
||||
|
||||
session = podmanTest.Podman([]string{
|
||||
"generate", "systemd", "--name",
|
||||
"--wants", "foobar.service", "--wants", "barfoo.service",
|
||||
"--after", "foobar.service", "--after", "barfoo.service",
|
||||
"--requires", "foobar.service", "--requires", "barfoo.service", "foo"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session).Should(Exit(0))
|
||||
|
||||
// The generated systemd unit should contain the User-defined Want, After, Requires options
|
||||
Expect(session.OutputToString()).To(ContainSubstring("# User-defined dependencies"))
|
||||
Expect(session.OutputToString()).To(ContainSubstring("Wants=foobar.service barfoo.service"))
|
||||
Expect(session.OutputToString()).To(ContainSubstring("After=foobar.service barfoo.service"))
|
||||
Expect(session.OutputToString()).To(ContainSubstring("Requires=foobar.service barfoo.service"))
|
||||
})
|
||||
|
||||
It("podman generate systemd --new --name foo", func() {
|
||||
n := podmanTest.Podman([]string{"create", "--name", "foo", "alpine", "top"})
|
||||
n.WaitWithDefaultTimeout()
|
||||
|
Reference in New Issue
Block a user