spiegel_podman/cmd/podman/system/service.go
Valentin Rothberg 4e29ce2baf use cached containers.conf
Use `Default()` instead of re-loading containers.conf.

Also rework how the containers.conf objects are handled for parsing the
CLI.  Previously, we were conflating "loading the defaults" with
"storing values from the CLI" with "libpod may further change fields"
which ultimately led to various bugs and test failues.

To address the issue, separate the defaults from the values from the CLI
and properly name the fields to make the semantics less ambiguous.

[NO NEW TESTS NEEDED] as it's not a functional change.

Fixes: containers/common/issues/1200
Signed-off-by: Valentin Rothberg <vrothberg@redhat.com>
2022-10-21 14:03:14 +02:00

149 lines
4.1 KiB
Go

//go:build linux && !remote
// +build linux,!remote
package system
import (
"net/url"
"os"
"path/filepath"
"syscall"
"time"
"github.com/containers/common/pkg/completion"
"github.com/containers/podman/v4/cmd/podman/common"
"github.com/containers/podman/v4/cmd/podman/registry"
"github.com/containers/podman/v4/pkg/domain/entities"
"github.com/containers/podman/v4/pkg/rootless"
"github.com/containers/podman/v4/pkg/systemd"
"github.com/containers/podman/v4/pkg/util"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
)
var (
srvDescription = `Run an API service
Enable a listening service for API access to Podman commands.
`
srvCmd = &cobra.Command{
Annotations: map[string]string{registry.EngineMode: registry.ABIMode},
Use: "service [options] [URI]",
Args: cobra.MaximumNArgs(1),
Short: "Run API service",
Long: srvDescription,
RunE: service,
ValidArgsFunction: common.AutocompleteDefaultOneArg,
Example: `podman system service --time=0 unix:///tmp/podman.sock
podman system service --time=0 tcp://localhost:8888`,
}
srvArgs = struct {
CorsHeaders string
PProfAddr string
Timeout uint
}{}
)
func init() {
registry.Commands = append(registry.Commands, registry.CliCommand{
Command: srvCmd,
Parent: systemCmd,
})
flags := srvCmd.Flags()
cfg := registry.PodmanConfig()
timeFlagName := "time"
flags.UintVarP(&srvArgs.Timeout, timeFlagName, "t", cfg.ContainersConfDefaultsRO.Engine.ServiceTimeout,
"Time until the service session expires in seconds. Use 0 to disable the timeout")
_ = srvCmd.RegisterFlagCompletionFunc(timeFlagName, completion.AutocompleteNone)
flags.SetNormalizeFunc(aliasTimeoutFlag)
flags.StringVarP(&srvArgs.CorsHeaders, "cors", "", "", "Set CORS Headers")
_ = srvCmd.RegisterFlagCompletionFunc("cors", completion.AutocompleteNone)
flags.StringVarP(&srvArgs.PProfAddr, "pprof-address", "", "",
"Binding network address for pprof profile endpoints, default: do not expose endpoints")
_ = flags.MarkHidden("pprof-address")
}
func aliasTimeoutFlag(_ *pflag.FlagSet, name string) pflag.NormalizedName {
if name == "timeout" {
name = "time"
}
return pflag.NormalizedName(name)
}
func service(cmd *cobra.Command, args []string) error {
apiURI, err := resolveAPIURI(args)
if err != nil {
return err
}
// Clean up any old existing unix domain socket
if len(apiURI) > 0 {
uri, err := url.Parse(apiURI)
if err != nil {
return err
}
// socket activation uses a unix:// socket in the shipped unit files but apiURI is coded as "" at this layer.
if uri.Scheme == "unix" && !registry.IsRemote() {
if err := syscall.Unlink(uri.Path); err != nil && !os.IsNotExist(err) {
return err
}
mask := syscall.Umask(0177)
defer syscall.Umask(mask)
}
}
return restService(cmd.Flags(), registry.PodmanConfig(), entities.ServiceOptions{
CorsHeaders: srvArgs.CorsHeaders,
PProfAddr: srvArgs.PProfAddr,
Timeout: time.Duration(srvArgs.Timeout) * time.Second,
URI: apiURI,
})
}
func resolveAPIURI(uri []string) (string, error) {
// When determining _*THE*_ listening endpoint --
// 1) User input wins always
// 2) systemd socket activation
// 3) rootless honors XDG_RUNTIME_DIR
// 4) lastly adapter.DefaultAPIAddress
if len(uri) == 0 {
if v, found := os.LookupEnv("PODMAN_SOCKET"); found {
logrus.Debugf("PODMAN_SOCKET=%q used to determine API endpoint", v)
uri = []string{v}
}
}
switch {
case len(uri) > 0 && uri[0] != "":
return uri[0], nil
case systemd.SocketActivated():
logrus.Info("Using systemd socket activation to determine API endpoint")
return "", nil
case rootless.IsRootless():
xdg, err := util.GetRuntimeDir()
if err != nil {
return "", err
}
socketName := "podman.sock"
socketPath := filepath.Join(xdg, "podman", socketName)
if err := os.MkdirAll(filepath.Dir(socketPath), 0700); err != nil {
return "", err
}
return "unix:" + socketPath, nil
default:
if err := os.MkdirAll(filepath.Dir(registry.DefaultRootAPIPath), 0700); err != nil {
return "", err
}
return registry.DefaultRootAPIAddress, nil
}
}