diff --git a/pkg/metric/metric.go b/pkg/metric/metric.go index 0fd68dddc..72e0d88cc 100644 --- a/pkg/metric/metric.go +++ b/pkg/metric/metric.go @@ -135,6 +135,7 @@ func Initialize() error { for _, s := range allStages { m.Stages = append(m.Stages, string(s)) } + allMetrics.registration = &m if err := eventchannel.Emit(&m); err != nil { return fmt.Errorf("unable to emit metric initialize event: %w", err) } @@ -143,6 +144,18 @@ func Initialize() error { return nil } +// GetMetricRegistration returns the metric registration data for all registered metrics. +// Must be called after Initialize(). +func GetMetricRegistration() (*pb.MetricRegistration, error) { + if !initialized { + return nil, errors.New("metric.GetMetricRegistration called before metric.Initialize") + } + if allMetrics.registration == nil { + return nil, errors.New("metrics are disabled") + } + return allMetrics.registration, nil +} + // Disable sends an empty metric registration event over the event channel, // disabling metric collection. // @@ -846,6 +859,9 @@ func (s stageTiming) inProgress() bool { // metricSet holds metric data. type metricSet struct { + // Metric registration data for all the metrics below. + registration *pb.MetricRegistration + // Map of uint64 metrics. uint64Metrics map[string]customUint64Metric diff --git a/pkg/sentry/control/BUILD b/pkg/sentry/control/BUILD index 430eabe4a..9a28b0b2e 100644 --- a/pkg/sentry/control/BUILD +++ b/pkg/sentry/control/BUILD @@ -38,6 +38,7 @@ go_library( "//pkg/fspath", "//pkg/log", "//pkg/metric", + "//pkg/metric:metric_go_proto", "//pkg/prometheus", "//pkg/sentry/fdimport", "//pkg/sentry/fsimpl/host", diff --git a/pkg/sentry/control/metrics.go b/pkg/sentry/control/metrics.go index 801e86a11..f7af83cee 100644 --- a/pkg/sentry/control/metrics.go +++ b/pkg/sentry/control/metrics.go @@ -16,12 +16,35 @@ package control import ( "gvisor.dev/gvisor/pkg/metric" + pb "gvisor.dev/gvisor/pkg/metric/metric_go_proto" "gvisor.dev/gvisor/pkg/prometheus" ) // Metrics includes metrics-related RPC stubs. type Metrics struct{} +// GetRegisteredMetricsOpts contains metric registration query options. +type GetRegisteredMetricsOpts struct{} + +// MetricsRegistrationResponse contains metric registration data. +type MetricsRegistrationResponse struct { + RegisteredMetrics *pb.MetricRegistration +} + +// GetRegisteredMetrics sets `out` to the metric registration information. +// Meant to be called over the control channel, with `out` as return value. +// This should be called during Sentry boot before any container starts. +// Metric registration data is used by the processes querying sandbox metrics +// to ensure the integrity of metrics exported from the untrusted sandbox. +func (u *Metrics) GetRegisteredMetrics(_ *GetRegisteredMetricsOpts, out *MetricsRegistrationResponse) error { + registration, err := metric.GetMetricRegistration() + if err != nil { + return err + } + out.RegisteredMetrics = registration + return nil +} + // MetricsExportOpts contains metric exporting options. type MetricsExportOpts struct{} diff --git a/runsc/boot/controller.go b/runsc/boot/controller.go index bc71e7be6..9ca112540 100644 --- a/runsc/boot/controller.go +++ b/runsc/boot/controller.go @@ -131,7 +131,8 @@ const ( // Metrics related commands (see metrics.go). const ( - MetricsExport = "Metrics.Export" + MetricsGetRegistered = "Metrics.GetRegisteredMetrics" + MetricsExport = "Metrics.Export" ) // Commands for interacting with cgroupfs within the sandbox.