diff options
-rw-r--r-- | cmd/podman/containers/stats.go | 10 | ||||
-rw-r--r-- | docs/source/markdown/podman-stats.1.md | 4 | ||||
-rw-r--r-- | pkg/api/handlers/libpod/containers_stats.go | 10 | ||||
-rw-r--r-- | pkg/api/server/register_containers.go | 5 | ||||
-rw-r--r-- | pkg/bindings/containers/types.go | 3 | ||||
-rw-r--r-- | pkg/bindings/containers/types_stats_options.go | 16 | ||||
-rw-r--r-- | pkg/domain/entities/containers.go | 2 | ||||
-rw-r--r-- | pkg/domain/infra/abi/containers.go | 5 | ||||
-rw-r--r-- | pkg/domain/infra/tunnel/containers.go | 2 |
9 files changed, 47 insertions, 10 deletions
diff --git a/cmd/podman/containers/stats.go b/cmd/podman/containers/stats.go index 208d5d58f..69fef7b79 100644 --- a/cmd/podman/containers/stats.go +++ b/cmd/podman/containers/stats.go @@ -5,6 +5,7 @@ import ( "os" tm "github.com/buger/goterm" + "github.com/containers/common/pkg/completion" "github.com/containers/common/pkg/report" "github.com/containers/podman/v3/cmd/podman/common" "github.com/containers/podman/v3/cmd/podman/registry" @@ -55,6 +56,7 @@ type statsOptionsCLI struct { Latest bool NoReset bool NoStream bool + Interval int } var ( @@ -72,6 +74,9 @@ func statFlags(cmd *cobra.Command) { flags.BoolVar(&statsOptions.NoReset, "no-reset", false, "Disable resetting the screen between intervals") flags.BoolVar(&statsOptions.NoStream, "no-stream", false, "Disable streaming stats and only pull the first result, default setting is false") + intervalFlagName := "interval" + flags.IntVarP(&statsOptions.Interval, intervalFlagName, "i", 5, "Time in seconds between stats reports") + _ = cmd.RegisterFlagCompletionFunc(intervalFlagName, completion.AutocompleteNone) } func init() { @@ -122,8 +127,9 @@ func stats(cmd *cobra.Command, args []string) error { // Convert to the entities options. We should not leak CLI-only // options into the backend and separate concerns. opts := entities.ContainerStatsOptions{ - Latest: statsOptions.Latest, - Stream: !statsOptions.NoStream, + Latest: statsOptions.Latest, + Stream: !statsOptions.NoStream, + Interval: statsOptions.Interval, } statsChan, err := registry.ContainerEngine().ContainerStats(registry.Context(), args, opts) if err != nil { diff --git a/docs/source/markdown/podman-stats.1.md b/docs/source/markdown/podman-stats.1.md index 300106796..abd8fd530 100644 --- a/docs/source/markdown/podman-stats.1.md +++ b/docs/source/markdown/podman-stats.1.md @@ -37,6 +37,10 @@ Do not clear the terminal/screen in between reporting intervals Disable streaming stats and only pull the first result, default setting is false +#### **--interval**=*seconds*, **-i**=*seconds* + +Time in seconds between stats reports, defaults to 5 seconds. + #### **--format**=*template* Pretty-print container statistics to JSON or using a Go template diff --git a/pkg/api/handlers/libpod/containers_stats.go b/pkg/api/handlers/libpod/containers_stats.go index 75c404d4f..1807823fa 100644 --- a/pkg/api/handlers/libpod/containers_stats.go +++ b/pkg/api/handlers/libpod/containers_stats.go @@ -3,7 +3,6 @@ package libpod import ( "encoding/json" "net/http" - "time" "github.com/containers/podman/v3/libpod" "github.com/containers/podman/v3/pkg/api/handlers/utils" @@ -14,8 +13,6 @@ import ( "github.com/sirupsen/logrus" ) -const DefaultStatsPeriod = 5 * time.Second - func StatsContainer(w http.ResponseWriter, r *http.Request) { runtime := r.Context().Value("runtime").(*libpod.Runtime) decoder := r.Context().Value("decoder").(*schema.Decoder) @@ -23,8 +20,10 @@ func StatsContainer(w http.ResponseWriter, r *http.Request) { query := struct { Containers []string `schema:"containers"` Stream bool `schema:"stream"` + Interval int `schema:"interval"` }{ - Stream: true, + Stream: true, + Interval: 5, } if err := decoder.Decode(&query, r.URL.Query()); err != nil { utils.Error(w, "Something went wrong.", http.StatusBadRequest, errors.Wrapf(err, "failed to parse parameters for %s", r.URL.String())) @@ -36,7 +35,8 @@ func StatsContainer(w http.ResponseWriter, r *http.Request) { containerEngine := abi.ContainerEngine{Libpod: runtime} statsOptions := entities.ContainerStatsOptions{ - Stream: query.Stream, + Stream: query.Stream, + Interval: query.Interval, } // Stats will stop if the connection is closed. diff --git a/pkg/api/server/register_containers.go b/pkg/api/server/register_containers.go index 50e059ecc..5a4137533 100644 --- a/pkg/api/server/register_containers.go +++ b/pkg/api/server/register_containers.go @@ -1106,6 +1106,11 @@ func (s *APIServer) registerContainersHandlers(r *mux.Router) error { // type: boolean // default: true // description: Stream the output + // - in: query + // name: interval + // type: integer + // default: 5 + // description: Time in seconds between stats reports // produces: // - application/json // responses: diff --git a/pkg/bindings/containers/types.go b/pkg/bindings/containers/types.go index 1058c7a48..28c644841 100644 --- a/pkg/bindings/containers/types.go +++ b/pkg/bindings/containers/types.go @@ -165,7 +165,8 @@ type StartOptions struct { //go:generate go run ../generator/generator.go StatsOptions // StatsOptions are optional options for getting stats on containers type StatsOptions struct { - Stream *bool + Stream *bool + Interval *int } //go:generate go run ../generator/generator.go TopOptions diff --git a/pkg/bindings/containers/types_stats_options.go b/pkg/bindings/containers/types_stats_options.go index 8f6a03301..604004eb6 100644 --- a/pkg/bindings/containers/types_stats_options.go +++ b/pkg/bindings/containers/types_stats_options.go @@ -35,3 +35,19 @@ func (o *StatsOptions) GetStream() bool { } return *o.Stream } + +// WithInterval +func (o *StatsOptions) WithInterval(value int) *StatsOptions { + v := &value + o.Interval = v + return o +} + +// GetInterval +func (o *StatsOptions) GetInterval() int { + var interval int + if o.Interval == nil { + return interval + } + return *o.Interval +} diff --git a/pkg/domain/entities/containers.go b/pkg/domain/entities/containers.go index 302b35a47..dcb351e82 100644 --- a/pkg/domain/entities/containers.go +++ b/pkg/domain/entities/containers.go @@ -435,6 +435,8 @@ type ContainerStatsOptions struct { Latest bool // Stream stats. Stream bool + // Interval in seconds + Interval int } // ContainerStatsReport is used for streaming container stats. diff --git a/pkg/domain/infra/abi/containers.go b/pkg/domain/infra/abi/containers.go index 50751aa12..6eeef870f 100644 --- a/pkg/domain/infra/abi/containers.go +++ b/pkg/domain/infra/abi/containers.go @@ -1281,6 +1281,9 @@ func (ic *ContainerEngine) Shutdown(_ context.Context) { } func (ic *ContainerEngine) ContainerStats(ctx context.Context, namesOrIds []string, options entities.ContainerStatsOptions) (statsChan chan entities.ContainerStatsReport, err error) { + if options.Interval < 1 { + return nil, errors.New("Invalid interval, must be a positive number greater zero") + } statsChan = make(chan entities.ContainerStatsReport, 1) containerFunc := ic.Libpod.GetRunningContainers @@ -1361,7 +1364,7 @@ func (ic *ContainerEngine) ContainerStats(ctx context.Context, namesOrIds []stri return } - time.Sleep(time.Second) + time.Sleep(time.Second * time.Duration(options.Interval)) goto stream }() diff --git a/pkg/domain/infra/tunnel/containers.go b/pkg/domain/infra/tunnel/containers.go index c17d7b54f..1df79c373 100644 --- a/pkg/domain/infra/tunnel/containers.go +++ b/pkg/domain/infra/tunnel/containers.go @@ -871,7 +871,7 @@ func (ic *ContainerEngine) ContainerStats(ctx context.Context, namesOrIds []stri if options.Latest { return nil, errors.New("latest is not supported for the remote client") } - return containers.Stats(ic.ClientCtx, namesOrIds, new(containers.StatsOptions).WithStream(options.Stream)) + return containers.Stats(ic.ClientCtx, namesOrIds, new(containers.StatsOptions).WithStream(options.Stream).WithInterval(options.Interval)) } // ShouldRestart reports back whether the container will restart |