diff options
-rw-r--r-- | cmd/podman/system/service_abi.go | 26 | ||||
-rw-r--r-- | cmd/podman/utils/signals_linux.go | 14 | ||||
-rw-r--r-- | cmd/podman/utils/signals_windows.go | 14 | ||||
-rw-r--r-- | libpod/runtime.go | 49 | ||||
-rw-r--r-- | pkg/env/env.go | 14 | ||||
-rw-r--r-- | pkg/spec/spec.go | 4 | ||||
-rw-r--r-- | pkg/systemd/generate/common.go | 13 | ||||
-rw-r--r-- | pkg/systemd/generate/common_test.go | 25 | ||||
-rw-r--r-- | pkg/systemd/generate/containers.go | 1 | ||||
-rw-r--r-- | pkg/systemd/generate/containers_test.go | 4 | ||||
-rw-r--r-- | pkg/systemd/generate/pods.go | 1 | ||||
-rw-r--r-- | pkg/systemd/generate/pods_test.go | 4 |
12 files changed, 157 insertions, 12 deletions
diff --git a/cmd/podman/system/service_abi.go b/cmd/podman/system/service_abi.go index 6c6dd42a4..95cbd19d9 100644 --- a/cmd/podman/system/service_abi.go +++ b/cmd/podman/system/service_abi.go @@ -5,8 +5,12 @@ package system import ( "context" "net" + "os" + "os/signal" "strings" + "github.com/containers/podman/v2/cmd/podman/utils" + "github.com/containers/podman/v2/libpod" api "github.com/containers/podman/v2/pkg/api/server" "github.com/containers/podman/v2/pkg/domain/entities" "github.com/containers/podman/v2/pkg/domain/infra" @@ -39,6 +43,7 @@ func restService(opts entities.ServiceOptions, flags *pflag.FlagSet, cfg *entiti return err } + startWatcher(rt) server, err := api.NewServerWithSettings(rt, opts.Timeout, listener) if err != nil { return err @@ -55,3 +60,24 @@ func restService(opts entities.ServiceOptions, flags *pflag.FlagSet, cfg *entiti } return err } + +// startWatcher starts a new SIGHUP go routine for the current config. +func startWatcher(rt *libpod.Runtime) { + // Setup the signal notifier + ch := make(chan os.Signal, 1) + signal.Notify(ch, utils.SIGHUP) + + go func() { + for { + // Block until the signal is received + logrus.Debugf("waiting for SIGHUP to reload configuration") + <-ch + if err := rt.Reload(); err != nil { + logrus.Errorf("unable to reload configuration: %v", err) + continue + } + } + }() + + logrus.Debugf("registered SIGHUP watcher for config") +} diff --git a/cmd/podman/utils/signals_linux.go b/cmd/podman/utils/signals_linux.go new file mode 100644 index 000000000..f0a14aff0 --- /dev/null +++ b/cmd/podman/utils/signals_linux.go @@ -0,0 +1,14 @@ +// +build !windows + +package utils + +import ( + "os" + + "golang.org/x/sys/unix" +) + +// Platform specific signal synonyms +var ( + SIGHUP os.Signal = unix.SIGHUP +) diff --git a/cmd/podman/utils/signals_windows.go b/cmd/podman/utils/signals_windows.go new file mode 100644 index 000000000..30b058cb9 --- /dev/null +++ b/cmd/podman/utils/signals_windows.go @@ -0,0 +1,14 @@ +// +build windows + +package utils + +import ( + "os" + + "golang.org/x/sys/windows" +) + +// Platform specific signal synonyms +var ( + SIGHUP os.Signal = windows.SIGHUP +) diff --git a/libpod/runtime.go b/libpod/runtime.go index 8a7053e33..1d2e624d8 100644 --- a/libpod/runtime.go +++ b/libpod/runtime.go @@ -10,6 +10,7 @@ import ( "syscall" "github.com/containers/common/pkg/config" + "github.com/containers/image/v5/pkg/sysregistriesv2" is "github.com/containers/image/v5/storage" "github.com/containers/image/v5/types" "github.com/containers/podman/v2/libpod/define" @@ -17,6 +18,7 @@ import ( "github.com/containers/podman/v2/libpod/image" "github.com/containers/podman/v2/libpod/lock" "github.com/containers/podman/v2/pkg/cgroups" + "github.com/containers/podman/v2/pkg/registries" "github.com/containers/podman/v2/pkg/rootless" "github.com/containers/podman/v2/pkg/util" "github.com/containers/storage" @@ -816,3 +818,50 @@ func (r *Runtime) mergeDBConfig(dbConfig *DBConfig) { func (r *Runtime) EnableLabeling() bool { return r.config.Containers.EnableLabeling } + +// Reload reloads the configurations files +func (r *Runtime) Reload() error { + if err := r.reloadContainersConf(); err != nil { + return err + } + if err := r.reloadStorageConf(); err != nil { + return err + } + if err := reloadRegistriesConf(); err != nil { + return err + } + return nil +} + +// reloadContainersConf reloads the containers.conf +func (r *Runtime) reloadContainersConf() error { + config, err := config.Reload() + if err != nil { + return err + } + r.config = config + logrus.Infof("applied new containers configuration: %v", config) + return nil +} + +// reloadRegistries reloads the registries.conf +func reloadRegistriesConf() error { + sysregistriesv2.InvalidateCache() + registries, err := sysregistriesv2.GetRegistries(&types.SystemContext{SystemRegistriesConfPath: registries.SystemRegistriesConfPath()}) + if err != nil { + return err + } + logrus.Infof("applied new registry configuration: %+v", registries) + return nil +} + +// reloadStorageConf reloads the storage.conf +func (r *Runtime) reloadStorageConf() error { + configFile, err := storage.DefaultConfigFile(rootless.IsRootless()) + if err != nil { + return err + } + storage.ReloadConfigurationFile(configFile, &r.storageConfig) + logrus.Infof("applied new storage configuration: %v", r.storageConfig) + return nil +} diff --git a/pkg/env/env.go b/pkg/env/env.go index a16007a50..0d55e5560 100644 --- a/pkg/env/env.go +++ b/pkg/env/env.go @@ -12,14 +12,16 @@ import ( "github.com/pkg/errors" ) -// DefaultEnvVariables sets $PATH and $TERM. -var DefaultEnvVariables = map[string]string{ - "PATH": "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", - "TERM": "xterm", -} - const whiteSpaces = " \t" +// DefaultEnvVariables returns a default environment, with $PATH and $TERM set. +func DefaultEnvVariables() map[string]string { + return map[string]string{ + "PATH": "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", + "TERM": "xterm", + } +} + // Slice transforms the specified map of environment variables into a // slice. If a value is non-empty, the key and value are joined with '='. func Slice(m map[string]string) []string { diff --git a/pkg/spec/spec.go b/pkg/spec/spec.go index c7a838d4c..893ae3cab 100644 --- a/pkg/spec/spec.go +++ b/pkg/spec/spec.go @@ -321,13 +321,13 @@ func (config *CreateConfig) createConfigToOCISpec(runtime *libpod.Runtime, userM // config. var defaultEnv map[string]string if runtimeConfig == nil { - defaultEnv = env.DefaultEnvVariables + defaultEnv = env.DefaultEnvVariables() } else { defaultEnv, err = env.ParseSlice(runtimeConfig.Containers.Env) if err != nil { return nil, errors.Wrap(err, "Env fields in containers.conf failed ot parse") } - defaultEnv = env.Join(env.DefaultEnvVariables, defaultEnv) + defaultEnv = env.Join(env.DefaultEnvVariables(), defaultEnv) } if err := addRlimits(config, &g); err != nil { diff --git a/pkg/systemd/generate/common.go b/pkg/systemd/generate/common.go index d6d18a810..1fc4479ff 100644 --- a/pkg/systemd/generate/common.go +++ b/pkg/systemd/generate/common.go @@ -1,6 +1,7 @@ package generate import ( + "strconv" "strings" "github.com/pkg/errors" @@ -53,3 +54,15 @@ func filterPodFlags(command []string) []string { } return processed } + +// quoteArguments 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. +func quoteArguments(command []string) []string { + for i := range command { + if strings.ContainsAny(command[i], " \t") { + command[i] = strconv.Quote(command[i]) + } + } + return command +} diff --git a/pkg/systemd/generate/common_test.go b/pkg/systemd/generate/common_test.go index 389c30f59..d0ec5637c 100644 --- a/pkg/systemd/generate/common_test.go +++ b/pkg/systemd/generate/common_test.go @@ -28,3 +28,28 @@ func TestFilterPodFlags(t *testing.T) { } } } + +func TestQuoteArguments(t *testing.T) { + tests := []struct { + input []string + output []string + }{ + { + []string{"foo", "bar=\"arg\""}, + []string{"foo", "bar=\"arg\""}, + }, + { + []string{"foo", "bar=\"arg with space\""}, + []string{"foo", "\"bar=\\\"arg with space\\\"\""}, + }, + { + []string{"foo", "bar=\"arg with\ttab\""}, + []string{"foo", "\"bar=\\\"arg with\\ttab\\\"\""}, + }, + } + + for _, test := range tests { + quoted := quoteArguments(test.input) + assert.Equal(t, test.output, quoted) + } +} diff --git a/pkg/systemd/generate/containers.go b/pkg/systemd/generate/containers.go index 3d266a7a1..5f6376977 100644 --- a/pkg/systemd/generate/containers.go +++ b/pkg/systemd/generate/containers.go @@ -241,6 +241,7 @@ func executeContainerTemplate(info *containerInfo, options entities.GenerateSyst startCommand = append(startCommand, "--replace") } startCommand = append(startCommand, info.CreateCommand[index:]...) + startCommand = quoteArguments(startCommand) info.ExecStartPre = "/bin/rm -f {{.PIDFile}} {{.ContainerIDFile}}" info.ExecStart = strings.Join(startCommand, " ") diff --git a/pkg/systemd/generate/containers_test.go b/pkg/systemd/generate/containers_test.go index 41817c03c..b5c736c5a 100644 --- a/pkg/systemd/generate/containers_test.go +++ b/pkg/systemd/generate/containers_test.go @@ -117,7 +117,7 @@ After=network-online.target Environment=PODMAN_SYSTEMD_UNIT=%n Restart=always ExecStartPre=/bin/rm -f %t/jadda-jadda.pid %t/jadda-jadda.ctr-id -ExecStart=/usr/bin/podman run --conmon-pidfile %t/jadda-jadda.pid --cidfile %t/jadda-jadda.ctr-id --cgroups=no-conmon -d --replace --name jadda-jadda --hostname hello-world awesome-image:latest command arg1 ... argN +ExecStart=/usr/bin/podman run --conmon-pidfile %t/jadda-jadda.pid --cidfile %t/jadda-jadda.ctr-id --cgroups=no-conmon -d --replace --name jadda-jadda --hostname hello-world awesome-image:latest command arg1 ... argN "foo=arg \"with \" space" ExecStop=/usr/bin/podman stop --ignore --cidfile %t/jadda-jadda.ctr-id -t 42 ExecStopPost=/usr/bin/podman rm --ignore -f --cidfile %t/jadda-jadda.ctr-id PIDFile=%t/jadda-jadda.pid @@ -296,7 +296,7 @@ WantedBy=multi-user.target default.target` PIDFile: "/var/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid", StopTimeout: 42, PodmanVersion: "CI", - CreateCommand: []string{"I'll get stripped", "container", "run", "--name", "jadda-jadda", "--hostname", "hello-world", "awesome-image:latest", "command", "arg1", "...", "argN"}, + CreateCommand: []string{"I'll get stripped", "container", "run", "--name", "jadda-jadda", "--hostname", "hello-world", "awesome-image:latest", "command", "arg1", "...", "argN", "foo=arg \"with \" space"}, EnvVariable: EnvVariable, }, goodWithNameAndGeneric, diff --git a/pkg/systemd/generate/pods.go b/pkg/systemd/generate/pods.go index ec28dfe84..dec9587d9 100644 --- a/pkg/systemd/generate/pods.go +++ b/pkg/systemd/generate/pods.go @@ -292,6 +292,7 @@ func executePodTemplate(info *podInfo, options entities.GenerateSystemdOptions) } startCommand = append(startCommand, podCreateArgs...) + startCommand = quoteArguments(startCommand) info.ExecStartPre1 = "/bin/rm -f {{.PIDFile}} {{.PodIDFile}}" info.ExecStartPre2 = strings.Join(startCommand, " ") diff --git a/pkg/systemd/generate/pods_test.go b/pkg/systemd/generate/pods_test.go index 32c760956..8bf4705a7 100644 --- a/pkg/systemd/generate/pods_test.go +++ b/pkg/systemd/generate/pods_test.go @@ -75,7 +75,7 @@ Before=container-1.service container-2.service Environment=PODMAN_SYSTEMD_UNIT=%n Restart=on-failure ExecStartPre=/bin/rm -f %t/pod-123abc.pid %t/pod-123abc.pod-id -ExecStartPre=/usr/bin/podman pod create --infra-conmon-pidfile %t/pod-123abc.pid --pod-id-file %t/pod-123abc.pod-id --name foo --replace +ExecStartPre=/usr/bin/podman pod create --infra-conmon-pidfile %t/pod-123abc.pid --pod-id-file %t/pod-123abc.pod-id --name foo "bar=arg with space" --replace ExecStart=/usr/bin/podman pod start --pod-id-file %t/pod-123abc.pod-id ExecStop=/usr/bin/podman pod stop --ignore --pod-id-file %t/pod-123abc.pod-id -t 10 ExecStopPost=/usr/bin/podman pod rm --ignore -f --pod-id-file %t/pod-123abc.pod-id @@ -118,7 +118,7 @@ WantedBy=multi-user.target default.target` StopTimeout: 10, PodmanVersion: "CI", RequiredServices: []string{"container-1", "container-2"}, - CreateCommand: []string{"podman", "pod", "create", "--name", "foo"}, + CreateCommand: []string{"podman", "pod", "create", "--name", "foo", "bar=arg with space"}, }, podGoodNamedNew, true, |