Skip to content

Commit

Permalink
Add generate systemd -e/--env option
Browse files Browse the repository at this point in the history
-e/--env option sets environment variables to the systemd unit files.

Fixes: containers#15523

Signed-off-by: Toshiki Sonoda <sonoda.toshiki@fujitsu.com>
  • Loading branch information
sstosh committed Sep 5, 2022
1 parent 9ab6449 commit a8d8e75
Show file tree
Hide file tree
Showing 10 changed files with 198 additions and 149 deletions.
16 changes: 16 additions & 0 deletions cmd/podman/generate/systemd.go
Expand Up @@ -13,6 +13,7 @@ import (
"github.com/containers/podman/v4/cmd/podman/registry"
"github.com/containers/podman/v4/cmd/podman/utils"
"github.com/containers/podman/v4/pkg/domain/entities"
envLib "github.com/containers/podman/v4/pkg/env"
systemDefine "github.com/containers/podman/v4/pkg/systemd/define"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
Expand All @@ -28,9 +29,11 @@ const (
wantsFlagName = "wants"
afterFlagName = "after"
requiresFlagName = "requires"
envFlagName = "env"
)

var (
envInput []string
files bool
format string
systemdRestart string
Expand Down Expand Up @@ -109,6 +112,9 @@ func init() {
flags.StringArrayVar(&systemdOptions.Requires, requiresFlagName, nil, "Similar to wants, but declares stronger requirement dependencies")
_ = systemdCmd.RegisterFlagCompletionFunc(requiresFlagName, completion.AutocompleteNone)

flags.StringArrayVarP(&envInput, envFlagName, "e", []string{}, "Set environment variables to the systemd unit files")
_ = systemdCmd.RegisterFlagCompletionFunc(envFlagName, completion.AutocompleteNone)

flags.SetNormalizeFunc(utils.TimeoutAliasFlags)
}

Expand Down Expand Up @@ -141,6 +147,16 @@ func systemd(cmd *cobra.Command, args []string) error {
if cmd.Flags().Changed(stopTimeoutCompatFlagName) {
setStopTimeout++
}
if cmd.Flags().Changed(envFlagName) {
systemdOptions.AdditionalEnvVariables = make(map[string]string)

cliEnv, err := envLib.ParseSlice(envInput)
if err != nil {
return fmt.Errorf("error parsing environment variables: %w", err)
}

systemdOptions.AdditionalEnvVariables = envLib.Join(systemdOptions.AdditionalEnvVariables, cliEnv)
}
switch setStopTimeout {
case 1:
systemdOptions.StopTimeout = &stopTimeout
Expand Down
8 changes: 8 additions & 0 deletions docs/source/markdown/podman-generate-systemd.1.md
Expand Up @@ -44,6 +44,14 @@ User-defined dependencies will be appended to the generated unit file, but any e

Set the systemd unit name prefix for containers. The default is *container*.

#### **--env**, **-e**=*env*

Set environment variables to the systemd unit files.

If an environment variable is specified without a value, Podman will check the host environment for a value and set the variable only if it is set on the host. As a special case, if an environment variable ending in __*__ is specified without a value, Podman will search the host environment for variables starting with the prefix and will add those variables to the systemd unit files.

See [**Environment**](#environment) note below for precedence and examples.

#### **--files**, **-f**

Generate files instead of printing to stdout. The generated files are named {container,pod}-{ID,name}.service and will be placed in the current working directory.
Expand Down
58 changes: 30 additions & 28 deletions pkg/api/handlers/libpod/generate.go
Expand Up @@ -17,20 +17,21 @@ 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"`
Wants []string `schema:"wants"`
After []string `schema:"after"`
Requires []string `schema:"requires"`
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"`
AdditionalEnvVariables map[string]string `schema:"additionalEnvVariables"`
}{
StartTimeout: 0,
StopTimeout: util.DefaultContainerConfig().Engine.StopTimeout,
Expand Down Expand Up @@ -58,20 +59,21 @@ 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,
TemplateUnitFile: query.TemplateUnitFile,
RestartPolicy: query.RestartPolicy,
StartTimeout: &query.StartTimeout,
StopTimeout: &query.StopTimeout,
ContainerPrefix: ContainerPrefix,
PodPrefix: PodPrefix,
Separator: Separator,
RestartSec: &query.RestartSec,
Wants: query.Wants,
After: query.After,
Requires: query.Requires,
Name: query.Name,
New: query.New,
NoHeader: query.NoHeader,
TemplateUnitFile: query.TemplateUnitFile,
RestartPolicy: query.RestartPolicy,
StartTimeout: &query.StartTimeout,
StopTimeout: &query.StopTimeout,
ContainerPrefix: ContainerPrefix,
PodPrefix: PodPrefix,
Separator: Separator,
RestartSec: &query.RestartSec,
Wants: query.Wants,
After: query.After,
Requires: query.Requires,
AdditionalEnvVariables: query.AdditionalEnvVariables,
}

report, err := containerEngine.GenerateSystemd(r.Context(), utils.GetName(r), options)
Expand Down
7 changes: 7 additions & 0 deletions pkg/api/server/register_generate.go
Expand Up @@ -93,6 +93,13 @@ func (s *APIServer) registerGenerateHandlers(r *mux.Router) error {
// type: string
// default: []
// description: Systemd Requires list for the container or pods.
// - in: query
// name: additionalEnvVariables
// type: array
// items:
// type: string
// default: []
// description: Set environment variables to the systemd unit files.
// produces:
// - application/json
// responses:
Expand Down
2 changes: 2 additions & 0 deletions pkg/bindings/generate/types.go
Expand Up @@ -38,4 +38,6 @@ type SystemdOptions struct {
After *[]string
// Requires - systemd requires list for the container or pods
Requires *[]string
// AdditionalEnvVariables - environment variables setted by -e/--env
AdditionalEnvVariables map[string]string
}
15 changes: 15 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.

43 changes: 15 additions & 28 deletions pkg/domain/entities/generate.go
Expand Up @@ -4,34 +4,21 @@ import "io"

// GenerateSystemdOptions control the generation of systemd unit files.
type GenerateSystemdOptions struct {
// Name - use container/pod name instead of its ID.
Name bool
// New - create a new container instead of starting a new one.
New bool
// RestartPolicy - systemd restart policy.
RestartPolicy *string
// RestartSec - systemd service restartsec. Configures the time to sleep before restarting a service.
RestartSec *uint
// StartTimeout - time when starting the container.
StartTimeout *uint
// StopTimeout - time when stopping the container.
StopTimeout *uint
// ContainerPrefix - systemd unit name prefix for containers
ContainerPrefix string
// PodPrefix - systemd unit name prefix for pods
PodPrefix string
// Separator - systemd unit name separator between name/id and prefix
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
// 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
Name bool
New bool
RestartPolicy *string
RestartSec *uint
StartTimeout *uint
StopTimeout *uint
ContainerPrefix string
PodPrefix string
Separator string
NoHeader bool
TemplateUnitFile bool
Wants []string
After []string
Requires []string
AdditionalEnvVariables map[string]string
}

// GenerateSystemdReport
Expand Down
3 changes: 2 additions & 1 deletion pkg/domain/infra/tunnel/generate.go
Expand Up @@ -19,7 +19,8 @@ func (ic *ContainerEngine) GenerateSystemd(ctx context.Context, nameOrID string,
WithSeparator(opts.Separator).
WithWants(opts.Wants).
WithAfter(opts.After).
WithRequires(opts.Requires)
WithRequires(opts.Requires).
WithAdditionalEnvVariables(opts.AdditionalEnvVariables)

if opts.StartTimeout != nil {
options.WithStartTimeout(*opts.StartTimeout)
Expand Down

0 comments on commit a8d8e75

Please sign in to comment.