Merge pull request #8473 from brandond/fix-cri-stats_main

cri: Fix umarshal metrics
This commit is contained in:
Samuel Karp 2023-05-04 00:32:24 -07:00 committed by GitHub
commit f5b10fdea2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 44 additions and 16 deletions

View File

@ -17,12 +17,15 @@
package sbserver package sbserver
import ( import (
"errors"
"fmt" "fmt"
"reflect"
"time" "time"
wstats "github.com/Microsoft/hcsshim/cmd/containerd-shim-runhcs-v1/stats"
v1 "github.com/containerd/cgroups/v3/cgroup1/stats"
v2 "github.com/containerd/cgroups/v3/cgroup2/stats"
"github.com/containerd/containerd/api/types" "github.com/containerd/containerd/api/types"
v1 "github.com/containerd/containerd/metrics/types/v1"
v2 "github.com/containerd/containerd/metrics/types/v2"
"github.com/containerd/containerd/protobuf" "github.com/containerd/containerd/protobuf"
"github.com/containerd/typeurl/v2" "github.com/containerd/typeurl/v2"
runtime "k8s.io/cri-api/pkg/apis/runtime/v1" runtime "k8s.io/cri-api/pkg/apis/runtime/v1"
@ -59,18 +62,29 @@ func (c *criService) containerMetrics(
} }
if stats != nil { if stats != nil {
s, err := typeurl.UnmarshalAny(stats.Data) var data interface{}
if err != nil { switch {
case typeurl.Is(stats.Data, (*v1.Metrics)(nil)):
data = &v1.Metrics{}
case typeurl.Is(stats.Data, (*v2.Metrics)(nil)):
data = &v2.Metrics{}
case typeurl.Is(stats.Data, (*wstats.Statistics)(nil)):
data = &wstats.Statistics{}
default:
return nil, errors.New("cannot convert metric data to cgroups.Metrics or windows.Statistics")
}
if err := typeurl.UnmarshalTo(stats.Data, data); err != nil {
return nil, fmt.Errorf("failed to extract container metrics: %w", err) return nil, fmt.Errorf("failed to extract container metrics: %w", err)
} }
cpuStats, err := c.cpuContainerStats(meta.ID, false /* isSandbox */, s, protobuf.FromTimestamp(stats.Timestamp)) cpuStats, err := c.cpuContainerStats(meta.ID, false /* isSandbox */, data, protobuf.FromTimestamp(stats.Timestamp))
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to obtain cpu stats: %w", err) return nil, fmt.Errorf("failed to obtain cpu stats: %w", err)
} }
cs.Cpu = cpuStats cs.Cpu = cpuStats
memoryStats, err := c.memoryContainerStats(meta.ID, s, protobuf.FromTimestamp(stats.Timestamp)) memoryStats, err := c.memoryContainerStats(meta.ID, data, protobuf.FromTimestamp(stats.Timestamp))
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to obtain memory stats: %w", err) return nil, fmt.Errorf("failed to obtain memory stats: %w", err)
} }
@ -151,7 +165,7 @@ func (c *criService) cpuContainerStats(ID string, isSandbox bool, stats interfac
}, nil }, nil
} }
default: default:
return nil, fmt.Errorf("unexpected metrics type: %v", metrics) return nil, fmt.Errorf("unexpected metrics type: %T from %s", metrics, reflect.TypeOf(metrics).Elem().PkgPath())
} }
return nil, nil return nil, nil
} }
@ -193,7 +207,7 @@ func (c *criService) memoryContainerStats(ID string, stats interface{}, timestam
}, nil }, nil
} }
default: default:
return nil, fmt.Errorf("unexpected metrics type: %v", metrics) return nil, fmt.Errorf("unexpected metrics type: %T from %s", metrics, reflect.TypeOf(metrics).Elem().PkgPath())
} }
return nil, nil return nil, nil
} }

View File

@ -17,12 +17,15 @@
package server package server
import ( import (
"errors"
"fmt" "fmt"
"reflect"
"time" "time"
wstats "github.com/Microsoft/hcsshim/cmd/containerd-shim-runhcs-v1/stats"
v1 "github.com/containerd/cgroups/v3/cgroup1/stats"
v2 "github.com/containerd/cgroups/v3/cgroup2/stats"
"github.com/containerd/containerd/api/types" "github.com/containerd/containerd/api/types"
v1 "github.com/containerd/containerd/metrics/types/v1"
v2 "github.com/containerd/containerd/metrics/types/v2"
"github.com/containerd/containerd/protobuf" "github.com/containerd/containerd/protobuf"
"github.com/containerd/typeurl/v2" "github.com/containerd/typeurl/v2"
runtime "k8s.io/cri-api/pkg/apis/runtime/v1" runtime "k8s.io/cri-api/pkg/apis/runtime/v1"
@ -59,18 +62,29 @@ func (c *criService) containerMetrics(
} }
if stats != nil { if stats != nil {
s, err := typeurl.UnmarshalAny(stats.Data) var data interface{}
if err != nil { switch {
case typeurl.Is(stats.Data, (*v1.Metrics)(nil)):
data = &v1.Metrics{}
case typeurl.Is(stats.Data, (*v2.Metrics)(nil)):
data = &v2.Metrics{}
case typeurl.Is(stats.Data, (*wstats.Statistics)(nil)):
data = &wstats.Statistics{}
default:
return nil, errors.New("cannot convert metric data to cgroups.Metrics or windows.Statistics")
}
if err := typeurl.UnmarshalTo(stats.Data, data); err != nil {
return nil, fmt.Errorf("failed to extract container metrics: %w", err) return nil, fmt.Errorf("failed to extract container metrics: %w", err)
} }
cpuStats, err := c.cpuContainerStats(meta.ID, false /* isSandbox */, s, protobuf.FromTimestamp(stats.Timestamp)) cpuStats, err := c.cpuContainerStats(meta.ID, false /* isSandbox */, data, protobuf.FromTimestamp(stats.Timestamp))
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to obtain cpu stats: %w", err) return nil, fmt.Errorf("failed to obtain cpu stats: %w", err)
} }
cs.Cpu = cpuStats cs.Cpu = cpuStats
memoryStats, err := c.memoryContainerStats(meta.ID, s, protobuf.FromTimestamp(stats.Timestamp)) memoryStats, err := c.memoryContainerStats(meta.ID, data, protobuf.FromTimestamp(stats.Timestamp))
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to obtain memory stats: %w", err) return nil, fmt.Errorf("failed to obtain memory stats: %w", err)
} }
@ -152,7 +166,7 @@ func (c *criService) cpuContainerStats(ID string, isSandbox bool, stats interfac
}, nil }, nil
} }
default: default:
return nil, fmt.Errorf("unexpected metrics type: %v", metrics) return nil, fmt.Errorf("unexpected metrics type: %T from %s", metrics, reflect.TypeOf(metrics).Elem().PkgPath())
} }
return nil, nil return nil, nil
} }
@ -194,7 +208,7 @@ func (c *criService) memoryContainerStats(ID string, stats interface{}, timestam
}, nil }, nil
} }
default: default:
return nil, fmt.Errorf("unexpected metrics type: %v", metrics) return nil, fmt.Errorf("unexpected metrics type: %T from %s", metrics, reflect.TypeOf(metrics).Elem().PkgPath())
} }
return nil, nil return nil, nil
} }