diff options
author | OpenShift Merge Robot <openshift-merge-robot@users.noreply.github.com> | 2021-10-10 12:54:29 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-10-10 12:54:29 +0200 |
commit | 60c711f78956f4eda1f811757dc8b320e5e66d9f (patch) | |
tree | 851f1a5766e15066ba64b527bf26a85fb27f3554 /cmd/podman | |
parent | c47f714fe8193cd1ac90a9359da3ef177a6db7e1 (diff) | |
parent | 8d3aec9d08bddf486dcb30e7113777b9d0cc27bd (diff) | |
download | podman-60c711f78956f4eda1f811757dc8b320e5e66d9f.tar.gz podman-60c711f78956f4eda1f811757dc8b320e5e66d9f.tar.bz2 podman-60c711f78956f4eda1f811757dc8b320e5e66d9f.zip |
Merge pull request #11869 from jwhonce/wip/pprof
Enable /debug/pprof API service endpoints
Diffstat (limited to 'cmd/podman')
-rw-r--r-- | cmd/podman/system/service.go | 43 | ||||
-rw-r--r-- | cmd/podman/system/service_abi.go | 61 |
2 files changed, 61 insertions, 43 deletions
diff --git a/cmd/podman/system/service.go b/cmd/podman/system/service.go index 99a6b1e1e..41d20d9fd 100644 --- a/cmd/podman/system/service.go +++ b/cmd/podman/system/service.go @@ -35,12 +35,14 @@ Enable a listening service for API access to Podman commands. Long: srvDescription, RunE: service, ValidArgsFunction: common.AutocompleteDefaultOneArg, - Example: `podman system service --time=0 unix:///tmp/podman.sock`, + Example: `podman system service --time=0 unix:///tmp/podman.sock + podman system service --time=0 tcp://localhost:8888`, } srvArgs = struct { - Timeout int64 CorsHeaders string + PProfAddr string + Timeout uint }{} ) @@ -51,15 +53,20 @@ func init() { }) flags := srvCmd.Flags() - cfg := registry.PodmanConfig() + timeFlagName := "time" - flags.Int64VarP(&srvArgs.Timeout, timeFlagName, "t", int64(cfg.Engine.ServiceTimeout), "Time until the service session expires in seconds. Use 0 to disable the timeout") + flags.UintVarP(&srvArgs.Timeout, timeFlagName, "t", cfg.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.SetNormalizeFunc(aliasTimeoutFlag) + 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 { @@ -74,7 +81,7 @@ func service(cmd *cobra.Command, args []string) error { if err != nil { return err } - logrus.Infof("Using API endpoint: '%s'", apiURI) + // Clean up any old existing unix domain socket if len(apiURI) > 0 { uri, err := url.Parse(apiURI) @@ -92,33 +99,31 @@ func service(cmd *cobra.Command, args []string) error { } } - opts := entities.ServiceOptions{ - URI: apiURI, - Command: cmd, + return restService(cmd.Flags(), registry.PodmanConfig(), entities.ServiceOptions{ CorsHeaders: srvArgs.CorsHeaders, - } - - opts.Timeout = time.Duration(srvArgs.Timeout) * time.Second - return restService(opts, cmd.Flags(), registry.PodmanConfig()) + PProfAddr: srvArgs.PProfAddr, + Timeout: time.Duration(srvArgs.Timeout) * time.Second, + URI: apiURI, + }) } -func resolveAPIURI(_url []string) (string, error) { +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(_url) == 0 { + if len(uri) == 0 { if v, found := os.LookupEnv("PODMAN_SOCKET"); found { - logrus.Debugf("PODMAN_SOCKET='%s' used to determine API endpoint", v) - _url = []string{v} + logrus.Debugf("PODMAN_SOCKET=%q used to determine API endpoint", v) + uri = []string{v} } } switch { - case len(_url) > 0 && _url[0] != "": - return _url[0], nil + 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 diff --git a/cmd/podman/system/service_abi.go b/cmd/podman/system/service_abi.go index e484db339..0a4be6aea 100644 --- a/cmd/podman/system/service_abi.go +++ b/cmd/podman/system/service_abi.go @@ -5,9 +5,9 @@ package system import ( "context" "net" + "net/url" "os" "path/filepath" - "strings" api "github.com/containers/podman/v3/pkg/api/server" "github.com/containers/podman/v3/pkg/domain/entities" @@ -20,41 +20,54 @@ import ( "golang.org/x/sys/unix" ) -func restService(opts entities.ServiceOptions, flags *pflag.FlagSet, cfg *entities.PodmanConfig) error { +func restService(flags *pflag.FlagSet, cfg *entities.PodmanConfig, opts entities.ServiceOptions) error { var ( listener *net.Listener err error ) if opts.URI != "" { - fields := strings.Split(opts.URI, ":") - if len(fields) == 1 { + uri, err := url.Parse(opts.URI) + if err != nil { return errors.Errorf("%s is an invalid socket destination", opts.URI) } - path := opts.URI - if fields[0] == "unix" { - if path, err = filepath.Abs(fields[1]); err != nil { - return err - } - } - util.SetSocketPath(path) - if os.Getenv("LISTEN_FDS") != "" { - // If it is activated by systemd, use the first LISTEN_FD (3) - // instead of opening the socket file. - f := os.NewFile(uintptr(3), "podman.sock") - l, err := net.FileListener(f) + + switch uri.Scheme { + case "unix": + path, err := filepath.Abs(uri.Path) if err != nil { return err } - listener = &l - } else { - network := fields[0] - address := strings.Join(fields[1:], ":") - l, err := net.Listen(network, address) + util.SetSocketPath(path) + if os.Getenv("LISTEN_FDS") != "" { + // If it is activated by systemd, use the first LISTEN_FD (3) + // instead of opening the socket file. + f := os.NewFile(uintptr(3), "podman.sock") + l, err := net.FileListener(f) + if err != nil { + return err + } + listener = &l + } else { + l, err := net.Listen(uri.Scheme, path) + if err != nil { + return errors.Wrapf(err, "unable to create socket") + } + listener = &l + } + case "tcp": + host := uri.Host + if host == "" { + // For backward compatibility, support "tcp:<host>:<port>" and "tcp://<host>:<port>" + host = uri.Opaque + } + l, err := net.Listen(uri.Scheme, host) if err != nil { - return errors.Wrapf(err, "unable to create socket") + return errors.Wrapf(err, "unable to create socket %v", host) } listener = &l + default: + logrus.Debugf("Attempting API Service endpoint scheme %q", uri.Scheme) } } @@ -75,12 +88,12 @@ func restService(opts entities.ServiceOptions, flags *pflag.FlagSet, cfg *entiti servicereaper.Start() infra.StartWatcher(rt) - server, err := api.NewServerWithSettings(rt, listener, api.Options{Timeout: opts.Timeout, CorsHeaders: opts.CorsHeaders}) + server, err := api.NewServerWithSettings(rt, listener, opts) if err != nil { return err } defer func() { - if err := server.Shutdown(); err != nil { + if err := server.Shutdown(false); err != nil { logrus.Warnf("Error when stopping API service: %s", err) } }() |