From dd86128e0dff1c4261d23b76e0ad0bcdabd10dc6 Mon Sep 17 00:00:00 2001 From: Kazuyoshi Kato Date: Fri, 11 Nov 2022 18:10:01 +0000 Subject: [PATCH] Convert hcsshim's stats to cgroups' stats Since hcsshim still uses containerd/cgroups 1.x which uses gogo/protobuf. Signed-off-by: Kazuyoshi Kato --- cmd/ctr/commands/tasks/metrics.go | 46 +++++++++++++++++++++++-------- 1 file changed, 35 insertions(+), 11 deletions(-) diff --git a/cmd/ctr/commands/tasks/metrics.go b/cmd/ctr/commands/tasks/metrics.go index b2c18f296..3fd9c4639 100644 --- a/cmd/ctr/commands/tasks/metrics.go +++ b/cmd/ctr/commands/tasks/metrics.go @@ -24,15 +24,16 @@ import ( "text/tabwriter" wstats "github.com/Microsoft/hcsshim/cmd/containerd-shim-runhcs-v1/stats" - v1 "github.com/containerd/cgroups/stats/v1" - v2 "github.com/containerd/cgroups/v2/stats" + v1 "github.com/containerd/cgroups/v3/cgroup1/stats" + v2 "github.com/containerd/cgroups/v3/cgroup2/stats" "github.com/containerd/containerd/cmd/ctr/commands" + "github.com/containerd/containerd/protobuf/proto" "github.com/containerd/typeurl" "github.com/urfave/cli" ) func init() { - // metricsCommand is only added on Linux as github.com/containerd/cgroups + // metricsCommand is only added on Linux as github.com/containerd/cgroups/v3 // does not compile on darwin or windows Command.Subcommands = append(Command.Subcommands, metricsCommand) } @@ -103,14 +104,9 @@ var metricsCommand = cli.Command{ } else if data2 != nil { printCgroup2MetricsTable(w, data2) } else { - if windowsStats.GetLinux() != nil { - printCgroupMetricsTable(w, windowsStats.GetLinux()) - } else if windowsStats.GetWindows() != nil { - printWindowsContainerStatistics(w, windowsStats.GetWindows()) - } - // Print VM stats if its isolated - if windowsStats.VM != nil { - printWindowsVMStatistics(w, windowsStats.VM) + err := printWindowsStats(w, windowsStats) + if err != nil { + return fmt.Errorf("cannot convert metrics data from windows.Statistics: %w", err) } } return w.Flush() @@ -166,6 +162,34 @@ func printCgroup2MetricsTable(w *tabwriter.Writer, data *v2.Metrics) { } } +func printWindowsStats(w *tabwriter.Writer, windowsStats *wstats.Statistics) error { + if windowsStats.GetLinux() != nil { + var stats v1.Metrics + + // It cannot be casted to v1.Metrics since windowsStats is still generated by gogo/protobuf. + linux := windowsStats.GetLinux() + + // But Marshal/Unmarshal works because the underlying protobuf message is compatible. + data, err := linux.Marshal() + if err != nil { + return err + } + err = proto.Unmarshal(data, &stats) + if err != nil { + return err + } + + printCgroupMetricsTable(w, &stats) + } else if windowsStats.GetWindows() != nil { + printWindowsContainerStatistics(w, windowsStats.GetWindows()) + } + // Print VM stats if its isolated + if windowsStats.VM != nil { + printWindowsVMStatistics(w, windowsStats.VM) + } + return nil +} + func printWindowsContainerStatistics(w *tabwriter.Writer, stats *wstats.WindowsContainerStatistics) { fmt.Fprintf(w, "METRIC\tVALUE\t\n") fmt.Fprintf(w, "timestamp\t%s\t\n", stats.Timestamp)