api: remove code for container stats on api < v1.21
API v1.23 and older are deprecated, so we can remove the code to adjust responses for API v1.20 and lower. Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
parent
ed93110e11
commit
d1974aa492
6 changed files with 9 additions and 147 deletions
|
@ -111,14 +111,11 @@ func (s *containerRouter) getContainersStats(ctx context.Context, w http.Respons
|
||||||
oneShot = httputils.BoolValueOrDefault(r, "one-shot", false)
|
oneShot = httputils.BoolValueOrDefault(r, "one-shot", false)
|
||||||
}
|
}
|
||||||
|
|
||||||
config := &backend.ContainerStatsConfig{
|
return s.backend.ContainerStats(ctx, vars["name"], &backend.ContainerStatsConfig{
|
||||||
Stream: stream,
|
Stream: stream,
|
||||||
OneShot: oneShot,
|
OneShot: oneShot,
|
||||||
OutStream: w,
|
OutStream: w,
|
||||||
Version: httputils.VersionFromContext(ctx),
|
})
|
||||||
}
|
|
||||||
|
|
||||||
return s.backend.ContainerStats(ctx, vars["name"], config)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *containerRouter) getContainersLogs(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
func (s *containerRouter) getContainersLogs(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
||||||
|
|
|
@ -89,7 +89,6 @@ type ContainerStatsConfig struct {
|
||||||
Stream bool
|
Stream bool
|
||||||
OneShot bool
|
OneShot bool
|
||||||
OutStream io.Writer
|
OutStream io.Writer
|
||||||
Version string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ExecInspect holds information about a running process started
|
// ExecInspect holds information about a running process started
|
||||||
|
|
|
@ -1,14 +0,0 @@
|
||||||
# Legacy API type versions
|
|
||||||
|
|
||||||
This package includes types for legacy API versions. The stable version of the API types live in `api/types/*.go`.
|
|
||||||
|
|
||||||
Consider moving a type here when you need to keep backwards compatibility in the API. This legacy types are organized by the latest API version they appear in. For instance, types in the `v1p19` package are valid for API versions below or equal `1.19`. Types in the `v1p20` package are valid for the API version `1.20`, since the versions below that will use the legacy types in `v1p19`.
|
|
||||||
|
|
||||||
## Package name conventions
|
|
||||||
|
|
||||||
The package name convention is to use `v` as a prefix for the version number and `p`(patch) as a separator. We use this nomenclature due to a few restrictions in the Go package name convention:
|
|
||||||
|
|
||||||
1. We cannot use `.` because it's interpreted by the language, think of `v1.20.CallFunction`.
|
|
||||||
2. We cannot use `_` because golint complains about it. The code is actually valid, but it looks probably more weird: `v1_20.CallFunction`.
|
|
||||||
|
|
||||||
For instance, if you want to modify a type that was available in the version `1.21` of the API but it will have different fields in the version `1.22`, you want to create a new package under `api/types/versions/v1p21`.
|
|
|
@ -1,40 +0,0 @@
|
||||||
// Package v1p20 provides specific API types for the API version 1, patch 20.
|
|
||||||
package v1p20 // import "github.com/docker/docker/api/types/versions/v1p20"
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/docker/docker/api/types"
|
|
||||||
"github.com/docker/docker/api/types/container"
|
|
||||||
"github.com/docker/go-connections/nat"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ContainerJSON is a backcompatibility struct for the API 1.20
|
|
||||||
type ContainerJSON struct {
|
|
||||||
*types.ContainerJSONBase
|
|
||||||
Mounts []types.MountPoint
|
|
||||||
Config *ContainerConfig
|
|
||||||
NetworkSettings *NetworkSettings
|
|
||||||
}
|
|
||||||
|
|
||||||
// ContainerConfig is a backcompatibility struct used in ContainerJSON for the API 1.20
|
|
||||||
type ContainerConfig struct {
|
|
||||||
*container.Config
|
|
||||||
|
|
||||||
MacAddress string
|
|
||||||
NetworkDisabled bool
|
|
||||||
ExposedPorts map[nat.Port]struct{}
|
|
||||||
|
|
||||||
// backward compatibility, they now live in HostConfig
|
|
||||||
VolumeDriver string
|
|
||||||
}
|
|
||||||
|
|
||||||
// StatsJSON is a backcompatibility struct used in Stats for APIs prior to 1.21
|
|
||||||
type StatsJSON struct {
|
|
||||||
types.Stats
|
|
||||||
Network types.NetworkStats `json:"network,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// NetworkSettings is a backward compatible struct for APIs prior to 1.21
|
|
||||||
type NetworkSettings struct {
|
|
||||||
types.NetworkSettingsBase
|
|
||||||
types.DefaultNetworkSettings
|
|
||||||
}
|
|
|
@ -10,8 +10,6 @@ import (
|
||||||
"github.com/containerd/log"
|
"github.com/containerd/log"
|
||||||
"github.com/docker/docker/api/types"
|
"github.com/docker/docker/api/types"
|
||||||
"github.com/docker/docker/api/types/backend"
|
"github.com/docker/docker/api/types/backend"
|
||||||
"github.com/docker/docker/api/types/versions"
|
|
||||||
"github.com/docker/docker/api/types/versions/v1p20"
|
|
||||||
"github.com/docker/docker/container"
|
"github.com/docker/docker/container"
|
||||||
"github.com/docker/docker/errdefs"
|
"github.com/docker/docker/errdefs"
|
||||||
"github.com/docker/docker/pkg/ioutils"
|
"github.com/docker/docker/pkg/ioutils"
|
||||||
|
@ -20,13 +18,6 @@ import (
|
||||||
// ContainerStats writes information about the container to the stream
|
// ContainerStats writes information about the container to the stream
|
||||||
// given in the config object.
|
// given in the config object.
|
||||||
func (daemon *Daemon) ContainerStats(ctx context.Context, prefixOrName string, config *backend.ContainerStatsConfig) error {
|
func (daemon *Daemon) ContainerStats(ctx context.Context, prefixOrName string, config *backend.ContainerStatsConfig) error {
|
||||||
// Engine API version (used for backwards compatibility)
|
|
||||||
apiVersion := config.Version
|
|
||||||
|
|
||||||
if isWindows && versions.LessThan(apiVersion, "1.21") {
|
|
||||||
return errors.New("API versions pre v1.21 do not support stats on Windows")
|
|
||||||
}
|
|
||||||
|
|
||||||
ctr, err := daemon.GetContainer(prefixOrName)
|
ctr, err := daemon.GetContainer(prefixOrName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -87,46 +78,7 @@ func (daemon *Daemon) ContainerStats(ctx context.Context, prefixOrName string, c
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var statsJSON interface{}
|
statsJSON := getStatJSON(v)
|
||||||
statsJSONPost120 := getStatJSON(v)
|
|
||||||
if versions.LessThan(apiVersion, "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 {
|
if !config.Stream && noStreamFirstFrame {
|
||||||
// prime the cpu stats so they aren't 0 in the final output
|
// prime the cpu stats so they aren't 0 in the final output
|
||||||
noStreamFirstFrame = false
|
noStreamFirstFrame = false
|
||||||
|
|
|
@ -8,13 +8,11 @@ import (
|
||||||
"runtime"
|
"runtime"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/docker/docker/api/types"
|
"github.com/docker/docker/api/types"
|
||||||
"github.com/docker/docker/api/types/system"
|
"github.com/docker/docker/api/types/system"
|
||||||
"github.com/docker/docker/api/types/versions"
|
|
||||||
"github.com/docker/docker/client"
|
"github.com/docker/docker/client"
|
||||||
"github.com/docker/docker/integration-cli/cli"
|
"github.com/docker/docker/integration-cli/cli"
|
||||||
"github.com/docker/docker/testutil"
|
"github.com/docker/docker/testutil"
|
||||||
|
@ -166,27 +164,13 @@ func (s *DockerAPISuite) TestAPIStatsNetworkStats(c *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *DockerAPISuite) TestAPIStatsNetworkStatsVersioning(c *testing.T) {
|
func (s *DockerAPISuite) TestAPIStatsNetworkStatsVersioning(c *testing.T) {
|
||||||
// Windows doesn't support API versions less than 1.25, so no point testing 1.17 .. 1.21
|
|
||||||
testRequires(c, testEnv.IsLocalDaemon, DaemonIsLinux)
|
testRequires(c, testEnv.IsLocalDaemon, DaemonIsLinux)
|
||||||
|
|
||||||
id := runSleepingContainer(c)
|
id := runSleepingContainer(c)
|
||||||
cli.WaitRun(c, id)
|
cli.WaitRun(c, id)
|
||||||
wg := sync.WaitGroup{}
|
|
||||||
|
|
||||||
for i := 17; i <= 21; i++ {
|
statsJSONBlob := getStats(c, id)
|
||||||
wg.Add(1)
|
assert.Assert(c, jsonBlobHasGTE121NetworkStats(statsJSONBlob), "Stats JSON blob from API does not look like a >=v1.21 API stats structure", statsJSONBlob)
|
||||||
go func(i int) {
|
|
||||||
defer wg.Done()
|
|
||||||
apiVersion := fmt.Sprintf("v1.%d", i)
|
|
||||||
statsJSONBlob := getVersionedStats(c, id, apiVersion)
|
|
||||||
if versions.LessThan(apiVersion, "v1.21") {
|
|
||||||
assert.Assert(c, jsonBlobHasLTv121NetworkStats(statsJSONBlob), "Stats JSON blob from API %s %#v does not look like a <v1.21 API stats structure", apiVersion, statsJSONBlob)
|
|
||||||
} else {
|
|
||||||
assert.Assert(c, jsonBlobHasGTE121NetworkStats(statsJSONBlob), "Stats JSON blob from API %s %#v does not look like a >=v1.21 API stats structure", apiVersion, statsJSONBlob)
|
|
||||||
}
|
|
||||||
}(i)
|
|
||||||
}
|
|
||||||
wg.Wait()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func getNetworkStats(c *testing.T, id string) map[string]types.NetworkStats {
|
func getNetworkStats(c *testing.T, id string) map[string]types.NetworkStats {
|
||||||
|
@ -202,14 +186,15 @@ func getNetworkStats(c *testing.T, id string) map[string]types.NetworkStats {
|
||||||
return st.Networks
|
return st.Networks
|
||||||
}
|
}
|
||||||
|
|
||||||
// getVersionedStats returns stats result for the
|
// getStats returns stats result for the
|
||||||
// container with id using an API call with version apiVersion. Since the
|
// container with id using an API call with version apiVersion. Since the
|
||||||
// stats result type differs between API versions, we simply return
|
// stats result type differs between API versions, we simply return
|
||||||
// map[string]interface{}.
|
// map[string]interface{}.
|
||||||
func getVersionedStats(c *testing.T, id string, apiVersion string) map[string]interface{} {
|
func getStats(c *testing.T, id string) map[string]interface{} {
|
||||||
|
c.Helper()
|
||||||
stats := make(map[string]interface{})
|
stats := make(map[string]interface{})
|
||||||
|
|
||||||
_, body, err := request.Get(testutil.GetContext(c), "/"+apiVersion+"/containers/"+id+"/stats?stream=false")
|
_, body, err := request.Get(testutil.GetContext(c), "/containers/"+id+"/stats?stream=false")
|
||||||
assert.NilError(c, err)
|
assert.NilError(c, err)
|
||||||
defer body.Close()
|
defer body.Close()
|
||||||
|
|
||||||
|
@ -219,23 +204,6 @@ func getVersionedStats(c *testing.T, id string, apiVersion string) map[string]in
|
||||||
return stats
|
return stats
|
||||||
}
|
}
|
||||||
|
|
||||||
func jsonBlobHasLTv121NetworkStats(blob map[string]interface{}) bool {
|
|
||||||
networkStatsIntfc, ok := blob["network"]
|
|
||||||
if !ok {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
networkStats, ok := networkStatsIntfc.(map[string]interface{})
|
|
||||||
if !ok {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
for _, expectedKey := range expectedNetworkInterfaceStats {
|
|
||||||
if _, ok := networkStats[expectedKey]; !ok {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
func jsonBlobHasGTE121NetworkStats(blob map[string]interface{}) bool {
|
func jsonBlobHasGTE121NetworkStats(blob map[string]interface{}) bool {
|
||||||
networksStatsIntfc, ok := blob["networks"]
|
networksStatsIntfc, ok := blob["networks"]
|
||||||
if !ok {
|
if !ok {
|
||||||
|
|
Loading…
Reference in a new issue