Skip to content

Commit

Permalink
Merge pull request #12887 from esendjer/main
Browse files Browse the repository at this point in the history
Add custom defined dependencies to podman generate systemd
  • Loading branch information
openshift-merge-robot authored Jan 20, 2022
2 parents 6b59b10 + b9a2d86 commit 7fc8bf4
Show file tree
Hide file tree
Showing 13 changed files with 660 additions and 12 deletions.
12 changes: 12 additions & 0 deletions cmd/podman/generate/systemd.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ const (
restartPolicyFlagName = "restart-policy"
restartSecFlagName = "restart-sec"
newFlagName = "new"
wantsFlagName = "wants"
afterFlagName = "after"
requiresFlagName = "requires"
)

var (
Expand Down Expand Up @@ -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)
}

Expand Down
16 changes: 16 additions & 0 deletions docs/source/markdown/podman-generate-systemd.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
28 changes: 17 additions & 11 deletions pkg/api/handlers/libpod/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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)
Expand Down
21 changes: 21 additions & 0 deletions pkg/api/server/register_generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
6 changes: 6 additions & 0 deletions pkg/bindings/generate/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
45 changes: 45 additions & 0 deletions pkg/bindings/generate/types_systemd_options.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions pkg/domain/entities/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
12 changes: 11 additions & 1 deletion pkg/domain/infra/tunnel/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
23 changes: 23 additions & 0 deletions pkg/systemd/generate/containers.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,13 +94,33 @@ 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 + `
{{{{- if .BoundToServices}}}}
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}}}}
Expand Down Expand Up @@ -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
Expand Down
Loading

0 comments on commit 7fc8bf4

Please sign in to comment.