diff options
Diffstat (limited to 'pkg')
-rw-r--r-- | pkg/api/handlers/libpod/generate.go | 34 | ||||
-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 | 2 | ||||
-rw-r--r-- | pkg/systemd/generate/common.go | 4 | ||||
-rw-r--r-- | pkg/systemd/generate/containers.go | 31 | ||||
-rw-r--r-- | pkg/systemd/generate/pods.go | 5 |
8 files changed, 74 insertions, 21 deletions
diff --git a/pkg/api/handlers/libpod/generate.go b/pkg/api/handlers/libpod/generate.go index 117c5e2aa..5205d875d 100644 --- a/pkg/api/handlers/libpod/generate.go +++ b/pkg/api/handlers/libpod/generate.go @@ -17,14 +17,15 @@ 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"` - RestartPolicy *string `schema:"restartPolicy"` - StopTimeout uint `schema:"stopTimeout"` - 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"` + StopTimeout uint `schema:"stopTimeout"` + ContainerPrefix string `schema:"containerPrefix"` + PodPrefix string `schema:"podPrefix"` + Separator string `schema:"separator"` }{ StopTimeout: util.DefaultContainerConfig().Engine.StopTimeout, ContainerPrefix: "container", @@ -40,14 +41,15 @@ func GenerateSystemd(w http.ResponseWriter, r *http.Request) { containerEngine := abi.ContainerEngine{Libpod: runtime} options := entities.GenerateSystemdOptions{ - Name: query.Name, - New: query.New, - NoHeader: query.NoHeader, - RestartPolicy: query.RestartPolicy, - StopTimeout: &query.StopTimeout, - ContainerPrefix: query.ContainerPrefix, - PodPrefix: query.PodPrefix, - Separator: query.Separator, + Name: query.Name, + New: query.New, + NoHeader: query.NoHeader, + TemplateUnitFile: query.TemplateUnitFile, + RestartPolicy: query.RestartPolicy, + StopTimeout: &query.StopTimeout, + ContainerPrefix: query.ContainerPrefix, + PodPrefix: query.PodPrefix, + Separator: query.Separator, } report, err := containerEngine.GenerateSystemd(r.Context(), utils.GetName(r), options) diff --git a/pkg/bindings/generate/types.go b/pkg/bindings/generate/types.go index 3c9ea87d4..6f2594604 100644 --- a/pkg/bindings/generate/types.go +++ b/pkg/bindings/generate/types.go @@ -16,6 +16,8 @@ type SystemdOptions struct { New *bool // NoHeader - Removes autogenerated by Podman and timestamp if set to true NoHeader *bool + // TemplateUnitFile - Create a template unit file that uses the identity specifiers + TemplateUnitFile *bool // RestartPolicy - systemd restart policy. RestartPolicy *string // StopTimeout - time when stopping the container. diff --git a/pkg/bindings/generate/types_systemd_options.go b/pkg/bindings/generate/types_systemd_options.go index 7a778a52b..b26aa7fc2 100644 --- a/pkg/bindings/generate/types_systemd_options.go +++ b/pkg/bindings/generate/types_systemd_options.go @@ -62,6 +62,21 @@ func (o *SystemdOptions) GetNoHeader() bool { return *o.NoHeader } +// WithTemplateUnitFile set field TemplateUnitFile to given value +func (o *SystemdOptions) WithTemplateUnitFile(value bool) *SystemdOptions { + o.TemplateUnitFile = &value + return o +} + +// GetTemplateUnitFile returns value of field TemplateUnitFile +func (o *SystemdOptions) GetTemplateUnitFile() bool { + if o.TemplateUnitFile == nil { + var z bool + return z + } + return *o.TemplateUnitFile +} + // WithRestartPolicy set field RestartPolicy to given value func (o *SystemdOptions) WithRestartPolicy(value string) *SystemdOptions { o.RestartPolicy = &value diff --git a/pkg/domain/entities/generate.go b/pkg/domain/entities/generate.go index 7809c5241..dfb5bfc6c 100644 --- a/pkg/domain/entities/generate.go +++ b/pkg/domain/entities/generate.go @@ -20,6 +20,8 @@ type GenerateSystemdOptions struct { Separator string // NoHeader - skip header generation NoHeader bool + // TemplateUnitFile - make use of %i and %I to differentiate between the different instances of the unit + TemplateUnitFile bool } // GenerateSystemdReport diff --git a/pkg/domain/infra/tunnel/generate.go b/pkg/domain/infra/tunnel/generate.go index 9f69abb1a..3a35dd59c 100644 --- a/pkg/domain/infra/tunnel/generate.go +++ b/pkg/domain/infra/tunnel/generate.go @@ -8,7 +8,7 @@ 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) + 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) diff --git a/pkg/systemd/generate/common.go b/pkg/systemd/generate/common.go index 3515bb3b7..24c85a27e 100644 --- a/pkg/systemd/generate/common.go +++ b/pkg/systemd/generate/common.go @@ -23,7 +23,7 @@ func validateRestartPolicy(restart string) error { return errors.Errorf("%s is not a valid restart policy", restart) } -const headerTemplate = `# {{{{.ServiceName}}}}.service +const headerTemplate = `# {{{{.ServiceName}}}}{{{{- if (eq .IdentifySpecifier true) }}}}@{{{{- end}}}}.service {{{{- if (eq .GenerateNoHeader false) }}}} # autogenerated by Podman {{{{.PodmanVersion}}}} {{{{- if .TimeStamp}}}} @@ -32,7 +32,7 @@ const headerTemplate = `# {{{{.ServiceName}}}}.service {{{{- end}}}} [Unit] -Description=Podman {{{{.ServiceName}}}}.service +Description=Podman {{{{.ServiceName}}}}.service{{{{- if (eq .IdentifySpecifier true) }}}} for %I{{{{- end}}}} Documentation=man:podman-generate-systemd(1) Wants=network-online.target After=network-online.target diff --git a/pkg/systemd/generate/containers.go b/pkg/systemd/generate/containers.go index 037652a6d..c0a49c614 100644 --- a/pkg/systemd/generate/containers.go +++ b/pkg/systemd/generate/containers.go @@ -90,6 +90,8 @@ type containerInfo struct { // Location of the RunRoot for the container. Required for ensuring the tmpfs // or volume exists and is mounted when coming online at boot. RunRoot string + // Add %i and %I to description and execute parts + IdentifySpecifier bool } const containerTemplate = headerTemplate + ` @@ -99,7 +101,7 @@ After={{{{- range $index, $value := .BoundToServices -}}}}{{{{if $index}}}} {{{{ {{{{- end}}}} [Service] -Environment={{{{.EnvVariable}}}}=%n +Environment={{{{.EnvVariable}}}}=%n{{{{- if (eq .IdentifySpecifier true) }}}}-%i{{{{- end}}}} {{{{- if .ExtraEnvs}}}} Environment={{{{- range $index, $value := .ExtraEnvs -}}}}{{{{if $index}}}} {{{{end}}}}{{{{ $value }}}}{{{{end}}}} {{{{- end}}}} @@ -273,7 +275,6 @@ func executeContainerTemplate(info *containerInfo, options entities.GenerateSyst "--rm", ) remainingCmd := info.CreateCommand[index:] - // Presence check for certain flags/options. fs := pflag.NewFlagSet("args", pflag.ContinueOnError) fs.ParseErrorsWhitelist.UnknownFlags = true @@ -389,6 +390,32 @@ func executeContainerTemplate(info *containerInfo, options entities.GenerateSyst startCommand = append(startCommand, remainingCmd...) startCommand = escapeSystemdArguments(startCommand) + if options.TemplateUnitFile { + info.IdentifySpecifier = true + runIx := -1 + nameIx := -1 + for argIx, arg := range startCommand { + if arg == "run" { + runIx = argIx + continue + } + if arg == "--name" { + nameIx = argIx + 1 + break + } + if strings.HasPrefix(arg, "--name=") { + nameIx = argIx + break + } + } + if nameIx == -1 { + startCommand = append(startCommand[:runIx+1], startCommand[runIx:]...) + startCommand[runIx+1] = fmt.Sprintf("--name=%s-%%i", info.ServiceName) + fmt.Println(startCommand) + } else { + startCommand[nameIx] = fmt.Sprintf("%s-%%i", startCommand[nameIx]) + } + } info.ExecStart = strings.Join(startCommand, " ") } diff --git a/pkg/systemd/generate/pods.go b/pkg/systemd/generate/pods.go index e755b8eea..38f7e8e3e 100644 --- a/pkg/systemd/generate/pods.go +++ b/pkg/systemd/generate/pods.go @@ -79,6 +79,8 @@ type podInfo struct { // Location of the RunRoot for the pod. Required for ensuring the tmpfs // or volume exists and is mounted when coming online at boot. RunRoot string + // Add %i and %I to description and execute parts - this should not be used + IdentifySpecifier bool } const podTemplate = headerTemplate + `Requires={{{{- range $index, $value := .RequiredServices -}}}}{{{{if $index}}}} {{{{end}}}}{{{{ $value }}}}.service{{{{end}}}} @@ -108,6 +110,9 @@ WantedBy=multi-user.target default.target // Based on the options, the return value might be the content of all units or // the files they been written to. func PodUnits(pod *libpod.Pod, options entities.GenerateSystemdOptions) (map[string]string, error) { + if options.TemplateUnitFile { + return nil, errors.New("--template is not supported for pods") + } // Error out if the pod has no infra container, which we require to be the // main service. if !pod.HasInfraContainer() { |