mirror of
https://github.com/moby/moby.git
synced 2026-01-11 18:51:37 +00:00
This is done by moving the following types to api/types/config.go:
- ContainersConfig
- ContainerAttachWithLogsConfig
- ContainerWsAttachWithLogsConfig
- ContainerLogsConfig
- ContainerStatsConfig
Remove dependency on "version" package from types.ContainerStatsConfig.
Decouple the "container" router from the "daemon/exec" implementation.
* This is done by making daemon.ContainerExecInspect() return an interface{}
value. The same trick is already used by daemon.ContainerInspect().
Improve documentation for router packages.
Extract localRoute and router into separate files.
Move local.router to image.imageRouter.
Changes:
- Move local/image.go to image/image_routes.go.
- Move local/local.go to image/image.go
- Rename router to imageRouter.
- Simplify imports for image/image.go (remove alias for router package).
Merge router/local package into router package.
Decouple the "image" router from the actual daemon implementation.
Add Daemon.GetNetworkByID and Daemon.GetNetworkByName.
Decouple the "network" router from the actual daemon implementation.
This is done by replacing the daemon.NetworkByName constant with
an explicit GetNetworkByName method.
Remove the unused Daemon.GetNetwork method and the associated constants NetworkByID and NetworkByName.
Signed-off-by: Lukas Waslowski <cr7pt0gr4ph7@gmail.com>
Signed-off-by: David Calavera <david.calavera@gmail.com>
124 lines
3.0 KiB
Go
124 lines
3.0 KiB
Go
package daemon
|
|
|
|
import (
|
|
"encoding/json"
|
|
"errors"
|
|
"runtime"
|
|
|
|
"github.com/docker/docker/daemon/execdriver"
|
|
"github.com/docker/docker/pkg/version"
|
|
"github.com/docker/engine-api/types"
|
|
"github.com/docker/engine-api/types/backend"
|
|
"github.com/docker/engine-api/types/versions/v1p20"
|
|
)
|
|
|
|
// ContainerStats writes information about the container to the stream
|
|
// given in the config object.
|
|
func (daemon *Daemon) ContainerStats(prefixOrName string, config *backend.ContainerStatsConfig) error {
|
|
if runtime.GOOS == "windows" {
|
|
return errors.New("Windows does not support stats")
|
|
}
|
|
// Remote API version (used for backwards compatibility)
|
|
apiVersion := version.Version(config.Version)
|
|
|
|
container, err := daemon.GetContainer(prefixOrName)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// If the container is not running and requires no stream, return an empty stats.
|
|
if !container.IsRunning() && !config.Stream {
|
|
return json.NewEncoder(config.OutStream).Encode(&types.Stats{})
|
|
}
|
|
|
|
if config.Stream {
|
|
// Write an empty chunk of data.
|
|
// This is to ensure that the HTTP status code is sent immediately,
|
|
// even if the container has not yet produced any data.
|
|
config.OutStream.Write(nil)
|
|
}
|
|
|
|
var preCPUStats types.CPUStats
|
|
getStatJSON := func(v interface{}) *types.StatsJSON {
|
|
update := v.(*execdriver.ResourceStats)
|
|
ss := convertStatsToAPITypes(update.Stats)
|
|
ss.PreCPUStats = preCPUStats
|
|
ss.MemoryStats.Limit = uint64(update.MemoryLimit)
|
|
ss.Read = update.Read
|
|
ss.CPUStats.SystemUsage = update.SystemUsage
|
|
preCPUStats = ss.CPUStats
|
|
return ss
|
|
}
|
|
|
|
enc := json.NewEncoder(config.OutStream)
|
|
|
|
updates := daemon.subscribeToContainerStats(container)
|
|
defer daemon.unsubscribeToContainerStats(container, updates)
|
|
|
|
noStreamFirstFrame := true
|
|
for {
|
|
select {
|
|
case v, ok := <-updates:
|
|
if !ok {
|
|
return nil
|
|
}
|
|
|
|
var statsJSON interface{}
|
|
statsJSONPost120 := getStatJSON(v)
|
|
if apiVersion.LessThan("1.21") {
|
|
var (
|
|
rxBytes uint64
|
|
rxPackets uint64
|
|
rxErrors uint64
|
|
rxDropped uint64
|
|
txBytes uint64
|
|
txPackets uint64
|
|
txErrors uint64
|
|
txDropped uint64
|
|
)
|
|
for _, v := range statsJSONPost120.Networks {
|
|
rxBytes += v.RxBytes
|
|
rxPackets += v.RxPackets
|
|
rxErrors += v.RxErrors
|
|
rxDropped += v.RxDropped
|
|
txBytes += v.TxBytes
|
|
txPackets += v.TxPackets
|
|
txErrors += v.TxErrors
|
|
txDropped += v.TxDropped
|
|
}
|
|
statsJSON = &v1p20.StatsJSON{
|
|
Stats: statsJSONPost120.Stats,
|
|
Network: types.NetworkStats{
|
|
RxBytes: rxBytes,
|
|
RxPackets: rxPackets,
|
|
RxErrors: rxErrors,
|
|
RxDropped: rxDropped,
|
|
TxBytes: txBytes,
|
|
TxPackets: txPackets,
|
|
TxErrors: txErrors,
|
|
TxDropped: txDropped,
|
|
},
|
|
}
|
|
} else {
|
|
statsJSON = statsJSONPost120
|
|
}
|
|
|
|
if !config.Stream && noStreamFirstFrame {
|
|
// prime the cpu stats so they aren't 0 in the final output
|
|
noStreamFirstFrame = false
|
|
continue
|
|
}
|
|
|
|
if err := enc.Encode(statsJSON); err != nil {
|
|
return err
|
|
}
|
|
|
|
if !config.Stream {
|
|
return nil
|
|
}
|
|
case <-config.Stop:
|
|
return nil
|
|
}
|
|
}
|
|
}
|