From deef0ea2d7cf63b64fb16109f1a6b3eabbd6e06d Mon Sep 17 00:00:00 2001 From: Dawei Wei Date: Thu, 16 Jul 2026 17:45:25 -0700 Subject: [PATCH] daemon: fix empty docker stats for Windows containerd runtime When the daemon uses the containerd runtime (io.containerd.runhcs.v1), the runhcs shim emits container metrics as the typeurl `containerd.runhcs.stats.v1.Statistics`. moby never imported the package that registers this type, so `typeurl.UnmarshalAny` failed with "type not found" and `docker stats` reported all zeros for running Windows containers. Import the hcsshim runhcs stats package so its proto init registers the typeurl, and handle `*wstats.Statistics` in `InterfaceToStats`, converting the Windows container statistics (processor time is reported in nanoseconds and converted to the 100ns units used by hcsshim.Statistics) into the shape consumed by stats_windows.go. Also replace the bare type assertion with a type switch so unexpected payloads no longer panic. Un-skip TestStatsAllNoStream and TestStatsAllRunningNoStream, and add a unit test for the conversion. Signed-off-by: Dawei Wei --- .../libcontainerd/types/types_windows.go | 70 +- .../libcontainerd/types/types_windows_test.go | 107 +++ integration-cli/docker_cli_stats_test.go | 7 - .../containerd-shim-runhcs-v1/stats/doc.go | 6 + .../stats/stats.pb.go | 757 ++++++++++++++++++ .../stats/stats.proto | 69 ++ vendor/modules.txt | 1 + 7 files changed, 1007 insertions(+), 10 deletions(-) create mode 100644 daemon/internal/libcontainerd/types/types_windows_test.go create mode 100644 vendor/github.com/Microsoft/hcsshim/cmd/containerd-shim-runhcs-v1/stats/doc.go create mode 100644 vendor/github.com/Microsoft/hcsshim/cmd/containerd-shim-runhcs-v1/stats/stats.pb.go create mode 100644 vendor/github.com/Microsoft/hcsshim/cmd/containerd-shim-runhcs-v1/stats/stats.proto diff --git a/daemon/internal/libcontainerd/types/types_windows.go b/daemon/internal/libcontainerd/types/types_windows.go index f63f569990..387db8853d 100644 --- a/daemon/internal/libcontainerd/types/types_windows.go +++ b/daemon/internal/libcontainerd/types/types_windows.go @@ -5,6 +5,7 @@ import ( "github.com/Microsoft/hcsshim" "github.com/Microsoft/hcsshim/cmd/containerd-shim-runhcs-v1/options" + wstats "github.com/Microsoft/hcsshim/cmd/containerd-shim-runhcs-v1/stats" ) type Summary options.ProcessDetails @@ -16,13 +17,76 @@ type Stats struct { } // InterfaceToStats returns a stats object from the platform-specific interface. +// The builtin HCS runtime emits *hcsshim.Statistics; the runhcs shim (containerd +// runtime) emits *wstats.Statistics, which is converted to the same shape. func InterfaceToStats(read time.Time, v any) *Stats { - return &Stats{ - HCSStats: v.(*hcsshim.Statistics), - Read: read, + switch stats := v.(type) { + case *hcsshim.Statistics: + return &Stats{ + HCSStats: stats, + Read: read, + } + case *wstats.Statistics: + return &Stats{ + HCSStats: winStatsToHCSStats(stats), + Read: read, + } + default: + return &Stats{ + Read: read, + } } } +// hcsRuntimeUnit converts the shim's nanosecond runtime values to the 100ns +// units used by hcsshim.Statistics. +const hcsRuntimeUnit = 100 + +// winStatsToHCSStats converts runhcs shim stats to the *hcsshim.Statistics shape +// consumed by stats_windows.go, returning nil for a non-Windows-container payload. +func winStatsToHCSStats(stats *wstats.Statistics) *hcsshim.Statistics { + win := stats.GetWindows() + if win == nil { + return nil + } + + hcss := &hcsshim.Statistics{} + if ts := win.GetTimestamp(); ts != nil { + hcss.Timestamp = ts.AsTime() + } + if ts := win.GetContainerStartTime(); ts != nil { + hcss.ContainerStartTime = ts.AsTime() + } + hcss.Uptime100ns = win.GetUptimeNS() / hcsRuntimeUnit + + if proc := win.GetProcessor(); proc != nil { + hcss.Processor = hcsshim.ProcessorStats{ + TotalRuntime100ns: proc.GetTotalRuntimeNS() / hcsRuntimeUnit, + RuntimeUser100ns: proc.GetRuntimeUserNS() / hcsRuntimeUnit, + RuntimeKernel100ns: proc.GetRuntimeKernelNS() / hcsRuntimeUnit, + } + } + + if mem := win.GetMemory(); mem != nil { + hcss.Memory = hcsshim.MemoryStats{ + UsageCommitBytes: mem.GetMemoryUsageCommitBytes(), + UsageCommitPeakBytes: mem.GetMemoryUsageCommitPeakBytes(), + UsagePrivateWorkingSetBytes: mem.GetMemoryUsagePrivateWorkingSetBytes(), + } + } + + if storage := win.GetStorage(); storage != nil { + hcss.Storage = hcsshim.StorageStats{ + ReadCountNormalized: storage.GetReadCountNormalized(), + ReadSizeBytes: storage.GetReadSizeBytes(), + WriteCountNormalized: storage.GetWriteCountNormalized(), + WriteSizeBytes: storage.GetWriteSizeBytes(), + } + } + + return hcss +} + // Resources defines updatable container resource values. type Resources struct{} diff --git a/daemon/internal/libcontainerd/types/types_windows_test.go b/daemon/internal/libcontainerd/types/types_windows_test.go new file mode 100644 index 0000000000..02fa72f225 --- /dev/null +++ b/daemon/internal/libcontainerd/types/types_windows_test.go @@ -0,0 +1,107 @@ +package types + +import ( + "testing" + "time" + + "github.com/Microsoft/hcsshim" + wstats "github.com/Microsoft/hcsshim/cmd/containerd-shim-runhcs-v1/stats" + "google.golang.org/protobuf/types/known/timestamppb" +) + +func TestInterfaceToStatsHCS(t *testing.T) { + read := time.Now() + in := &hcsshim.Statistics{ + Processor: hcsshim.ProcessorStats{TotalRuntime100ns: 1234}, + } + + got := InterfaceToStats(read, in) + if got.HCSStats != in { + t.Fatalf("expected the original *hcsshim.Statistics to be passed through unchanged") + } + if !got.Read.Equal(read) { + t.Fatalf("Read = %v, want %v", got.Read, read) + } +} + +func TestInterfaceToStatsRunhcs(t *testing.T) { + read := time.Now() + start := time.Unix(1000, 0).UTC() + ts := time.Unix(2000, 0).UTC() + + in := &wstats.Statistics{ + Container: &wstats.Statistics_Windows{ + Windows: &wstats.WindowsContainerStatistics{ + Timestamp: timestamppb.New(ts), + ContainerStartTime: timestamppb.New(start), + UptimeNS: 500, + Processor: &wstats.WindowsContainerProcessorStatistics{ + TotalRuntimeNS: 100000, + RuntimeUserNS: 60000, + RuntimeKernelNS: 40000, + }, + Memory: &wstats.WindowsContainerMemoryStatistics{ + MemoryUsageCommitBytes: 111, + MemoryUsageCommitPeakBytes: 222, + MemoryUsagePrivateWorkingSetBytes: 333, + }, + Storage: &wstats.WindowsContainerStorageStatistics{ + ReadCountNormalized: 1, + ReadSizeBytes: 2, + WriteCountNormalized: 3, + WriteSizeBytes: 4, + }, + }, + }, + } + + got := InterfaceToStats(read, in) + if !got.Read.Equal(read) { + t.Fatalf("Read = %v, want %v", got.Read, read) + } + if got.HCSStats == nil { + t.Fatal("HCSStats is nil, want populated stats") + } + hcss := got.HCSStats + + if !hcss.Timestamp.Equal(ts) { + t.Errorf("Timestamp = %v, want %v", hcss.Timestamp, ts) + } + if !hcss.ContainerStartTime.Equal(start) { + t.Errorf("ContainerStartTime = %v, want %v", hcss.ContainerStartTime, start) + } + // Runtime fields are reported in nanoseconds and converted to 100ns units. + if hcss.Uptime100ns != 5 { + t.Errorf("Uptime100ns = %d, want 5", hcss.Uptime100ns) + } + if hcss.Processor.TotalRuntime100ns != 1000 { + t.Errorf("TotalRuntime100ns = %d, want 1000", hcss.Processor.TotalRuntime100ns) + } + if hcss.Processor.RuntimeUser100ns != 600 { + t.Errorf("RuntimeUser100ns = %d, want 600", hcss.Processor.RuntimeUser100ns) + } + if hcss.Processor.RuntimeKernel100ns != 400 { + t.Errorf("RuntimeKernel100ns = %d, want 400", hcss.Processor.RuntimeKernel100ns) + } + if hcss.Memory.UsageCommitBytes != 111 { + t.Errorf("UsageCommitBytes = %d, want 111", hcss.Memory.UsageCommitBytes) + } + if hcss.Memory.UsageCommitPeakBytes != 222 { + t.Errorf("UsageCommitPeakBytes = %d, want 222", hcss.Memory.UsageCommitPeakBytes) + } + if hcss.Memory.UsagePrivateWorkingSetBytes != 333 { + t.Errorf("UsagePrivateWorkingSetBytes = %d, want 333", hcss.Memory.UsagePrivateWorkingSetBytes) + } + if hcss.Storage.ReadCountNormalized != 1 || hcss.Storage.ReadSizeBytes != 2 || + hcss.Storage.WriteCountNormalized != 3 || hcss.Storage.WriteSizeBytes != 4 { + t.Errorf("Storage = %+v, want {1 2 3 4}", hcss.Storage) + } +} + +func TestInterfaceToStatsRunhcsNoWindows(t *testing.T) { + // A non-Windows-container payload yields nil HCSStats rather than panicking. + got := InterfaceToStats(time.Now(), &wstats.Statistics{}) + if got.HCSStats != nil { + t.Fatalf("HCSStats = %+v, want nil", got.HCSStats) + } +} diff --git a/integration-cli/docker_cli_stats_test.go b/integration-cli/docker_cli_stats_test.go index 066cb667da..2f09a93013 100644 --- a/integration-cli/docker_cli_stats_test.go +++ b/integration-cli/docker_cli_stats_test.go @@ -12,7 +12,6 @@ import ( "github.com/moby/moby/v2/integration-cli/cli" "gotest.tools/v3/assert" is "gotest.tools/v3/assert/cmp" - "gotest.tools/v3/skip" ) type DockerCLIStatsSuite struct { @@ -64,9 +63,6 @@ func (s *DockerCLIStatsSuite) TestStatsContainerNotFound(c *testing.T) { } func (s *DockerCLIStatsSuite) TestStatsAllRunningNoStream(c *testing.T) { - // FIXME(thaJeztah): stats doesn't work on Windows with containerd; see https://github.com/moby/moby/pull/52913#issuecomment-4741507027 - skip.If(c, RuntimeIsWindowsContainerd(), "FIXME: Broken on Windows + containerd combination") - id1 := runSleepingContainer(c)[:12] cli.WaitRun(c, id1) id2 := runSleepingContainer(c)[:12] @@ -97,9 +93,6 @@ func (s *DockerCLIStatsSuite) TestStatsAllRunningNoStream(c *testing.T) { } func (s *DockerCLIStatsSuite) TestStatsAllNoStream(c *testing.T) { - // FIXME(thaJeztah): stats doesn't work on Windows with containerd; see https://github.com/moby/moby/pull/52913#issuecomment-4741507027 - skip.If(c, RuntimeIsWindowsContainerd(), "FIXME: Broken on Windows + containerd combination") - id1 := runSleepingContainer(c)[:12] cli.WaitRun(c, id1) cli.DockerCmd(c, "stop", id1) diff --git a/vendor/github.com/Microsoft/hcsshim/cmd/containerd-shim-runhcs-v1/stats/doc.go b/vendor/github.com/Microsoft/hcsshim/cmd/containerd-shim-runhcs-v1/stats/doc.go new file mode 100644 index 0000000000..efe22b3672 --- /dev/null +++ b/vendor/github.com/Microsoft/hcsshim/cmd/containerd-shim-runhcs-v1/stats/doc.go @@ -0,0 +1,6 @@ +package stats + +import ( + // go mod will not vendor without an import for metrics.proto + _ "github.com/containerd/cgroups/v3/cgroup1/stats" +) diff --git a/vendor/github.com/Microsoft/hcsshim/cmd/containerd-shim-runhcs-v1/stats/stats.pb.go b/vendor/github.com/Microsoft/hcsshim/cmd/containerd-shim-runhcs-v1/stats/stats.pb.go new file mode 100644 index 0000000000..37c85abc81 --- /dev/null +++ b/vendor/github.com/Microsoft/hcsshim/cmd/containerd-shim-runhcs-v1/stats/stats.pb.go @@ -0,0 +1,757 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.36.10 +// protoc v5.26.0 +// source: github.com/Microsoft/hcsshim/cmd/containerd-shim-runhcs-v1/stats/stats.proto + +package stats + +import ( + stats "github.com/containerd/cgroups/v3/cgroup1/stats" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" + reflect "reflect" + sync "sync" + unsafe "unsafe" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type Statistics struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Types that are valid to be assigned to Container: + // + // *Statistics_Windows + // *Statistics_Linux + Container isStatistics_Container `protobuf_oneof:"container"` + VM *VirtualMachineStatistics `protobuf:"bytes,3,opt,name=vm,proto3" json:"vm,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Statistics) Reset() { + *x = Statistics{} + mi := &file_github_com_Microsoft_hcsshim_cmd_containerd_shim_runhcs_v1_stats_stats_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Statistics) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Statistics) ProtoMessage() {} + +func (x *Statistics) ProtoReflect() protoreflect.Message { + mi := &file_github_com_Microsoft_hcsshim_cmd_containerd_shim_runhcs_v1_stats_stats_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Statistics.ProtoReflect.Descriptor instead. +func (*Statistics) Descriptor() ([]byte, []int) { + return file_github_com_Microsoft_hcsshim_cmd_containerd_shim_runhcs_v1_stats_stats_proto_rawDescGZIP(), []int{0} +} + +func (x *Statistics) GetContainer() isStatistics_Container { + if x != nil { + return x.Container + } + return nil +} + +func (x *Statistics) GetWindows() *WindowsContainerStatistics { + if x != nil { + if x, ok := x.Container.(*Statistics_Windows); ok { + return x.Windows + } + } + return nil +} + +func (x *Statistics) GetLinux() *stats.Metrics { + if x != nil { + if x, ok := x.Container.(*Statistics_Linux); ok { + return x.Linux + } + } + return nil +} + +func (x *Statistics) GetVM() *VirtualMachineStatistics { + if x != nil { + return x.VM + } + return nil +} + +type isStatistics_Container interface { + isStatistics_Container() +} + +type Statistics_Windows struct { + Windows *WindowsContainerStatistics `protobuf:"bytes,1,opt,name=windows,proto3,oneof"` +} + +type Statistics_Linux struct { + Linux *stats.Metrics `protobuf:"bytes,2,opt,name=linux,proto3,oneof"` +} + +func (*Statistics_Windows) isStatistics_Container() {} + +func (*Statistics_Linux) isStatistics_Container() {} + +type WindowsContainerStatistics struct { + state protoimpl.MessageState `protogen:"open.v1"` + Timestamp *timestamppb.Timestamp `protobuf:"bytes,1,opt,name=timestamp,proto3" json:"timestamp,omitempty"` + ContainerStartTime *timestamppb.Timestamp `protobuf:"bytes,2,opt,name=container_start_time,json=containerStartTime,proto3" json:"container_start_time,omitempty"` + UptimeNS uint64 `protobuf:"varint,3,opt,name=uptime_ns,json=uptimeNs,proto3" json:"uptime_ns,omitempty"` + Processor *WindowsContainerProcessorStatistics `protobuf:"bytes,4,opt,name=processor,proto3" json:"processor,omitempty"` + Memory *WindowsContainerMemoryStatistics `protobuf:"bytes,5,opt,name=memory,proto3" json:"memory,omitempty"` + Storage *WindowsContainerStorageStatistics `protobuf:"bytes,6,opt,name=storage,proto3" json:"storage,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *WindowsContainerStatistics) Reset() { + *x = WindowsContainerStatistics{} + mi := &file_github_com_Microsoft_hcsshim_cmd_containerd_shim_runhcs_v1_stats_stats_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *WindowsContainerStatistics) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*WindowsContainerStatistics) ProtoMessage() {} + +func (x *WindowsContainerStatistics) ProtoReflect() protoreflect.Message { + mi := &file_github_com_Microsoft_hcsshim_cmd_containerd_shim_runhcs_v1_stats_stats_proto_msgTypes[1] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use WindowsContainerStatistics.ProtoReflect.Descriptor instead. +func (*WindowsContainerStatistics) Descriptor() ([]byte, []int) { + return file_github_com_Microsoft_hcsshim_cmd_containerd_shim_runhcs_v1_stats_stats_proto_rawDescGZIP(), []int{1} +} + +func (x *WindowsContainerStatistics) GetTimestamp() *timestamppb.Timestamp { + if x != nil { + return x.Timestamp + } + return nil +} + +func (x *WindowsContainerStatistics) GetContainerStartTime() *timestamppb.Timestamp { + if x != nil { + return x.ContainerStartTime + } + return nil +} + +func (x *WindowsContainerStatistics) GetUptimeNS() uint64 { + if x != nil { + return x.UptimeNS + } + return 0 +} + +func (x *WindowsContainerStatistics) GetProcessor() *WindowsContainerProcessorStatistics { + if x != nil { + return x.Processor + } + return nil +} + +func (x *WindowsContainerStatistics) GetMemory() *WindowsContainerMemoryStatistics { + if x != nil { + return x.Memory + } + return nil +} + +func (x *WindowsContainerStatistics) GetStorage() *WindowsContainerStorageStatistics { + if x != nil { + return x.Storage + } + return nil +} + +type WindowsContainerProcessorStatistics struct { + state protoimpl.MessageState `protogen:"open.v1"` + TotalRuntimeNS uint64 `protobuf:"varint,1,opt,name=total_runtime_ns,json=totalRuntimeNs,proto3" json:"total_runtime_ns,omitempty"` + RuntimeUserNS uint64 `protobuf:"varint,2,opt,name=runtime_user_ns,json=runtimeUserNs,proto3" json:"runtime_user_ns,omitempty"` + RuntimeKernelNS uint64 `protobuf:"varint,3,opt,name=runtime_kernel_ns,json=runtimeKernelNs,proto3" json:"runtime_kernel_ns,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *WindowsContainerProcessorStatistics) Reset() { + *x = WindowsContainerProcessorStatistics{} + mi := &file_github_com_Microsoft_hcsshim_cmd_containerd_shim_runhcs_v1_stats_stats_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *WindowsContainerProcessorStatistics) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*WindowsContainerProcessorStatistics) ProtoMessage() {} + +func (x *WindowsContainerProcessorStatistics) ProtoReflect() protoreflect.Message { + mi := &file_github_com_Microsoft_hcsshim_cmd_containerd_shim_runhcs_v1_stats_stats_proto_msgTypes[2] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use WindowsContainerProcessorStatistics.ProtoReflect.Descriptor instead. +func (*WindowsContainerProcessorStatistics) Descriptor() ([]byte, []int) { + return file_github_com_Microsoft_hcsshim_cmd_containerd_shim_runhcs_v1_stats_stats_proto_rawDescGZIP(), []int{2} +} + +func (x *WindowsContainerProcessorStatistics) GetTotalRuntimeNS() uint64 { + if x != nil { + return x.TotalRuntimeNS + } + return 0 +} + +func (x *WindowsContainerProcessorStatistics) GetRuntimeUserNS() uint64 { + if x != nil { + return x.RuntimeUserNS + } + return 0 +} + +func (x *WindowsContainerProcessorStatistics) GetRuntimeKernelNS() uint64 { + if x != nil { + return x.RuntimeKernelNS + } + return 0 +} + +type WindowsContainerMemoryStatistics struct { + state protoimpl.MessageState `protogen:"open.v1"` + MemoryUsageCommitBytes uint64 `protobuf:"varint,1,opt,name=memory_usage_commit_bytes,json=memoryUsageCommitBytes,proto3" json:"memory_usage_commit_bytes,omitempty"` + MemoryUsageCommitPeakBytes uint64 `protobuf:"varint,2,opt,name=memory_usage_commit_peak_bytes,json=memoryUsageCommitPeakBytes,proto3" json:"memory_usage_commit_peak_bytes,omitempty"` + MemoryUsagePrivateWorkingSetBytes uint64 `protobuf:"varint,3,opt,name=memory_usage_private_working_set_bytes,json=memoryUsagePrivateWorkingSetBytes,proto3" json:"memory_usage_private_working_set_bytes,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *WindowsContainerMemoryStatistics) Reset() { + *x = WindowsContainerMemoryStatistics{} + mi := &file_github_com_Microsoft_hcsshim_cmd_containerd_shim_runhcs_v1_stats_stats_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *WindowsContainerMemoryStatistics) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*WindowsContainerMemoryStatistics) ProtoMessage() {} + +func (x *WindowsContainerMemoryStatistics) ProtoReflect() protoreflect.Message { + mi := &file_github_com_Microsoft_hcsshim_cmd_containerd_shim_runhcs_v1_stats_stats_proto_msgTypes[3] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use WindowsContainerMemoryStatistics.ProtoReflect.Descriptor instead. +func (*WindowsContainerMemoryStatistics) Descriptor() ([]byte, []int) { + return file_github_com_Microsoft_hcsshim_cmd_containerd_shim_runhcs_v1_stats_stats_proto_rawDescGZIP(), []int{3} +} + +func (x *WindowsContainerMemoryStatistics) GetMemoryUsageCommitBytes() uint64 { + if x != nil { + return x.MemoryUsageCommitBytes + } + return 0 +} + +func (x *WindowsContainerMemoryStatistics) GetMemoryUsageCommitPeakBytes() uint64 { + if x != nil { + return x.MemoryUsageCommitPeakBytes + } + return 0 +} + +func (x *WindowsContainerMemoryStatistics) GetMemoryUsagePrivateWorkingSetBytes() uint64 { + if x != nil { + return x.MemoryUsagePrivateWorkingSetBytes + } + return 0 +} + +type WindowsContainerStorageStatistics struct { + state protoimpl.MessageState `protogen:"open.v1"` + ReadCountNormalized uint64 `protobuf:"varint,1,opt,name=read_count_normalized,json=readCountNormalized,proto3" json:"read_count_normalized,omitempty"` + ReadSizeBytes uint64 `protobuf:"varint,2,opt,name=read_size_bytes,json=readSizeBytes,proto3" json:"read_size_bytes,omitempty"` + WriteCountNormalized uint64 `protobuf:"varint,3,opt,name=write_count_normalized,json=writeCountNormalized,proto3" json:"write_count_normalized,omitempty"` + WriteSizeBytes uint64 `protobuf:"varint,4,opt,name=write_size_bytes,json=writeSizeBytes,proto3" json:"write_size_bytes,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *WindowsContainerStorageStatistics) Reset() { + *x = WindowsContainerStorageStatistics{} + mi := &file_github_com_Microsoft_hcsshim_cmd_containerd_shim_runhcs_v1_stats_stats_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *WindowsContainerStorageStatistics) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*WindowsContainerStorageStatistics) ProtoMessage() {} + +func (x *WindowsContainerStorageStatistics) ProtoReflect() protoreflect.Message { + mi := &file_github_com_Microsoft_hcsshim_cmd_containerd_shim_runhcs_v1_stats_stats_proto_msgTypes[4] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use WindowsContainerStorageStatistics.ProtoReflect.Descriptor instead. +func (*WindowsContainerStorageStatistics) Descriptor() ([]byte, []int) { + return file_github_com_Microsoft_hcsshim_cmd_containerd_shim_runhcs_v1_stats_stats_proto_rawDescGZIP(), []int{4} +} + +func (x *WindowsContainerStorageStatistics) GetReadCountNormalized() uint64 { + if x != nil { + return x.ReadCountNormalized + } + return 0 +} + +func (x *WindowsContainerStorageStatistics) GetReadSizeBytes() uint64 { + if x != nil { + return x.ReadSizeBytes + } + return 0 +} + +func (x *WindowsContainerStorageStatistics) GetWriteCountNormalized() uint64 { + if x != nil { + return x.WriteCountNormalized + } + return 0 +} + +func (x *WindowsContainerStorageStatistics) GetWriteSizeBytes() uint64 { + if x != nil { + return x.WriteSizeBytes + } + return 0 +} + +type VirtualMachineStatistics struct { + state protoimpl.MessageState `protogen:"open.v1"` + Processor *VirtualMachineProcessorStatistics `protobuf:"bytes,1,opt,name=processor,proto3" json:"processor,omitempty"` + Memory *VirtualMachineMemoryStatistics `protobuf:"bytes,2,opt,name=memory,proto3" json:"memory,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *VirtualMachineStatistics) Reset() { + *x = VirtualMachineStatistics{} + mi := &file_github_com_Microsoft_hcsshim_cmd_containerd_shim_runhcs_v1_stats_stats_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *VirtualMachineStatistics) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*VirtualMachineStatistics) ProtoMessage() {} + +func (x *VirtualMachineStatistics) ProtoReflect() protoreflect.Message { + mi := &file_github_com_Microsoft_hcsshim_cmd_containerd_shim_runhcs_v1_stats_stats_proto_msgTypes[5] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use VirtualMachineStatistics.ProtoReflect.Descriptor instead. +func (*VirtualMachineStatistics) Descriptor() ([]byte, []int) { + return file_github_com_Microsoft_hcsshim_cmd_containerd_shim_runhcs_v1_stats_stats_proto_rawDescGZIP(), []int{5} +} + +func (x *VirtualMachineStatistics) GetProcessor() *VirtualMachineProcessorStatistics { + if x != nil { + return x.Processor + } + return nil +} + +func (x *VirtualMachineStatistics) GetMemory() *VirtualMachineMemoryStatistics { + if x != nil { + return x.Memory + } + return nil +} + +type VirtualMachineProcessorStatistics struct { + state protoimpl.MessageState `protogen:"open.v1"` + TotalRuntimeNS uint64 `protobuf:"varint,1,opt,name=total_runtime_ns,json=totalRuntimeNs,proto3" json:"total_runtime_ns,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *VirtualMachineProcessorStatistics) Reset() { + *x = VirtualMachineProcessorStatistics{} + mi := &file_github_com_Microsoft_hcsshim_cmd_containerd_shim_runhcs_v1_stats_stats_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *VirtualMachineProcessorStatistics) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*VirtualMachineProcessorStatistics) ProtoMessage() {} + +func (x *VirtualMachineProcessorStatistics) ProtoReflect() protoreflect.Message { + mi := &file_github_com_Microsoft_hcsshim_cmd_containerd_shim_runhcs_v1_stats_stats_proto_msgTypes[6] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use VirtualMachineProcessorStatistics.ProtoReflect.Descriptor instead. +func (*VirtualMachineProcessorStatistics) Descriptor() ([]byte, []int) { + return file_github_com_Microsoft_hcsshim_cmd_containerd_shim_runhcs_v1_stats_stats_proto_rawDescGZIP(), []int{6} +} + +func (x *VirtualMachineProcessorStatistics) GetTotalRuntimeNS() uint64 { + if x != nil { + return x.TotalRuntimeNS + } + return 0 +} + +type VirtualMachineMemoryStatistics struct { + state protoimpl.MessageState `protogen:"open.v1"` + WorkingSetBytes uint64 `protobuf:"varint,1,opt,name=working_set_bytes,json=workingSetBytes,proto3" json:"working_set_bytes,omitempty"` + VirtualNodeCount uint32 `protobuf:"varint,2,opt,name=virtual_node_count,json=virtualNodeCount,proto3" json:"virtual_node_count,omitempty"` + VmMemory *VirtualMachineMemory `protobuf:"bytes,3,opt,name=vm_memory,json=vmMemory,proto3" json:"vm_memory,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *VirtualMachineMemoryStatistics) Reset() { + *x = VirtualMachineMemoryStatistics{} + mi := &file_github_com_Microsoft_hcsshim_cmd_containerd_shim_runhcs_v1_stats_stats_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *VirtualMachineMemoryStatistics) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*VirtualMachineMemoryStatistics) ProtoMessage() {} + +func (x *VirtualMachineMemoryStatistics) ProtoReflect() protoreflect.Message { + mi := &file_github_com_Microsoft_hcsshim_cmd_containerd_shim_runhcs_v1_stats_stats_proto_msgTypes[7] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use VirtualMachineMemoryStatistics.ProtoReflect.Descriptor instead. +func (*VirtualMachineMemoryStatistics) Descriptor() ([]byte, []int) { + return file_github_com_Microsoft_hcsshim_cmd_containerd_shim_runhcs_v1_stats_stats_proto_rawDescGZIP(), []int{7} +} + +func (x *VirtualMachineMemoryStatistics) GetWorkingSetBytes() uint64 { + if x != nil { + return x.WorkingSetBytes + } + return 0 +} + +func (x *VirtualMachineMemoryStatistics) GetVirtualNodeCount() uint32 { + if x != nil { + return x.VirtualNodeCount + } + return 0 +} + +func (x *VirtualMachineMemoryStatistics) GetVmMemory() *VirtualMachineMemory { + if x != nil { + return x.VmMemory + } + return nil +} + +type VirtualMachineMemory struct { + state protoimpl.MessageState `protogen:"open.v1"` + AvailableMemory int32 `protobuf:"varint,1,opt,name=available_memory,json=availableMemory,proto3" json:"available_memory,omitempty"` + AvailableMemoryBuffer int32 `protobuf:"varint,2,opt,name=available_memory_buffer,json=availableMemoryBuffer,proto3" json:"available_memory_buffer,omitempty"` + ReservedMemory uint64 `protobuf:"varint,3,opt,name=reserved_memory,json=reservedMemory,proto3" json:"reserved_memory,omitempty"` + AssignedMemory uint64 `protobuf:"varint,4,opt,name=assigned_memory,json=assignedMemory,proto3" json:"assigned_memory,omitempty"` + SlpActive bool `protobuf:"varint,5,opt,name=slp_active,json=slpActive,proto3" json:"slp_active,omitempty"` + BalancingEnabled bool `protobuf:"varint,6,opt,name=balancing_enabled,json=balancingEnabled,proto3" json:"balancing_enabled,omitempty"` + DmOperationInProgress bool `protobuf:"varint,7,opt,name=dm_operation_in_progress,json=dmOperationInProgress,proto3" json:"dm_operation_in_progress,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *VirtualMachineMemory) Reset() { + *x = VirtualMachineMemory{} + mi := &file_github_com_Microsoft_hcsshim_cmd_containerd_shim_runhcs_v1_stats_stats_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *VirtualMachineMemory) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*VirtualMachineMemory) ProtoMessage() {} + +func (x *VirtualMachineMemory) ProtoReflect() protoreflect.Message { + mi := &file_github_com_Microsoft_hcsshim_cmd_containerd_shim_runhcs_v1_stats_stats_proto_msgTypes[8] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use VirtualMachineMemory.ProtoReflect.Descriptor instead. +func (*VirtualMachineMemory) Descriptor() ([]byte, []int) { + return file_github_com_Microsoft_hcsshim_cmd_containerd_shim_runhcs_v1_stats_stats_proto_rawDescGZIP(), []int{8} +} + +func (x *VirtualMachineMemory) GetAvailableMemory() int32 { + if x != nil { + return x.AvailableMemory + } + return 0 +} + +func (x *VirtualMachineMemory) GetAvailableMemoryBuffer() int32 { + if x != nil { + return x.AvailableMemoryBuffer + } + return 0 +} + +func (x *VirtualMachineMemory) GetReservedMemory() uint64 { + if x != nil { + return x.ReservedMemory + } + return 0 +} + +func (x *VirtualMachineMemory) GetAssignedMemory() uint64 { + if x != nil { + return x.AssignedMemory + } + return 0 +} + +func (x *VirtualMachineMemory) GetSlpActive() bool { + if x != nil { + return x.SlpActive + } + return false +} + +func (x *VirtualMachineMemory) GetBalancingEnabled() bool { + if x != nil { + return x.BalancingEnabled + } + return false +} + +func (x *VirtualMachineMemory) GetDmOperationInProgress() bool { + if x != nil { + return x.DmOperationInProgress + } + return false +} + +var File_github_com_Microsoft_hcsshim_cmd_containerd_shim_runhcs_v1_stats_stats_proto protoreflect.FileDescriptor + +const file_github_com_Microsoft_hcsshim_cmd_containerd_shim_runhcs_v1_stats_stats_proto_rawDesc = "" + + "\n" + + "Lgithub.com/Microsoft/hcsshim/cmd/containerd-shim-runhcs-v1/stats/stats.proto\x12\x1acontainerd.runhcs.stats.v1\x1a\x1fgoogle/protobuf/timestamp.proto\x1a containerd.runhcs.stats.v1.WindowsContainerStatistics + 9, // 1: containerd.runhcs.stats.v1.Statistics.linux:type_name -> io.containerd.cgroups.v1.Metrics + 5, // 2: containerd.runhcs.stats.v1.Statistics.vm:type_name -> containerd.runhcs.stats.v1.VirtualMachineStatistics + 10, // 3: containerd.runhcs.stats.v1.WindowsContainerStatistics.timestamp:type_name -> google.protobuf.Timestamp + 10, // 4: containerd.runhcs.stats.v1.WindowsContainerStatistics.container_start_time:type_name -> google.protobuf.Timestamp + 2, // 5: containerd.runhcs.stats.v1.WindowsContainerStatistics.processor:type_name -> containerd.runhcs.stats.v1.WindowsContainerProcessorStatistics + 3, // 6: containerd.runhcs.stats.v1.WindowsContainerStatistics.memory:type_name -> containerd.runhcs.stats.v1.WindowsContainerMemoryStatistics + 4, // 7: containerd.runhcs.stats.v1.WindowsContainerStatistics.storage:type_name -> containerd.runhcs.stats.v1.WindowsContainerStorageStatistics + 6, // 8: containerd.runhcs.stats.v1.VirtualMachineStatistics.processor:type_name -> containerd.runhcs.stats.v1.VirtualMachineProcessorStatistics + 7, // 9: containerd.runhcs.stats.v1.VirtualMachineStatistics.memory:type_name -> containerd.runhcs.stats.v1.VirtualMachineMemoryStatistics + 8, // 10: containerd.runhcs.stats.v1.VirtualMachineMemoryStatistics.vm_memory:type_name -> containerd.runhcs.stats.v1.VirtualMachineMemory + 11, // [11:11] is the sub-list for method output_type + 11, // [11:11] is the sub-list for method input_type + 11, // [11:11] is the sub-list for extension type_name + 11, // [11:11] is the sub-list for extension extendee + 0, // [0:11] is the sub-list for field type_name +} + +func init() { file_github_com_Microsoft_hcsshim_cmd_containerd_shim_runhcs_v1_stats_stats_proto_init() } +func file_github_com_Microsoft_hcsshim_cmd_containerd_shim_runhcs_v1_stats_stats_proto_init() { + if File_github_com_Microsoft_hcsshim_cmd_containerd_shim_runhcs_v1_stats_stats_proto != nil { + return + } + file_github_com_Microsoft_hcsshim_cmd_containerd_shim_runhcs_v1_stats_stats_proto_msgTypes[0].OneofWrappers = []any{ + (*Statistics_Windows)(nil), + (*Statistics_Linux)(nil), + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_github_com_Microsoft_hcsshim_cmd_containerd_shim_runhcs_v1_stats_stats_proto_rawDesc), len(file_github_com_Microsoft_hcsshim_cmd_containerd_shim_runhcs_v1_stats_stats_proto_rawDesc)), + NumEnums: 0, + NumMessages: 9, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_github_com_Microsoft_hcsshim_cmd_containerd_shim_runhcs_v1_stats_stats_proto_goTypes, + DependencyIndexes: file_github_com_Microsoft_hcsshim_cmd_containerd_shim_runhcs_v1_stats_stats_proto_depIdxs, + MessageInfos: file_github_com_Microsoft_hcsshim_cmd_containerd_shim_runhcs_v1_stats_stats_proto_msgTypes, + }.Build() + File_github_com_Microsoft_hcsshim_cmd_containerd_shim_runhcs_v1_stats_stats_proto = out.File + file_github_com_Microsoft_hcsshim_cmd_containerd_shim_runhcs_v1_stats_stats_proto_goTypes = nil + file_github_com_Microsoft_hcsshim_cmd_containerd_shim_runhcs_v1_stats_stats_proto_depIdxs = nil +} diff --git a/vendor/github.com/Microsoft/hcsshim/cmd/containerd-shim-runhcs-v1/stats/stats.proto b/vendor/github.com/Microsoft/hcsshim/cmd/containerd-shim-runhcs-v1/stats/stats.proto new file mode 100644 index 0000000000..d870396cd7 --- /dev/null +++ b/vendor/github.com/Microsoft/hcsshim/cmd/containerd-shim-runhcs-v1/stats/stats.proto @@ -0,0 +1,69 @@ +syntax = "proto3"; + +package containerd.runhcs.stats.v1; + +import "google/protobuf/timestamp.proto"; +import "github.com/containerd/cgroups/v3/cgroup1/stats/metrics.proto"; + +option go_package = "github.com/Microsoft/hcsshim/cmd/containerd-shim-runhcs-v1/stats;stats"; + +message Statistics { + oneof container { + WindowsContainerStatistics windows = 1; + io.containerd.cgroups.v1.Metrics linux = 2; + } + VirtualMachineStatistics vm = 3; +} + +message WindowsContainerStatistics { + google.protobuf.Timestamp timestamp = 1; + google.protobuf.Timestamp container_start_time = 2; + uint64 uptime_ns = 3; + WindowsContainerProcessorStatistics processor = 4; + WindowsContainerMemoryStatistics memory = 5; + WindowsContainerStorageStatistics storage = 6; +} + +message WindowsContainerProcessorStatistics { + uint64 total_runtime_ns = 1; + uint64 runtime_user_ns = 2; + uint64 runtime_kernel_ns = 3; +} + +message WindowsContainerMemoryStatistics { + uint64 memory_usage_commit_bytes = 1; + uint64 memory_usage_commit_peak_bytes = 2; + uint64 memory_usage_private_working_set_bytes = 3; +} + +message WindowsContainerStorageStatistics { + uint64 read_count_normalized = 1; + uint64 read_size_bytes = 2; + uint64 write_count_normalized = 3; + uint64 write_size_bytes = 4; +} + +message VirtualMachineStatistics { + VirtualMachineProcessorStatistics processor = 1; + VirtualMachineMemoryStatistics memory = 2; +} + +message VirtualMachineProcessorStatistics { + uint64 total_runtime_ns = 1; +} + +message VirtualMachineMemoryStatistics { + uint64 working_set_bytes = 1; + uint32 virtual_node_count = 2; + VirtualMachineMemory vm_memory = 3; +} + +message VirtualMachineMemory { + int32 available_memory = 1; + int32 available_memory_buffer = 2; + uint64 reserved_memory = 3; + uint64 assigned_memory = 4; + bool slp_active = 5; + bool balancing_enabled = 6; + bool dm_operation_in_progress = 7; +} \ No newline at end of file diff --git a/vendor/modules.txt b/vendor/modules.txt index 89dc3d7dd3..d89e31be22 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -114,6 +114,7 @@ github.com/Microsoft/go-winio/vhd ## explicit; go 1.24.0 github.com/Microsoft/hcsshim github.com/Microsoft/hcsshim/cmd/containerd-shim-runhcs-v1/options +github.com/Microsoft/hcsshim/cmd/containerd-shim-runhcs-v1/stats github.com/Microsoft/hcsshim/computestorage github.com/Microsoft/hcsshim/hcn github.com/Microsoft/hcsshim/internal/cni