mirror of https://github.com/containers/podman.git
				
				
				
			
		
			
				
	
	
		
			109 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			Go
		
	
	
	
			
		
		
	
	
			109 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			Go
		
	
	
	
| package generate
 | |
| 
 | |
| import (
 | |
| 	"strconv"
 | |
| 	"strings"
 | |
| 
 | |
| 	"github.com/pkg/errors"
 | |
| )
 | |
| 
 | |
| // EnvVariable "PODMAN_SYSTEMD_UNIT" is set in all generated systemd units and
 | |
| // is set to the unit's (unique) name.
 | |
| const EnvVariable = "PODMAN_SYSTEMD_UNIT"
 | |
| 
 | |
| // minTimeoutStopSec is the minimal stop timeout for generated systemd units.
 | |
| // Once exceeded, processes of the services are killed and the cgroup(s) are
 | |
| // cleaned up.
 | |
| const minTimeoutStopSec = 60
 | |
| 
 | |
| // RestartPolicies includes all valid restart policies to be used in a unit
 | |
| // file.
 | |
| var RestartPolicies = []string{"no", "on-success", "on-failure", "on-abnormal", "on-watchdog", "on-abort", "always"}
 | |
| 
 | |
| // validateRestartPolicy checks that the user-provided policy is valid.
 | |
| func validateRestartPolicy(restart string) error {
 | |
| 	for _, i := range RestartPolicies {
 | |
| 		if i == restart {
 | |
| 			return nil
 | |
| 		}
 | |
| 	}
 | |
| 	return errors.Errorf("%s is not a valid restart policy", restart)
 | |
| }
 | |
| 
 | |
| const headerTemplate = `# {{{{.ServiceName}}}}.service
 | |
| # autogenerated by Podman {{{{.PodmanVersion}}}}
 | |
| {{{{- if .TimeStamp}}}}
 | |
| # {{{{.TimeStamp}}}}
 | |
| {{{{- end}}}}
 | |
| 
 | |
| [Unit]
 | |
| Description=Podman {{{{.ServiceName}}}}.service
 | |
| Documentation=man:podman-generate-systemd(1)
 | |
| Wants=network.target
 | |
| After=network-online.target
 | |
| `
 | |
| 
 | |
| // filterPodFlags removes --pod and --pod-id-file from the specified command.
 | |
| func filterPodFlags(command []string) []string {
 | |
| 	processed := []string{}
 | |
| 	for i := 0; i < len(command); i++ {
 | |
| 		s := command[i]
 | |
| 		if s == "--pod" || s == "--pod-id-file" {
 | |
| 			i++
 | |
| 			continue
 | |
| 		}
 | |
| 		if strings.HasPrefix(s, "--pod=") || strings.HasPrefix(s, "--pod-id-file=") {
 | |
| 			continue
 | |
| 		}
 | |
| 		processed = append(processed, s)
 | |
| 	}
 | |
| 	return processed
 | |
| }
 | |
| 
 | |
| // escapeSystemdArguments makes sure that all arguments with at least one whitespace
 | |
| // are quoted to make sure those are interpreted as one argument instead of
 | |
| // multiple ones. Also make sure to escape all characters which have a special
 | |
| // meaning to systemd -> $,% and \
 | |
| // see: https://www.freedesktop.org/software/systemd/man/systemd.service.html#Command%20lines
 | |
| func escapeSystemdArguments(command []string) []string {
 | |
| 	for i := range command {
 | |
| 		command[i] = strings.ReplaceAll(command[i], "$", "$$")
 | |
| 		command[i] = strings.ReplaceAll(command[i], "%", "%%")
 | |
| 		if strings.ContainsAny(command[i], " \t") {
 | |
| 			command[i] = strconv.Quote(command[i])
 | |
| 		} else if strings.Contains(command[i], `\`) {
 | |
| 			// strconv.Quote also escapes backslashes so
 | |
| 			// we should replace only if strconv.Quote was not used
 | |
| 			command[i] = strings.ReplaceAll(command[i], `\`, `\\`)
 | |
| 		}
 | |
| 	}
 | |
| 	return command
 | |
| }
 | |
| 
 | |
| func removeDetachArg(args []string, argCount int) []string {
 | |
| 	// "--detach=false" could also be in the container entrypoint
 | |
| 	// split them off so we do not remove it there
 | |
| 	realArgs := args[len(args)-argCount:]
 | |
| 	flagArgs := removeArg("-d=false", args[:len(args)-argCount])
 | |
| 	flagArgs = removeArg("--detach=false", flagArgs)
 | |
| 	return append(flagArgs, realArgs...)
 | |
| }
 | |
| 
 | |
| func removeReplaceArg(args []string, argCount int) []string {
 | |
| 	// "--replace=false" could also be in the container entrypoint
 | |
| 	// split them off so we do not remove it there
 | |
| 	realArgs := args[len(args)-argCount:]
 | |
| 	flagArgs := removeArg("--replace=false", args[:len(args)-argCount])
 | |
| 	return append(flagArgs, realArgs...)
 | |
| }
 | |
| 
 | |
| func removeArg(arg string, args []string) []string {
 | |
| 	newArgs := []string{}
 | |
| 	for _, a := range args {
 | |
| 		if a != arg {
 | |
| 			newArgs = append(newArgs, a)
 | |
| 		}
 | |
| 	}
 | |
| 	return newArgs
 | |
| }
 |