diff --git a/cmd/containerd-shim-runhcs-v1/task.go b/cmd/containerd-shim-runhcs-v1/task.go index 29b309c266..3304a5e601 100644 --- a/cmd/containerd-shim-runhcs-v1/task.go +++ b/cmd/containerd-shim-runhcs-v1/task.go @@ -7,7 +7,10 @@ import ( "github.com/Microsoft/hcsshim/cmd/containerd-shim-runhcs-v1/options" "github.com/Microsoft/hcsshim/cmd/containerd-shim-runhcs-v1/stats" + "github.com/Microsoft/hcsshim/internal/gcs" + "github.com/Microsoft/hcsshim/internal/hcs" "github.com/Microsoft/hcsshim/internal/shimdiag" + "github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/runtime/v2/task" specs "github.com/opencontainers/runtime-spec/specs-go" ) @@ -93,3 +96,12 @@ type shimTask interface { // metrics on the UVM may be returned as well. Stats(ctx context.Context) (*stats.Statistics, error) } + +// isStatsNotFound returns true if the err corresponds to a scenario +// where statistics cannot be retrieved or found +func isStatsNotFound(err error) bool { + return errdefs.IsNotFound(err) || + hcs.IsNotExist(err) || + hcs.IsOperationInvalidState(err) || + gcs.IsNotExist(err) +} diff --git a/cmd/containerd-shim-runhcs-v1/task_hcs.go b/cmd/containerd-shim-runhcs-v1/task_hcs.go index aa93019e1f..9f485375cf 100644 --- a/cmd/containerd-shim-runhcs-v1/task_hcs.go +++ b/cmd/containerd-shim-runhcs-v1/task_hcs.go @@ -674,19 +674,20 @@ func hcsPropertiesToWindowsStats(props *hcsschema.Properties) *stats.Statistics_ func (ht *hcsTask) Stats(ctx context.Context) (*stats.Statistics, error) { s := &stats.Statistics{} - props, err := ht.c.PropertiesV2(ctx, hcsschema.PTStatistics) - if err != nil { + if err != nil && !isStatsNotFound(err) { return nil, err } - if ht.isWCOW { - s.Container = hcsPropertiesToWindowsStats(props) - } else { - s.Container = &stats.Statistics_Linux{Linux: props.Metrics} + if props != nil { + if ht.isWCOW { + s.Container = hcsPropertiesToWindowsStats(props) + } else { + s.Container = &stats.Statistics_Linux{Linux: props.Metrics} + } } if ht.ownsHost && ht.host != nil { vmStats, err := ht.host.Stats(ctx) - if err != nil { + if err != nil && !isStatsNotFound(err) { return nil, err } s.VM = vmStats diff --git a/cmd/containerd-shim-runhcs-v1/task_wcow_podsandbox.go b/cmd/containerd-shim-runhcs-v1/task_wcow_podsandbox.go index 9f60d6398c..7085e8c03f 100644 --- a/cmd/containerd-shim-runhcs-v1/task_wcow_podsandbox.go +++ b/cmd/containerd-shim-runhcs-v1/task_wcow_podsandbox.go @@ -244,11 +244,11 @@ func (wpst *wcowPodSandboxTask) Share(ctx context.Context, req *shimdiag.ShareRe } func (wpst *wcowPodSandboxTask) Stats(ctx context.Context) (*stats.Statistics, error) { + stats := &stats.Statistics{} vmStats, err := wpst.host.Stats(ctx) - if err != nil { + if err != nil && !isStatsNotFound(err) { return nil, err } - stats := &stats.Statistics{} stats.VM = vmStats return stats, nil } diff --git a/internal/gcs/bridge.go b/internal/gcs/bridge.go index 692fdb2f55..d1650ecb4a 100644 --- a/internal/gcs/bridge.go +++ b/internal/gcs/bridge.go @@ -182,6 +182,15 @@ func (err *rpcError) Error() string { return "guest RPC failure: " + msg } +// IsNotExist is a helper function to determine if the inner rpc error is Not Exist +func IsNotExist(err error) bool { + switch rerr := err.(type) { + case *rpcError: + return uint32(rerr.result) == hrComputeSystemDoesNotExist + } + return false +} + // Err returns the RPC's result. This may be a transport error or an error from // the message response. func (call *rpc) Err() error {