From f35aaadef9f280a3cde20f58999c11ffcfb5a414 Mon Sep 17 00:00:00 2001 From: Hamza El-Saawy Date: Thu, 21 Apr 2022 16:02:38 -0400 Subject: [PATCH 1/2] Automatic span creation ttrpc interceptor automatically formats (as JSON) and adds server requests and responses as span attributes. Host and guest bridge automatically creates spans for RPCs. Replaced redundant `cmd/containerd-shim-runhcs-v1/service.go.(Service)` `internal/gcs`, and `interna\guest\bridge` spans with `.Trace` log entries, since they include all the same (or less) information as those automatically generated by the ttrp interceptor and `(*bridge).RPC` Signed-off-by: Hamza El-Saawy --- cmd/containerd-shim-runhcs-v1/serve.go | 10 +- cmd/containerd-shim-runhcs-v1/service.go | 321 +++-------------------- internal/gcs/bridge.go | 8 +- internal/gcs/container.go | 66 ++--- internal/gcs/guestconnection.go | 17 +- internal/gcs/process.go | 81 ++---- internal/gcs/protocol.go | 2 +- internal/guest/bridge/bridge.go | 27 +- internal/guest/bridge/bridge_v2.go | 127 +++++---- internal/logfields/fields.go | 4 + pkg/octtrpc/interceptor.go | 36 ++- 11 files changed, 206 insertions(+), 493 deletions(-) diff --git a/cmd/containerd-shim-runhcs-v1/serve.go b/cmd/containerd-shim-runhcs-v1/serve.go index 290f986c42..4a966a4c41 100644 --- a/cmd/containerd-shim-runhcs-v1/serve.go +++ b/cmd/containerd-shim-runhcs-v1/serve.go @@ -19,6 +19,7 @@ import ( "github.com/pkg/errors" "github.com/sirupsen/logrus" "github.com/urfave/cli" + "go.opencensus.io/trace" "golang.org/x/sys/windows" "google.golang.org/protobuf/proto" "google.golang.org/protobuf/types/known/anypb" @@ -26,6 +27,7 @@ import ( runhcsopts "github.com/Microsoft/hcsshim/cmd/containerd-shim-runhcs-v1/options" "github.com/Microsoft/hcsshim/internal/extendedtask" hcslog "github.com/Microsoft/hcsshim/internal/log" + "github.com/Microsoft/hcsshim/internal/logfields" "github.com/Microsoft/hcsshim/internal/shimdiag" "github.com/Microsoft/hcsshim/pkg/octtrpc" ) @@ -193,7 +195,13 @@ var serveCommand = cli.Command{ return fmt.Errorf("failed to create new service: %w", err) } - s, err := ttrpc.NewServer(ttrpc.WithUnaryServerInterceptor(octtrpc.ServerInterceptor())) + s, err := ttrpc.NewServer( + ttrpc.WithUnaryServerInterceptor(octtrpc.ServerInterceptor( + octtrpc.WithAttributes( // todo (helsaawy) set these in resource when we switch to OTel + trace.StringAttribute(logfields.ShimID, svc.tid), + trace.BoolAttribute(logfields.IsSandbox, svc.isSandbox), + ), + ))) if err != nil { return err } diff --git a/cmd/containerd-shim-runhcs-v1/service.go b/cmd/containerd-shim-runhcs-v1/service.go index d9f62e0ef9..36540a682b 100644 --- a/cmd/containerd-shim-runhcs-v1/service.go +++ b/cmd/containerd-shim-runhcs-v1/service.go @@ -6,18 +6,18 @@ import ( "context" "os" "runtime" - "strings" "sync" "sync/atomic" "time" task "github.com/containerd/containerd/api/runtime/task/v2" "github.com/containerd/containerd/errdefs" - "go.opencensus.io/trace" + "github.com/sirupsen/logrus" "google.golang.org/protobuf/types/known/emptypb" "github.com/Microsoft/hcsshim/internal/extendedtask" - "github.com/Microsoft/hcsshim/internal/oc" + "github.com/Microsoft/hcsshim/internal/log" + "github.com/Microsoft/hcsshim/internal/logfields" "github.com/Microsoft/hcsshim/internal/shimdiag" ) @@ -99,405 +99,150 @@ func NewService(o ...ServiceOption) (svc *service, err error) { } func (s *service) State(ctx context.Context, req *task.StateRequest) (resp *task.StateResponse, err error) { - ctx, span := oc.StartSpan(ctx, "State") - defer span.End() - defer func() { - if resp != nil { - span.AddAttributes( - trace.StringAttribute("status", resp.Status.String()), - trace.Int64Attribute("exitStatus", int64(resp.ExitStatus)), - trace.StringAttribute("exitedAt", resp.ExitedAt.String())) - } - oc.SetSpanStatus(span, err) - }() - - span.AddAttributes( - trace.StringAttribute("tid", req.ID), - trace.StringAttribute("eid", req.ExecID)) - - if s.isSandbox { - span.AddAttributes(trace.StringAttribute("pod-id", s.tid)) - } + s.logEntry(ctx).Trace("State") r, e := s.stateInternal(ctx, req) return r, errdefs.ToGRPC(e) } func (s *service) Create(ctx context.Context, req *task.CreateTaskRequest) (resp *task.CreateTaskResponse, err error) { - ctx, span := oc.StartSpan(ctx, "Create") - defer span.End() - defer func() { - if resp != nil { - span.AddAttributes(trace.Int64Attribute("pid", int64(resp.Pid))) - } - oc.SetSpanStatus(span, err) - }() - - span.AddAttributes( - trace.StringAttribute("tid", req.ID), - trace.StringAttribute("bundle", req.Bundle), - // trace.StringAttribute("rootfs", req.Rootfs), TODO: JTERRY75 - - // OpenCensus doesnt support slice like our logrus hook - trace.BoolAttribute("terminal", req.Terminal), - trace.StringAttribute("stdin", req.Stdin), - trace.StringAttribute("stdout", req.Stdout), - trace.StringAttribute("stderr", req.Stderr), - trace.StringAttribute("checkpoint", req.Checkpoint), - trace.StringAttribute("parentcheckpoint", req.ParentCheckpoint)) - - if s.isSandbox { - span.AddAttributes(trace.StringAttribute("pod-id", s.tid)) - } + s.logEntry(ctx).Trace("Create") r, e := s.createInternal(ctx, req) return r, errdefs.ToGRPC(e) } func (s *service) Start(ctx context.Context, req *task.StartRequest) (resp *task.StartResponse, err error) { - ctx, span := oc.StartSpan(ctx, "Start") - defer span.End() - defer func() { - if resp != nil { - span.AddAttributes(trace.Int64Attribute("pid", int64(resp.Pid))) - } - oc.SetSpanStatus(span, err) - }() - - span.AddAttributes( - trace.StringAttribute("tid", req.ID), - trace.StringAttribute("eid", req.ExecID)) - - if s.isSandbox { - span.AddAttributes(trace.StringAttribute("pod-id", s.tid)) - } + s.logEntry(ctx).Trace("Start") r, e := s.startInternal(ctx, req) return r, errdefs.ToGRPC(e) } func (s *service) Delete(ctx context.Context, req *task.DeleteRequest) (resp *task.DeleteResponse, err error) { - ctx, span := oc.StartSpan(ctx, "Delete") - defer span.End() - defer func() { - if resp != nil { - span.AddAttributes( - trace.Int64Attribute("pid", int64(resp.Pid)), - trace.Int64Attribute("exitStatus", int64(resp.ExitStatus)), - trace.StringAttribute("exitedAt", resp.ExitedAt.String())) - } - oc.SetSpanStatus(span, err) - }() - - span.AddAttributes( - trace.StringAttribute("tid", req.ID), - trace.StringAttribute("eid", req.ExecID)) - - if s.isSandbox { - span.AddAttributes(trace.StringAttribute("pod-id", s.tid)) - } + s.logEntry(ctx).Trace("Delete") r, e := s.deleteInternal(ctx, req) return r, errdefs.ToGRPC(e) } func (s *service) Pids(ctx context.Context, req *task.PidsRequest) (_ *task.PidsResponse, err error) { - ctx, span := oc.StartSpan(ctx, "Pids") - defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() - - span.AddAttributes(trace.StringAttribute("tid", req.ID)) - - if s.isSandbox { - span.AddAttributes(trace.StringAttribute("pod-id", s.tid)) - } + s.logEntry(ctx).Trace("Pids") r, e := s.pidsInternal(ctx, req) return r, errdefs.ToGRPC(e) } func (s *service) Pause(ctx context.Context, req *task.PauseRequest) (_ *emptypb.Empty, err error) { - ctx, span := oc.StartSpan(ctx, "Pause") - defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() - - span.AddAttributes(trace.StringAttribute("tid", req.ID)) - - if s.isSandbox { - span.AddAttributes(trace.StringAttribute("pod-id", s.tid)) - } + s.logEntry(ctx).Trace("Pause") r, e := s.pauseInternal(ctx, req) return r, errdefs.ToGRPC(e) } func (s *service) Resume(ctx context.Context, req *task.ResumeRequest) (_ *emptypb.Empty, err error) { - ctx, span := oc.StartSpan(ctx, "Resume") - defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() - - span.AddAttributes(trace.StringAttribute("tid", req.ID)) - - if s.isSandbox { - span.AddAttributes(trace.StringAttribute("pod-id", s.tid)) - } + s.logEntry(ctx).Trace("Resume") r, e := s.resumeInternal(ctx, req) return r, errdefs.ToGRPC(e) } func (s *service) Checkpoint(ctx context.Context, req *task.CheckpointTaskRequest) (_ *emptypb.Empty, err error) { - ctx, span := oc.StartSpan(ctx, "Checkpoint") - defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() - - span.AddAttributes( - trace.StringAttribute("tid", req.ID), - trace.StringAttribute("path", req.Path)) - - if s.isSandbox { - span.AddAttributes(trace.StringAttribute("pod-id", s.tid)) - } + s.logEntry(ctx).Trace("Checkpoint") r, e := s.checkpointInternal(ctx, req) return r, errdefs.ToGRPC(e) } func (s *service) Kill(ctx context.Context, req *task.KillRequest) (_ *emptypb.Empty, err error) { - ctx, span := oc.StartSpan(ctx, "Kill") - defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() - - span.AddAttributes( - trace.StringAttribute("tid", req.ID), - trace.StringAttribute("eid", req.ExecID), - trace.Int64Attribute("signal", int64(req.Signal)), - trace.BoolAttribute("all", req.All)) - - if s.isSandbox { - span.AddAttributes(trace.StringAttribute("pod-id", s.tid)) - } + s.logEntry(ctx).Trace("Kill") r, e := s.killInternal(ctx, req) return r, errdefs.ToGRPC(e) } func (s *service) Exec(ctx context.Context, req *task.ExecProcessRequest) (_ *emptypb.Empty, err error) { - ctx, span := oc.StartSpan(ctx, "Exec") - defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() - - span.AddAttributes( - trace.StringAttribute("tid", req.ID), - trace.StringAttribute("eid", req.ExecID), - trace.BoolAttribute("terminal", req.Terminal), - trace.StringAttribute("stdin", req.Stdin), - trace.StringAttribute("stdout", req.Stdout), - trace.StringAttribute("stderr", req.Stderr)) - - if s.isSandbox { - span.AddAttributes(trace.StringAttribute("pod-id", s.tid)) - } + s.logEntry(ctx).Trace("Exec") r, e := s.execInternal(ctx, req) return r, errdefs.ToGRPC(e) } func (s *service) DiagExecInHost(ctx context.Context, req *shimdiag.ExecProcessRequest) (_ *shimdiag.ExecProcessResponse, err error) { - ctx, span := oc.StartSpan(ctx, "DiagExecInHost") - defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() - - span.AddAttributes( - trace.StringAttribute("args", strings.Join(req.Args, " ")), - trace.StringAttribute("workdir", req.Workdir), - trace.BoolAttribute("terminal", req.Terminal), - trace.StringAttribute("stdin", req.Stdin), - trace.StringAttribute("stdout", req.Stdout), - trace.StringAttribute("stderr", req.Stderr)) - - if s.isSandbox { - span.AddAttributes(trace.StringAttribute("pod-id", s.tid)) - } + s.logEntry(ctx).Trace("DiagExecInHost") r, e := s.diagExecInHostInternal(ctx, req) return r, errdefs.ToGRPC(e) } func (s *service) DiagShare(ctx context.Context, req *shimdiag.ShareRequest) (_ *shimdiag.ShareResponse, err error) { - ctx, span := oc.StartSpan(ctx, "DiagShare") - defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() - - span.AddAttributes( - trace.StringAttribute("hostpath", req.HostPath), - trace.StringAttribute("uvmpath", req.UvmPath), - trace.BoolAttribute("readonly", req.ReadOnly)) - - if s.isSandbox { - span.AddAttributes(trace.StringAttribute("pod-id", s.tid)) - } + s.logEntry(ctx).Trace("DiagShare") r, e := s.diagShareInternal(ctx, req) return r, errdefs.ToGRPC(e) } func (s *service) DiagTasks(ctx context.Context, req *shimdiag.TasksRequest) (_ *shimdiag.TasksResponse, err error) { - ctx, span := oc.StartSpan(ctx, "DiagTasks") - defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() - - span.AddAttributes( - trace.BoolAttribute("execs", req.Execs)) - - if s.isSandbox { - span.AddAttributes(trace.StringAttribute("pod-id", s.tid)) - } + s.logEntry(ctx).Trace("DiagTasks") r, e := s.diagTasksInternal(ctx, req) return r, errdefs.ToGRPC(e) } func (s *service) ResizePty(ctx context.Context, req *task.ResizePtyRequest) (_ *emptypb.Empty, err error) { - ctx, span := oc.StartSpan(ctx, "ResizePty") - defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() - - span.AddAttributes( - trace.StringAttribute("tid", req.ID), - trace.StringAttribute("eid", req.ExecID), - trace.Int64Attribute("width", int64(req.Width)), - trace.Int64Attribute("height", int64(req.Height))) - - if s.isSandbox { - span.AddAttributes(trace.StringAttribute("pod-id", s.tid)) - } + s.logEntry(ctx).Trace("ResizePty") r, e := s.resizePtyInternal(ctx, req) return r, errdefs.ToGRPC(e) } func (s *service) CloseIO(ctx context.Context, req *task.CloseIORequest) (_ *emptypb.Empty, err error) { - ctx, span := oc.StartSpan(ctx, "CloseIO") - defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() - - span.AddAttributes( - trace.StringAttribute("tid", req.ID), - trace.StringAttribute("eid", req.ExecID), - trace.BoolAttribute("stdin", req.Stdin)) - - if s.isSandbox { - span.AddAttributes(trace.StringAttribute("pod-id", s.tid)) - } + s.logEntry(ctx).Trace("CloseIO") r, e := s.closeIOInternal(ctx, req) return r, errdefs.ToGRPC(e) } func (s *service) Update(ctx context.Context, req *task.UpdateTaskRequest) (_ *emptypb.Empty, err error) { - ctx, span := oc.StartSpan(ctx, "Update") - defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() - - span.AddAttributes(trace.StringAttribute("tid", req.ID)) - - if s.isSandbox { - span.AddAttributes(trace.StringAttribute("pod-id", s.tid)) - } + s.logEntry(ctx).Trace("Update") r, e := s.updateInternal(ctx, req) return r, errdefs.ToGRPC(e) } func (s *service) Wait(ctx context.Context, req *task.WaitRequest) (resp *task.WaitResponse, err error) { - ctx, span := oc.StartSpan(ctx, "Wait") - defer span.End() - defer func() { - if resp != nil { - span.AddAttributes( - trace.Int64Attribute("exitStatus", int64(resp.ExitStatus)), - trace.StringAttribute("exitedAt", resp.ExitedAt.String())) - } - oc.SetSpanStatus(span, err) - }() - - span.AddAttributes( - trace.StringAttribute("tid", req.ID), - trace.StringAttribute("eid", req.ExecID)) - - if s.isSandbox { - span.AddAttributes(trace.StringAttribute("pod-id", s.tid)) - } + s.logEntry(ctx).Trace("Wait") r, e := s.waitInternal(ctx, req) return r, errdefs.ToGRPC(e) } func (s *service) Stats(ctx context.Context, req *task.StatsRequest) (_ *task.StatsResponse, err error) { - ctx, span := oc.StartSpan(ctx, "Stats") - defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() - - span.AddAttributes(trace.StringAttribute("tid", req.ID)) - - if s.isSandbox { - span.AddAttributes(trace.StringAttribute("pod-id", s.tid)) - } + s.logEntry(ctx).Trace("Stats") r, e := s.statsInternal(ctx, req) return r, errdefs.ToGRPC(e) } func (s *service) Connect(ctx context.Context, req *task.ConnectRequest) (resp *task.ConnectResponse, err error) { - ctx, span := oc.StartSpan(ctx, "Connect") - defer span.End() - defer func() { - if resp != nil { - span.AddAttributes( - trace.Int64Attribute("shimPid", int64(resp.ShimPid)), - trace.Int64Attribute("taskPid", int64(resp.TaskPid)), - trace.StringAttribute("version", resp.Version)) - } - oc.SetSpanStatus(span, err) - }() - - span.AddAttributes(trace.StringAttribute("tid", req.ID)) - - if s.isSandbox { - span.AddAttributes(trace.StringAttribute("pod-id", s.tid)) - } + s.logEntry(ctx).Trace("Connect") r, e := s.connectInternal(ctx, req) return r, errdefs.ToGRPC(e) } func (s *service) Shutdown(ctx context.Context, req *task.ShutdownRequest) (_ *emptypb.Empty, err error) { - ctx, span := oc.StartSpan(ctx, "Shutdown") - defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() - - span.AddAttributes(trace.StringAttribute("tid", req.ID)) - - if s.isSandbox { - span.AddAttributes(trace.StringAttribute("pod-id", s.tid)) - } + s.logEntry(ctx).Trace("Shutdown") r, e := s.shutdownInternal(ctx, req) return r, errdefs.ToGRPC(e) } func (s *service) DiagStacks(ctx context.Context, req *shimdiag.StacksRequest) (*shimdiag.StacksResponse, error) { + s.logEntry(ctx).Trace("DiagStacks") if s == nil { return nil, nil } - ctx, span := oc.StartSpan(ctx, "DiagStacks") - defer span.End() - - span.AddAttributes(trace.StringAttribute("tid", s.tid)) - - if s.isSandbox { - span.AddAttributes(trace.StringAttribute("pod-id", s.tid)) - } buf := make([]byte, 4096) for { @@ -519,24 +264,17 @@ func (s *service) DiagStacks(ctx context.Context, req *shimdiag.StacksRequest) ( } func (s *service) DiagPid(ctx context.Context, req *shimdiag.PidRequest) (*shimdiag.PidResponse, error) { + s.logEntry(ctx).Trace("DiagPid") if s == nil { return nil, nil } - ctx, span := oc.StartSpan(ctx, "DiagPid") //nolint:ineffassign,staticcheck - defer span.End() - - span.AddAttributes(trace.StringAttribute("tid", s.tid)) - return &shimdiag.PidResponse{ Pid: int32(os.Getpid()), }, nil } func (s *service) ComputeProcessorInfo(ctx context.Context, req *extendedtask.ComputeProcessorInfoRequest) (*extendedtask.ComputeProcessorInfoResponse, error) { - ctx, span := oc.StartSpan(ctx, "ComputeProcessorInfo") - defer span.End() - - span.AddAttributes(trace.StringAttribute("tid", s.tid)) + s.logEntry(ctx).Trace("ComputeProcessorInfo") r, e := s.computeProcessorInfoInternal(ctx, req) return r, errdefs.ToGRPC(e) @@ -554,3 +292,10 @@ func (s *service) IsShutdown() bool { return false } } + +func (s *service) logEntry(ctx context.Context) *logrus.Entry { + return log.G(ctx).WithFields(logrus.Fields{ + logfields.ShimID: s.tid, + logfields.IsSandbox: s.isSandbox, + }) +} diff --git a/internal/gcs/bridge.go b/internal/gcs/bridge.go index 6f8a6b0558..fe6360dcaa 100644 --- a/internal/gcs/bridge.go +++ b/internal/gcs/bridge.go @@ -19,6 +19,7 @@ import ( "golang.org/x/sys/windows" "github.com/Microsoft/hcsshim/internal/log" + "github.com/Microsoft/hcsshim/internal/oc" ) const ( @@ -220,7 +221,11 @@ func (call *rpc) Wait() { // If allowCancel is set and the context becomes done, returns an error without // waiting for a response. Avoid this on messages that are not idempotent or // otherwise safe to ignore the response of. -func (brdg *bridge) RPC(ctx context.Context, proc rpcProc, req requestMessage, resp responseMessage, allowCancel bool) error { +func (brdg *bridge) RPC(ctx context.Context, proc rpcProc, req requestMessage, resp responseMessage, allowCancel bool) (err error) { + ctx, span := oc.StartSpan(ctx, "gcs::bridge::RPC::"+proc.String(), oc.WithClientSpanKind) + defer span.End() + defer func() { oc.SetSpanStatus(span, err) }() + call, err := brdg.AsyncRPC(ctx, proc, req, resp) if err != nil { return err @@ -239,6 +244,7 @@ func (brdg *bridge) RPC(ctx context.Context, proc rpcProc, req requestMessage, r brdg.log.WithField("reason", ctx.Err()).Warn("ignoring response to bridge message") return ctx.Err() case <-t.C: + //todo: dont kill bridge on message timeout brdg.kill(errors.New("message timeout")) <-call.ch return call.Err() diff --git a/internal/gcs/container.go b/internal/gcs/container.go index a64408b834..f3c60116c1 100644 --- a/internal/gcs/container.go +++ b/internal/gcs/container.go @@ -12,7 +12,9 @@ import ( "github.com/Microsoft/hcsshim/internal/hcs/schema1" hcsschema "github.com/Microsoft/hcsshim/internal/hcs/schema2" "github.com/Microsoft/hcsshim/internal/log" + "github.com/Microsoft/hcsshim/internal/logfields" "github.com/Microsoft/hcsshim/internal/oc" + "github.com/sirupsen/logrus" "go.opencensus.io/trace" ) @@ -37,10 +39,9 @@ var _ cow.Container = &Container{} // CreateContainer creates a container using ID `cid` and `cfg`. The request // will likely not be cancellable even if `ctx` becomes done. func (gc *GuestConnection) CreateContainer(ctx context.Context, cid string, config interface{}) (_ *Container, err error) { - ctx, span := oc.StartSpan(ctx, "gcs::GuestConnection::CreateContainer", oc.WithClientSpanKind) - defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() - span.AddAttributes(trace.StringAttribute("cid", cid)) + log.G(ctx).WithFields(logrus.Fields{ + logfields.ContainerID: cid, + }).Trace("gcs::GuestConnection::CreateContainer") c := &Container{ gc: gc, @@ -69,6 +70,10 @@ func (gc *GuestConnection) CreateContainer(ctx context.Context, cid string, conf // CloneContainer just creates the wrappers and sets up notification requests for a // container that is already running inside the UVM (after cloning). func (gc *GuestConnection) CloneContainer(ctx context.Context, cid string) (_ *Container, err error) { + log.G(ctx).WithFields(logrus.Fields{ + logfields.ContainerID: cid, + }).Trace("gcs::GuestConnection::CloneContainer") + c := &Container{ gc: gc, id: cid, @@ -97,22 +102,15 @@ func (c *Container) IsOCI() bool { // Close releases associated with the container. func (c *Container) Close() error { - c.closeOnce.Do(func() { - _, span := oc.StartSpan(context.Background(), "gcs::Container::Close") - defer span.End() - span.AddAttributes(trace.StringAttribute("cid", c.id)) + c.logEntry(context.Background()).Trace("gcs::Container::Close") + c.closeOnce.Do(func() { close(c.closeCh) }) - close(c.closeCh) - }) return nil } // CreateProcess creates a process in the container. func (c *Container) CreateProcess(ctx context.Context, config interface{}) (_ cow.Process, err error) { - ctx, span := oc.StartSpan(ctx, "gcs::Container::CreateProcess", oc.WithClientSpanKind) - defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() - span.AddAttributes(trace.StringAttribute("cid", c.id)) + c.logEntry(ctx).Trace("gcs::Container::CreateProcess") return c.gc.exec(ctx, c.id, config) } @@ -124,10 +122,7 @@ func (c *Container) ID() string { // Modify sends a modify request to the container. func (c *Container) Modify(ctx context.Context, config interface{}) (err error) { - ctx, span := oc.StartSpan(ctx, "gcs::Container::Modify", oc.WithClientSpanKind) - defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() - span.AddAttributes(trace.StringAttribute("cid", c.id)) + c.logEntry(ctx).Trace("gcs::Container::Modify") req := containerModifySettings{ requestBase: makeRequest(ctx, c.id), @@ -139,10 +134,7 @@ func (c *Container) Modify(ctx context.Context, config interface{}) (err error) // Properties returns the requested container properties targeting a V1 schema container. func (c *Container) Properties(ctx context.Context, types ...schema1.PropertyType) (_ *schema1.ContainerProperties, err error) { - ctx, span := oc.StartSpan(ctx, "gcs::Container::Properties", oc.WithClientSpanKind) - defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() - span.AddAttributes(trace.StringAttribute("cid", c.id)) + c.logEntry(ctx).Trace("gcs::Container::Properties") req := containerGetProperties{ requestBase: makeRequest(ctx, c.id), @@ -158,10 +150,7 @@ func (c *Container) Properties(ctx context.Context, types ...schema1.PropertyTyp // PropertiesV2 returns the requested container properties targeting a V2 schema container. func (c *Container) PropertiesV2(ctx context.Context, types ...hcsschema.PropertyType) (_ *hcsschema.Properties, err error) { - ctx, span := oc.StartSpan(ctx, "gcs::Container::PropertiesV2", oc.WithClientSpanKind) - defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() - span.AddAttributes(trace.StringAttribute("cid", c.id)) + c.logEntry(ctx).Trace("gcs::Container::PropertiesV2") req := containerGetPropertiesV2{ requestBase: makeRequest(ctx, c.id), @@ -177,10 +166,7 @@ func (c *Container) PropertiesV2(ctx context.Context, types ...hcsschema.Propert // Start starts the container. func (c *Container) Start(ctx context.Context) (err error) { - ctx, span := oc.StartSpan(ctx, "gcs::Container::Start", oc.WithClientSpanKind) - defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() - span.AddAttributes(trace.StringAttribute("cid", c.id)) + c.logEntry(ctx).Trace("gcs::Container::Start") req := makeRequest(ctx, c.id) var resp responseBase @@ -198,7 +184,7 @@ func (c *Container) shutdown(ctx context.Context, proc rpcProc) error { select { case <-c.notifyCh: default: - log.G(ctx).WithError(err).Warn("ignoring missing container") + c.logEntry(ctx).WithError(err).Warn("ignoring missing container") } } return nil @@ -208,10 +194,7 @@ func (c *Container) shutdown(ctx context.Context, proc rpcProc) error { // might not be terminated by the time the request completes (and might never // terminate). func (c *Container) Shutdown(ctx context.Context) (err error) { - ctx, span := oc.StartSpan(ctx, "gcs::Container::Shutdown", oc.WithClientSpanKind) - defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() - span.AddAttributes(trace.StringAttribute("cid", c.id)) + c.logEntry(ctx).Trace("gcs::Container::Shutdown") ctx, cancel := context.WithTimeout(ctx, 30*time.Second) defer cancel() @@ -222,10 +205,7 @@ func (c *Container) Shutdown(ctx context.Context) (err error) { // might not be terminated by the time the request completes (and might never // terminate). func (c *Container) Terminate(ctx context.Context) (err error) { - ctx, span := oc.StartSpan(ctx, "gcs::Container::Terminate", oc.WithClientSpanKind) - defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() - span.AddAttributes(trace.StringAttribute("cid", c.id)) + c.logEntry(ctx).Trace("gcs::Container::Terminate") ctx, cancel := context.WithTimeout(ctx, 30*time.Second) defer cancel() @@ -248,8 +228,9 @@ func (c *Container) Wait() error { } func (c *Container) waitBackground() { - ctx, span := oc.StartSpan(context.Background(), "gcs::Container::waitBackground") + _, span := oc.StartSpan(context.Background(), "gcs::Container::waitBackground") defer span.End() + defer func() { oc.SetSpanStatus(span, c.waitError) }() span.AddAttributes(trace.StringAttribute("cid", c.id)) select { @@ -258,7 +239,8 @@ func (c *Container) waitBackground() { c.waitError = errors.New("container closed") } close(c.waitBlock) +} - log.G(ctx).Debug("container exited") - oc.SetSpanStatus(span, c.waitError) +func (c *Container) logEntry(ctx context.Context) *logrus.Entry { + return log.G(ctx).WithField(logfields.ContainerID, c.id) } diff --git a/internal/gcs/guestconnection.go b/internal/gcs/guestconnection.go index 73282e95d0..9af89a32c1 100644 --- a/internal/gcs/guestconnection.go +++ b/internal/gcs/guestconnection.go @@ -166,9 +166,7 @@ func (gc *GuestConnection) connect(ctx context.Context, isColdStart bool, initGu // Modify sends a modify settings request to the null container. This is // generally used to prepare virtual hardware that has been added to the guest. func (gc *GuestConnection) Modify(ctx context.Context, settings interface{}) (err error) { - ctx, span := oc.StartSpan(ctx, "gcs::GuestConnection::Modify", oc.WithClientSpanKind) - defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() + log.G(ctx).Trace("gcs::GuestConnection::Modify") req := containerModifySettings{ requestBase: makeRequest(ctx, nullContainerID), @@ -179,9 +177,7 @@ func (gc *GuestConnection) Modify(ctx context.Context, settings interface{}) (er } func (gc *GuestConnection) DumpStacks(ctx context.Context) (response string, err error) { - ctx, span := oc.StartSpan(ctx, "gcs::GuestConnection::DumpStacks", oc.WithClientSpanKind) - defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() + log.G(ctx).Trace("gcs::GuestConnection::DumpStacks") req := dumpStacksRequest{ requestBase: makeRequest(ctx, nullContainerID), @@ -192,10 +188,7 @@ func (gc *GuestConnection) DumpStacks(ctx context.Context) (response string, err } func (gc *GuestConnection) DeleteContainerState(ctx context.Context, cid string) (err error) { - ctx, span := oc.StartSpan(ctx, "gcs::GuestConnection::DeleteContainerState", oc.WithClientSpanKind) - defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() - span.AddAttributes(trace.StringAttribute("cid", cid)) + log.G(ctx).Trace("gcs::GuestConnection::DeleteContainerState") req := deleteContainerStateRequest{ requestBase: makeRequest(ctx, cid), @@ -215,9 +208,7 @@ func (gc *GuestConnection) Close() error { // CreateProcess creates a process in the container host. func (gc *GuestConnection) CreateProcess(ctx context.Context, settings interface{}) (_ cow.Process, err error) { - ctx, span := oc.StartSpan(ctx, "gcs::GuestConnection::CreateProcess", oc.WithClientSpanKind) - defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() + log.G(ctx).Trace("gcs::GuestConnection::CreateProcess") return gc.exec(ctx, nullContainerID, settings) } diff --git a/internal/gcs/process.go b/internal/gcs/process.go index 87c5c29ae4..0744454364 100644 --- a/internal/gcs/process.go +++ b/internal/gcs/process.go @@ -124,32 +124,24 @@ func (gc *GuestConnection) exec(ctx context.Context, cid string, params interfac // Close releases resources associated with the process and closes the // associated standard IO streams. func (p *Process) Close() error { - ctx, span := oc.StartSpan(context.Background(), "gcs::Process::Close") - defer span.End() - span.AddAttributes( - trace.StringAttribute("cid", p.cid), - trace.Int64Attribute("pid", int64(p.id))) + entry := p.logEntry(context.Background()) + entry.Trace("gcs::Process::Close") if err := p.stdin.Close(); err != nil { - log.G(ctx).WithError(err).Warn("close stdin failed") + entry.WithError(err).Warn("close stdin failed") } if err := p.stdout.Close(); err != nil { - log.G(ctx).WithError(err).Warn("close stdout failed") + entry.WithError(err).Warn("close stdout failed") } if err := p.stderr.Close(); err != nil { - log.G(ctx).WithError(err).Warn("close stderr failed") + entry.WithError(err).Warn("close stderr failed") } return nil } // CloseStdin causes the process to read EOF on its stdin stream. func (p *Process) CloseStdin(ctx context.Context) (err error) { - ctx, span := oc.StartSpan(ctx, "gcs::Process::CloseStdin") //nolint:ineffassign,staticcheck - defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() - span.AddAttributes( - trace.StringAttribute("cid", p.cid), - trace.Int64Attribute("pid", int64(p.id))) + p.logEntry(ctx).Trace("gcs::Process::CloseStdin") p.stdinCloseWriteOnce.Do(func() { p.stdinCloseWriteErr = p.stdin.CloseWrite() @@ -158,23 +150,13 @@ func (p *Process) CloseStdin(ctx context.Context) (err error) { } func (p *Process) CloseStdout(ctx context.Context) (err error) { - ctx, span := oc.StartSpan(ctx, "gcs::Process::CloseStdout") //nolint:ineffassign,staticcheck - defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() - span.AddAttributes( - trace.StringAttribute("cid", p.cid), - trace.Int64Attribute("pid", int64(p.id))) + p.logEntry(ctx).Trace("gcs::Process::CloseStdout") return p.stdout.Close() } func (p *Process) CloseStderr(ctx context.Context) (err error) { - ctx, span := oc.StartSpan(ctx, "gcs::Process::CloseStderr") //nolint:ineffassign,staticcheck - defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() - span.AddAttributes( - trace.StringAttribute("cid", p.cid), - trace.Int64Attribute("pid", int64(p.id))) + p.logEntry(ctx).Trace("gcs::Process::CloseStderr") return p.stderr.Close() } @@ -195,12 +177,7 @@ func (p *Process) ExitCode() (_ int, err error) { // signal was delivered. The process might not be terminated by the time this // returns. func (p *Process) Kill(ctx context.Context) (_ bool, err error) { - ctx, span := oc.StartSpan(ctx, "gcs::Process::Kill") - defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() - span.AddAttributes( - trace.StringAttribute("cid", p.cid), - trace.Int64Attribute("pid", int64(p.id))) + p.logEntry(ctx).Trace("gcs::Process::Kill") return p.Signal(ctx, nil) } @@ -213,12 +190,7 @@ func (p *Process) Pid() int { // ResizeConsole requests that the pty associated with the process resize its // window. func (p *Process) ResizeConsole(ctx context.Context, width, height uint16) (err error) { - ctx, span := oc.StartSpan(ctx, "gcs::Process::ResizeConsole", oc.WithClientSpanKind) - defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() - span.AddAttributes( - trace.StringAttribute("cid", p.cid), - trace.Int64Attribute("pid", int64(p.id))) + p.logEntry(ctx).Trace("gcs::Process::ResizeConsole") req := containerResizeConsole{ requestBase: makeRequest(ctx, p.cid), @@ -232,12 +204,7 @@ func (p *Process) ResizeConsole(ctx context.Context, width, height uint16) (err // Signal sends a signal to the process, returning whether it was delivered. func (p *Process) Signal(ctx context.Context, options interface{}) (_ bool, err error) { - ctx, span := oc.StartSpan(ctx, "gcs::Process::Signal", oc.WithClientSpanKind) - defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() - span.AddAttributes( - trace.StringAttribute("cid", p.cid), - trace.Int64Attribute("pid", int64(p.id))) + p.logEntry(ctx).Trace("gcs::Process::Signal") req := containerSignalProcess{ requestBase: makeRequest(ctx, p.cid), @@ -253,11 +220,7 @@ func (p *Process) Signal(ctx context.Context, options interface{}) (_ bool, err return false, err } if !p.waitCall.Done() { - log.G(ctx).WithFields(logrus.Fields{ - logrus.ErrorKey: err, - logfields.ContainerID: p.cid, - logfields.ProcessID: p.id, - }).Warn("ignoring missing process") + p.logEntry(ctx).WithError(err).Warn("ignoring missing process") } return false, nil } @@ -277,17 +240,23 @@ func (p *Process) Wait() error { } func (p *Process) waitBackground() { - ctx, span := oc.StartSpan(context.Background(), "gcs::Process::waitBackground") + var err error + _, span := oc.StartSpan(context.Background(), "gcs::Process::waitBackground") defer span.End() + defer func() { oc.SetSpanStatus(span, err) }() span.AddAttributes( trace.StringAttribute("cid", p.cid), trace.Int64Attribute("pid", int64(p.id))) p.waitCall.Wait() - ec, err := p.ExitCode() - if err != nil { - log.G(ctx).WithError(err).Error("failed wait") - } - log.G(ctx).WithField("exitCode", ec).Debug("process exited") - oc.SetSpanStatus(span, err) + var ec int + ec, err = p.ExitCode() + span.AddAttributes(trace.Int64Attribute("exitCode", int64(ec))) +} + +func (p *Process) logEntry(ctx context.Context) *logrus.Entry { + return log.G(ctx).WithFields(logrus.Fields{ + logfields.ContainerID: p.cid, + logfields.ProcessID: p.id, + }) } diff --git a/internal/gcs/protocol.go b/internal/gcs/protocol.go index 94e55e4c1e..bebe530748 100644 --- a/internal/gcs/protocol.go +++ b/internal/gcs/protocol.go @@ -137,7 +137,7 @@ func (typ msgType) String() string { } // ocspancontext is the internal JSON representation of the OpenCensus -// `trace.SpanContext` for fowarding to a GCS that supports it. +// `trace.SpanContext` for forwarding to a GCS that supports it. type ocspancontext struct { // TraceID is the `hex` encoded string of the OpenCensus // `SpanContext.TraceID` to propagate to the guest. diff --git a/internal/guest/bridge/bridge.go b/internal/guest/bridge/bridge.go index f17cb2ce4d..f832207608 100644 --- a/internal/guest/bridge/bridge.go +++ b/internal/guest/bridge/bridge.go @@ -27,6 +27,7 @@ import ( "github.com/Microsoft/hcsshim/internal/guest/prot" "github.com/Microsoft/hcsshim/internal/guest/runtime/hcsv2" "github.com/Microsoft/hcsshim/internal/log" + "github.com/Microsoft/hcsshim/internal/logfields" "github.com/Microsoft/hcsshim/internal/oc" ) @@ -270,6 +271,7 @@ func (b *Bridge) ListenAndServe(bridgeIn io.ReadCloser, bridgeOut io.WriteCloser var ctx context.Context var span *trace.Span + spanName := "opengcs::bridge::" + header.Type.String() if base.OpenCensusSpanContext != nil { sc := trace.SpanContext{} if bytes, err := hex.DecodeString(base.OpenCensusSpanContext.TraceID); err == nil { @@ -289,25 +291,15 @@ func (b *Bridge) ListenAndServe(bridgeIn io.ReadCloser, bridgeOut io.WriteCloser } } } - ctx, span = oc.StartSpanWithRemoteParent( - context.Background(), - "opengcs::bridge::request", - sc, - oc.WithServerSpanKind, - ) + ctx, span = oc.StartSpanWithRemoteParent(context.Background(), spanName, sc, oc.WithServerSpanKind) } else { - ctx, span = oc.StartSpan( - context.Background(), - "opengcs::bridge::request", - oc.WithServerSpanKind, - ) + ctx, span = oc.StartSpan(context.Background(), spanName, oc.WithServerSpanKind) } span.AddAttributes( trace.Int64Attribute("message-id", int64(header.ID)), - trace.StringAttribute("message-type", header.Type.String()), trace.StringAttribute("activityID", base.ActivityID), - trace.StringAttribute("cid", base.ContainerID)) + trace.StringAttribute(logfields.ContainerID, base.ContainerID)) entry := log.G(ctx) if entry.Logger.GetLevel() >= logrus.DebugLevel { @@ -382,10 +374,9 @@ func (b *Bridge) ListenAndServe(bridgeIn io.ReadCloser, bridgeOut io.WriteCloser break } - s := trace.FromContext(resp.ctx) - if s != nil { - log.G(resp.ctx).WithField("message", string(responseBytes)).Debug("request write response") - s.End() + log.G(resp.ctx).WithField("message", string(responseBytes)).Debug("request write response") + if span := trace.FromContext(resp.ctx); span != nil { + span.End() } } responseErrChan <- resperr @@ -423,7 +414,7 @@ func (b *Bridge) PublishNotification(n *prot.ContainerNotification) { ctx, span := oc.StartSpan(context.Background(), "opengcs::bridge::PublishNotification", oc.WithClientSpanKind) - span.AddAttributes(trace.StringAttribute("notification", fmt.Sprintf("%+v", n))) + span.AddAttributes(trace.StringAttribute("notification", log.Format(ctx, n))) // DONT defer span.End() here. Publish is odd because bridgeResponse calls // `End` on the `ctx` after the response is sent. diff --git a/internal/guest/bridge/bridge_v2.go b/internal/guest/bridge/bridge_v2.go index f9712abc9d..83d7a49ed7 100644 --- a/internal/guest/bridge/bridge_v2.go +++ b/internal/guest/bridge/bridge_v2.go @@ -10,6 +10,7 @@ import ( "time" "github.com/pkg/errors" + "github.com/sirupsen/logrus" "go.opencensus.io/trace" "golang.org/x/sys/unix" @@ -19,6 +20,7 @@ import ( "github.com/Microsoft/hcsshim/internal/guest/runtime/hcsv2" "github.com/Microsoft/hcsshim/internal/guest/stdio" "github.com/Microsoft/hcsshim/internal/log" + "github.com/Microsoft/hcsshim/internal/logfields" "github.com/Microsoft/hcsshim/internal/oc" "github.com/Microsoft/hcsshim/internal/protocol/guestrequest" ) @@ -46,10 +48,8 @@ var capabilities = prot.GcsCapabilities{ // negotiateProtocolV2 was introduced in v4 so will not be called with a minimum // lower than that. func (b *Bridge) negotiateProtocolV2(r *Request) (_ RequestResponse, err error) { - _, span := oc.StartSpan(r.Context, "opengcs::bridge::negotiateProtocolV2") - defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() - span.AddAttributes(trace.StringAttribute("cid", r.ContainerID)) + ctx := r.Context + log.G(ctx).Trace("opengcs::bridge::createContainerV2") var request prot.NegotiateProtocol if err := commonutils.UnmarshalJSONWithHresult(r.Message, &request); err != nil { @@ -82,10 +82,8 @@ func (b *Bridge) negotiateProtocolV2(r *Request) (_ RequestResponse, err error) // // This is allowed only for protocol version 4+, schema version 2.1+ func (b *Bridge) createContainerV2(r *Request) (_ RequestResponse, err error) { - ctx, span := oc.StartSpan(r.Context, "opengcs::bridge::createContainerV2") - defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() - span.AddAttributes(trace.StringAttribute("cid", r.ContainerID)) + ctx := r.Context + logEntry(ctx, r).Trace("opengcs::bridge::createContainerV2") var request prot.ContainerCreate if err := commonutils.UnmarshalJSONWithHresult(r.Message, &request); err != nil { @@ -135,10 +133,8 @@ func (b *Bridge) createContainerV2(r *Request) (_ RequestResponse, err error) { // // This is allowed only for protocol version 4+, schema version 2.1+ func (b *Bridge) startContainerV2(r *Request) (_ RequestResponse, err error) { - _, span := oc.StartSpan(r.Context, "opengcs::bridge::startContainerV2") - defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() - span.AddAttributes(trace.StringAttribute("cid", r.ContainerID)) + ctx := r.Context + logEntry(ctx, r).Trace("opengcs::bridge::startContainerV2") // This is just a noop, but needs to be handled so that an error isn't // returned to the HCS. @@ -166,10 +162,8 @@ func (b *Bridge) startContainerV2(r *Request) (_ RequestResponse, err error) { // // This is allowed only for protocol version 4+, schema version 2.1+ func (b *Bridge) execProcessV2(r *Request) (_ RequestResponse, err error) { - ctx, span := oc.StartSpan(r.Context, "opengcs::bridge::execProcessV2") - defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() - span.AddAttributes(trace.StringAttribute("cid", r.ContainerID)) + ctx := r.Context + logEntry(ctx, r).Trace("opengcs::bridge::execProcessV2") var request prot.ContainerExecuteProcess if err := commonutils.UnmarshalJSONWithHresult(r.Message, &request); err != nil { @@ -199,7 +193,10 @@ func (b *Bridge) execProcessV2(r *Request) (_ RequestResponse, err error) { if err != nil { return nil, err } - log.G(ctx).WithField("pid", pid).Debug("created process pid") + log.G(ctx).WithFields(logrus.Fields{ + logfields.ContainerID: r.ContainerID, + logfields.ProcessID: pid, + }).Debug("created process pid") return &prot.ContainerExecuteProcessResponse{ ProcessID: uint32(pid), }, nil @@ -211,11 +208,10 @@ func (b *Bridge) execProcessV2(r *Request) (_ RequestResponse, err error) { // // This is allowed only for protocol version 4+, schema version 2.1+ func (b *Bridge) killContainerV2(r *Request) (RequestResponse, error) { - ctx, span := oc.StartSpan(r.Context, "opengcs::bridge::killContainerV2") - defer span.End() - span.AddAttributes(trace.StringAttribute("cid", r.ContainerID)) + ctx := r.Context + logEntry(ctx, r).Trace("opengcs::bridge::killContainerV2") - return b.signalContainerShutdownV2(ctx, span, r, false) + return b.signalContainerShutdownV2(ctx, r, false) } // shutdownContainerV2 is a user requested shutdown of the container and all @@ -224,23 +220,16 @@ func (b *Bridge) killContainerV2(r *Request) (RequestResponse, error) { // // This is allowed only for protocol version 4+, schema version 2.1+ func (b *Bridge) shutdownContainerV2(r *Request) (RequestResponse, error) { - ctx, span := oc.StartSpan(r.Context, "opengcs::bridge::shutdownContainerV2") - defer span.End() - span.AddAttributes(trace.StringAttribute("cid", r.ContainerID)) + ctx := r.Context + logEntry(ctx, r).Trace("opengcs::bridge::shutdownContainerV2") - return b.signalContainerShutdownV2(ctx, span, r, true) + return b.signalContainerShutdownV2(ctx, r, true) } -// signalContainerV2 is not a handler func. It is called from either -// `killContainerV2` or `shutdownContainerV2` to deliver a SIGTERM or SIGKILL -// respectively -func (b *Bridge) signalContainerShutdownV2(ctx context.Context, span *trace.Span, r *Request, graceful bool) (_ RequestResponse, err error) { - defer func() { oc.SetSpanStatus(span, err) }() - span.AddAttributes( - trace.StringAttribute("cid", r.ContainerID), - trace.BoolAttribute("graceful", graceful), - ) - +// signalContainerV2 is not a handler func. This is because the actual signal is +// implied based on the message type of either `killContainerV2` or +// `shutdownContainerV2`. +func (b *Bridge) signalContainerShutdownV2(ctx context.Context, r *Request, graceful bool) (_ RequestResponse, err error) { var request prot.MessageBase if err := commonutils.UnmarshalJSONWithHresult(r.Message, &request); err != nil { return nil, errors.Wrapf(err, "failed to unmarshal JSON in message \"%s\"", r.Message) @@ -248,11 +237,18 @@ func (b *Bridge) signalContainerShutdownV2(ctx context.Context, span *trace.Span // If this is targeting the UVM send the request to the host itself. if request.ContainerID == hcsv2.UVMContainerID { + // no guarantee this will be logged + log.G(ctx).Info("shutting down host") // We are asking to shutdown the UVM itself. // This is a destructive call. We do not respond to the HCS b.quitChan <- true b.hostState.Shutdown() } else { + log.G(ctx).WithFields(logrus.Fields{ + logfields.ContainerID: r.ContainerID, + "gracefull": graceful, + }).Debug("signaling container shutdown") + err = b.hostState.ShutdownContainer(ctx, request.ContainerID, graceful) if err != nil { return nil, err @@ -263,20 +259,14 @@ func (b *Bridge) signalContainerShutdownV2(ctx context.Context, span *trace.Span } func (b *Bridge) signalProcessV2(r *Request) (_ RequestResponse, err error) { - ctx, span := oc.StartSpan(r.Context, "opengcs::bridge::signalProcessV2") - defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() - span.AddAttributes(trace.StringAttribute("cid", r.ContainerID)) + ctx := r.Context + logEntry(ctx, r).Trace("opengcs::bridge::signalProcessV2") var request prot.ContainerSignalProcess if err := commonutils.UnmarshalJSONWithHresult(r.Message, &request); err != nil { return nil, errors.Wrapf(err, "failed to unmarshal JSON in message \"%s\"", r.Message) } - span.AddAttributes( - trace.Int64Attribute("pid", int64(request.ProcessID)), - trace.Int64Attribute("signal", int64(request.Options.Signal))) - var signal syscall.Signal if request.Options.Signal == 0 { signal = unix.SIGKILL @@ -284,6 +274,12 @@ func (b *Bridge) signalProcessV2(r *Request) (_ RequestResponse, err error) { signal = syscall.Signal(request.Options.Signal) } + log.G(ctx).WithFields(logrus.Fields{ + logfields.ContainerID: r.ContainerID, + logfields.ProcessID: request.ProcessID, + "signal": signal, + }).Debug("signaling container") + if err := b.hostState.SignalContainerProcess(ctx, request.ContainerID, request.ProcessID, signal); err != nil { return nil, err } @@ -292,10 +288,8 @@ func (b *Bridge) signalProcessV2(r *Request) (_ RequestResponse, err error) { } func (b *Bridge) getPropertiesV2(r *Request) (_ RequestResponse, err error) { - ctx, span := oc.StartSpan(r.Context, "opengcs::bridge::getPropertiesV2") - defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() - span.AddAttributes(trace.StringAttribute("cid", r.ContainerID)) + ctx := r.Context + logEntry(ctx, r).Trace("opengcs::bridge::getPropertiesV2") var request prot.ContainerGetProperties if err := commonutils.UnmarshalJSONWithHresult(r.Message, &request); err != nil { @@ -389,21 +383,14 @@ func (b *Bridge) waitOnProcessV2(r *Request) (_ RequestResponse, err error) { } func (b *Bridge) resizeConsoleV2(r *Request) (_ RequestResponse, err error) { - ctx, span := oc.StartSpan(r.Context, "opengcs::bridge::resizeConsoleV2") - defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() - span.AddAttributes(trace.StringAttribute("cid", r.ContainerID)) + ctx := r.Context + logEntry(ctx, r).Trace("opengcs::bridge::resizeConsoleV2") var request prot.ContainerResizeConsole if err := commonutils.UnmarshalJSONWithHresult(r.Message, &request); err != nil { return nil, errors.Wrapf(err, "failed to unmarshal JSON in message \"%s\"", r.Message) } - span.AddAttributes( - trace.Int64Attribute("pid", int64(request.ProcessID)), - trace.Int64Attribute("height", int64(request.Height)), - trace.Int64Attribute("width", int64(request.Width))) - c, err := b.hostState.GetCreatedContainer(request.ContainerID) if err != nil { return nil, err @@ -414,6 +401,12 @@ func (b *Bridge) resizeConsoleV2(r *Request) (_ RequestResponse, err error) { return nil, err } + log.G(ctx).WithFields(logrus.Fields{ + logfields.ContainerID: r.ContainerID, + logfields.ProcessID: request.ProcessID, + "height": request.Height, + "width": request.Width, + }).Debug("resizing console") err = p.ResizeConsole(ctx, request.Height, request.Width) if err != nil { return nil, err @@ -423,10 +416,8 @@ func (b *Bridge) resizeConsoleV2(r *Request) (_ RequestResponse, err error) { } func (b *Bridge) modifySettingsV2(r *Request) (_ RequestResponse, err error) { - ctx, span := oc.StartSpan(r.Context, "opengcs::bridge::modifySettingsV2") - defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() - span.AddAttributes(trace.StringAttribute("cid", r.ContainerID)) + ctx := r.Context + logEntry(ctx, r).Trace("opengcs::bridge::modifySettingsV2") request, err := prot.UnmarshalContainerModifySettings(r.Message) if err != nil { @@ -442,9 +433,8 @@ func (b *Bridge) modifySettingsV2(r *Request) (_ RequestResponse, err error) { } func (b *Bridge) dumpStacksV2(r *Request) (_ RequestResponse, err error) { - ctx, span := oc.StartSpan(r.Context, "opengcs::bridge::dumpStacksV2") - defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() + ctx := r.Context + log.G(ctx).Trace("opengcs::bridge::dumpStacksV2") stacks, err := b.hostState.GetStacks(ctx) if err != nil { @@ -456,11 +446,8 @@ func (b *Bridge) dumpStacksV2(r *Request) (_ RequestResponse, err error) { } func (b *Bridge) deleteContainerStateV2(r *Request) (_ RequestResponse, err error) { - ctx, span := oc.StartSpan(r.Context, "opengcs::bridge::deleteContainerStateV2") - defer span.End() - defer func() { oc.SetSpanStatus(span, err) }() - - span.AddAttributes(trace.StringAttribute("cid", r.ContainerID)) + ctx := r.Context + logEntry(ctx, r).Trace("opengcs::bridge::deleteContainerStateV2") var request prot.MessageBase if err := commonutils.UnmarshalJSONWithHresult(r.Message, &request); err != nil { @@ -480,3 +467,7 @@ func (b *Bridge) deleteContainerStateV2(r *Request) (_ RequestResponse, err erro return &prot.MessageResponseBase{}, nil } + +func logEntry(ctx context.Context, r *Request) *logrus.Entry { + return log.G(ctx).WithField(logfields.ContainerID, r.ContainerID) +} diff --git a/internal/logfields/fields.go b/internal/logfields/fields.go index cceb3e2d18..6d2babe405 100644 --- a/internal/logfields/fields.go +++ b/internal/logfields/fields.go @@ -15,6 +15,10 @@ const ( TaskID = "tid" UVMID = "uvm-id" + // shim service specific + ShimID = "shim-id" + IsSandbox = "is-sandbox" + // networking and IO File = "file" diff --git a/pkg/octtrpc/interceptor.go b/pkg/octtrpc/interceptor.go index 673b29b5a6..52ce61e94e 100644 --- a/pkg/octtrpc/interceptor.go +++ b/pkg/octtrpc/interceptor.go @@ -11,11 +11,13 @@ import ( "google.golang.org/grpc/codes" "google.golang.org/grpc/status" + "github.com/Microsoft/hcsshim/internal/log" "github.com/Microsoft/hcsshim/internal/oc" ) type options struct { sampler trace.Sampler + attrs []trace.Attribute } // Option represents an option function that can be used with the OC TTRPC @@ -30,6 +32,13 @@ func WithSampler(sampler trace.Sampler) Option { } } +// WithAttributes specifies additional attributes to add to spans created by the interceptor. +func WithAttributes(attr ...trace.Attribute) Option { + return func(opts *options) { + opts.attrs = append(opts.attrs, attr...) + } +} + const metadataTraceContextKey = "octtrpc.tracecontext" func convertMethodName(name string) string { @@ -70,6 +79,7 @@ func ClientInterceptor(opts ...Option) ttrpc.UnaryClientInterceptor { for _, opt := range opts { opt(&o) } + return func(ctx context.Context, req *ttrpc.Request, resp *ttrpc.Response, info *ttrpc.UnaryClientInfo, inv ttrpc.Invoker) (err error) { ctx, span := oc.StartSpan( ctx, @@ -78,6 +88,9 @@ func ClientInterceptor(opts ...Option) ttrpc.UnaryClientInterceptor { oc.WithClientSpanKind) defer span.End() defer setSpanStatus(span, err) + if len(o.attrs) > 0 { + span.AddAttributes(o.attrs...) + } spanContextBinary := propagation.Binary(span.SpanContext()) b64 := base64.StdEncoding.EncodeToString(spanContextBinary) @@ -98,20 +111,33 @@ func ServerInterceptor(opts ...Option) ttrpc.UnaryServerInterceptor { for _, opt := range opts { opt(&o) } - return func(ctx context.Context, unmarshal ttrpc.Unmarshaler, info *ttrpc.UnaryServerInfo, method ttrpc.Method) (_ interface{}, err error) { + + return func(ctx context.Context, unmarshal ttrpc.Unmarshaler, info *ttrpc.UnaryServerInfo, method ttrpc.Method) (resp interface{}, err error) { name := convertMethodName(info.FullMethod) var span *trace.Span opts := []trace.StartOption{trace.WithSampler(o.sampler), oc.WithServerSpanKind} - parent, ok := getParentSpanFromContext(ctx) - if ok { + if parent, ok := getParentSpanFromContext(ctx); ok { ctx, span = oc.StartSpanWithRemoteParent(ctx, name, parent, opts...) } else { ctx, span = oc.StartSpan(ctx, name, opts...) } defer span.End() - defer setSpanStatus(span, err) + defer func() { + if err == nil { + span.AddAttributes(trace.StringAttribute("response", log.Format(ctx, resp))) + } + setSpanStatus(span, err) + }() + if len(o.attrs) > 0 { + span.AddAttributes(o.attrs...) + } - return method(ctx, unmarshal) + return method(ctx, func(req interface{}) (err error) { + if err = unmarshal(req); err == nil { + span.AddAttributes(trace.StringAttribute("request", log.Format(ctx, req))) + } + return err + }) } } From d455f6dad794f3f6553965fdd52e56aed60083bb Mon Sep 17 00:00:00 2001 From: Hamza El-Saawy Date: Wed, 2 Aug 2023 16:46:59 -0400 Subject: [PATCH 2/2] Add scrubbing to octtrpc Allow enabling adding the request/response to the ttrpc span as attributes, since there are other customers of our code. Allow scrubbing the `proto.Message` request and response messages in the ttrpc server interceptor by specifying an arbitrary function to update a clone of the payloads. Signed-off-by: Hamza El-Saawy --- cmd/containerd-shim-runhcs-v1/exec_hcs.go | 2 +- cmd/containerd-shim-runhcs-v1/serve.go | 8 +- cmd/containerd-shim-runhcs-v1/service.go | 3 + internal/gcs/bridge.go | 4 +- internal/guest/bridge/bridge.go | 2 +- internal/guest/network/netns.go | 2 +- internal/log/format.go | 3 +- internal/log/scrub.go | 27 +- pkg/octtrpc/interceptor.go | 58 +- .../types/known/wrapperspb/wrappers.pb.go | 760 ++++++++++++++++++ vendor/modules.txt | 1 + 11 files changed, 854 insertions(+), 16 deletions(-) create mode 100644 vendor/google.golang.org/protobuf/types/known/wrapperspb/wrappers.pb.go diff --git a/cmd/containerd-shim-runhcs-v1/exec_hcs.go b/cmd/containerd-shim-runhcs-v1/exec_hcs.go index 5ac5cfa947..c3553898b0 100644 --- a/cmd/containerd-shim-runhcs-v1/exec_hcs.go +++ b/cmd/containerd-shim-runhcs-v1/exec_hcs.go @@ -517,7 +517,7 @@ func (he *hcsExec) waitForContainerExit() { trace.StringAttribute("tid", he.tid), trace.StringAttribute("eid", he.id)) - // wait for container or process to exit and ckean up resrources + // wait for container or process to exit and clean up resources select { case <-he.c.WaitChannel(): // Container exited first. We need to force the process into the exited diff --git a/cmd/containerd-shim-runhcs-v1/serve.go b/cmd/containerd-shim-runhcs-v1/serve.go index 4a966a4c41..5f227ea389 100644 --- a/cmd/containerd-shim-runhcs-v1/serve.go +++ b/cmd/containerd-shim-runhcs-v1/serve.go @@ -118,7 +118,7 @@ var serveCommand = cli.Command{ // TODO: JTERRY75 we need this to be the reconnect log listener or // switch to events // TODO: JTERRY75 switch containerd to use the protected path. - //const logAddrFmt = "\\\\.\\pipe\\ProtectedPrefix\\Administrators\\containerd-shim-%s-%s-log" + // const logAddrFmt = "\\\\.\\pipe\\ProtectedPrefix\\Administrators\\containerd-shim-%s-%s-log" const logAddrFmt = "\\\\.\\pipe\\containerd-shim-%s-%s-log" logl, err := winio.ListenPipe(fmt.Sprintf(logAddrFmt, namespaceFlag, idFlag), nil) if err != nil { @@ -197,10 +197,12 @@ var serveCommand = cli.Command{ s, err := ttrpc.NewServer( ttrpc.WithUnaryServerInterceptor(octtrpc.ServerInterceptor( - octtrpc.WithAttributes( // todo (helsaawy) set these in resource when we switch to OTel + octtrpc.WithAttributes( // TODO (helsaawy) set these in resource when we switch to OTel trace.StringAttribute(logfields.ShimID, svc.tid), trace.BoolAttribute(logfields.IsSandbox, svc.isSandbox), ), + octtrpc.WithAddMessage(), + octtrpc.WithAddMessageHook(hcslog.ScrubShimTTRPC), ))) if err != nil { return err @@ -318,7 +320,7 @@ func createEvent(event string) (windows.Handle, error) { } // setupDebuggerEvent listens for an event to allow a debugger such as delve -// to attach for advanced debugging. It's called when handling a ContainerCreate +// to attach for advanced debugging. It's called when handling a ContainerCreate. func setupDebuggerEvent() { if os.Getenv("CONTAINERD_SHIM_RUNHCS_V1_WAIT_DEBUGGER") == "" { return diff --git a/cmd/containerd-shim-runhcs-v1/service.go b/cmd/containerd-shim-runhcs-v1/service.go index 36540a682b..ff1e272734 100644 --- a/cmd/containerd-shim-runhcs-v1/service.go +++ b/cmd/containerd-shim-runhcs-v1/service.go @@ -294,6 +294,9 @@ func (s *service) IsShutdown() bool { } func (s *service) logEntry(ctx context.Context) *logrus.Entry { + if s == nil { + return log.G(ctx) + } return log.G(ctx).WithFields(logrus.Fields{ logfields.ShimID: s.tid, logfields.IsSandbox: s.isSandbox, diff --git a/internal/gcs/bridge.go b/internal/gcs/bridge.go index fe6360dcaa..b9d25c7a82 100644 --- a/internal/gcs/bridge.go +++ b/internal/gcs/bridge.go @@ -244,7 +244,7 @@ func (brdg *bridge) RPC(ctx context.Context, proc rpcProc, req requestMessage, r brdg.log.WithField("reason", ctx.Err()).Warn("ignoring response to bridge message") return ctx.Err() case <-t.C: - //todo: dont kill bridge on message timeout + // TODO: don't kill bridge on message timeout brdg.kill(errors.New("message timeout")) <-call.ch return call.Err() @@ -390,7 +390,7 @@ func (brdg *bridge) writeMessage(buf *bytes.Buffer, enc *json.Encoder, typ msgTy // Update the message header with the size. binary.LittleEndian.PutUint32(buf.Bytes()[hdrOffSize:], uint32(buf.Len())) - if brdg.log.Logger.GetLevel() >= logrus.DebugLevel { + if brdg.log.Logger.IsLevelEnabled(logrus.DebugLevel) { b := buf.Bytes()[hdrSize:] switch typ { // container environment vars are in rpCreate for linux; rpcExecuteProcess for windows diff --git a/internal/guest/bridge/bridge.go b/internal/guest/bridge/bridge.go index f832207608..16cdb63ad6 100644 --- a/internal/guest/bridge/bridge.go +++ b/internal/guest/bridge/bridge.go @@ -302,7 +302,7 @@ func (b *Bridge) ListenAndServe(bridgeIn io.ReadCloser, bridgeOut io.WriteCloser trace.StringAttribute(logfields.ContainerID, base.ContainerID)) entry := log.G(ctx) - if entry.Logger.GetLevel() >= logrus.DebugLevel { + if entry.Logger.IsLevelEnabled(logrus.DebugLevel) { s := string(message) switch header.Type { case prot.ComputeSystemCreateV1: diff --git a/internal/guest/network/netns.go b/internal/guest/network/netns.go index e414e5e320..bbab05155a 100644 --- a/internal/guest/network/netns.go +++ b/internal/guest/network/netns.go @@ -168,7 +168,7 @@ func NetNSConfig(ctx context.Context, ifStr string, nsPid int, adapter *prot.Net } // Add some debug logging - if entry.Logger.GetLevel() >= logrus.DebugLevel { + if entry.Logger.IsLevelEnabled(logrus.DebugLevel) { curNS, _ := netns.Get() // Refresh link attributes/state link, _ = netlink.LinkByIndex(link.Attrs().Index) diff --git a/internal/log/format.go b/internal/log/format.go index 1ceb26bada..5608082a45 100644 --- a/internal/log/format.go +++ b/internal/log/format.go @@ -65,7 +65,7 @@ func formatAddr(a net.Addr) string { func Format(ctx context.Context, v interface{}) string { b, err := encode(v) if err != nil { - // logging errors aren't really warning worthy, and can potentially spam a lot of logs out + // logging-related errors aren't really warning worthy, and can potentially spam a lot of logs out G(ctx).WithFields(logrus.Fields{ logrus.ErrorKey: err, "type": fmt.Sprintf("%T", v), @@ -93,7 +93,6 @@ func encode(v interface{}) (_ []byte, err error) { // more robust to fall back on json marshalling for errors in general return b, nil } - } buf := &bytes.Buffer{} diff --git a/internal/log/scrub.go b/internal/log/scrub.go index 5a960e0d35..53220a132c 100644 --- a/internal/log/scrub.go +++ b/internal/log/scrub.go @@ -6,6 +6,11 @@ import ( "errors" "sync/atomic" + task "github.com/containerd/containerd/api/runtime/task/v2" + "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/types/known/anypb" + "google.golang.org/protobuf/types/known/wrapperspb" + hcsschema "github.com/Microsoft/hcsshim/internal/hcs/schema2" ) @@ -22,6 +27,7 @@ var ( // case sensitive keywords, so "env" is not a substring on "Environment" _scrubKeywords = [][]byte{[]byte("env"), []byte("Environment")} + // TODO (go1.19) atomic.Bool _scrub int32 ) @@ -40,8 +46,27 @@ func IsScrubbingEnabled() bool { return v != 0 } +func ScrubShimTTRPC(m proto.Message) { + if !IsScrubbingEnabled() { + return + } + + switch t := m.(type) { + case *task.ExecProcessRequest: + // the spec will be logged elsewhere, so scrub the entire spec wholesale to avoid + // needing to unmarshall from then re-marshal back to an anypb.Any + // + // ignore errors with creating an anypb.Any and use nil response since nil is a + // "valid" proto.Message that it signifies an invlaid message + // see comment here: https://pkg.go.dev/google.golang.org/protobuf@v1.31.0/proto#Equal + a, _ := anypb.New(wrapperspb.String(_scrubbedReplacement)) + t.Spec = a + default: + } +} + // ScrubProcessParameters scrubs HCS Create Process requests with config parameters of -// type internal/hcs/schema2.ScrubProcessParameters (aka hcsshema.ScrubProcessParameters) +// type internal/hcs/schema2.ScrubProcessParameters (aka hcsschema.ScrubProcessParameters) func ScrubProcessParameters(s string) (string, error) { // todo: deal with v1 ProcessConfig b := []byte(s) diff --git a/pkg/octtrpc/interceptor.go b/pkg/octtrpc/interceptor.go index 52ce61e94e..6d81b271a4 100644 --- a/pkg/octtrpc/interceptor.go +++ b/pkg/octtrpc/interceptor.go @@ -10,6 +10,7 @@ import ( "go.opencensus.io/trace/propagation" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" + "google.golang.org/protobuf/proto" "github.com/Microsoft/hcsshim/internal/log" "github.com/Microsoft/hcsshim/internal/oc" @@ -18,6 +19,21 @@ import ( type options struct { sampler trace.Sampler attrs []trace.Attribute + // add the request/response messages as span attributes + addMsg bool + // hook to update/modify a copy of the request/response messages before adding them as span attributes + msgAttrHook func(proto.Message) +} + +func (o *options) msgHook(v any) any { + m, ok := v.(proto.Message) + if !ok || o.msgAttrHook == nil { + return v + } + + m = proto.Clone(m) + o.msgAttrHook(m) + return m } // Option represents an option function that can be used with the OC TTRPC @@ -39,6 +55,37 @@ func WithAttributes(attr ...trace.Attribute) Option { } } +// these are (currently) ServerInterceptor-specific options, but we cannot create a new [ServerOption] type +// since that would break our API + +// WithAddMessage adds the request and response messages as attributes to the ttrpc method span. +// +// [ServerInterceptor] only. +func WithAddMessage() Option { + return func(opts *options) { + opts.addMsg = true + } +} + +// WithAddMessageHook specifies a hook to modify the ttrpc request or response messages +// before adding them to the ttrpc method span. +// This is intended to allow scrubbing sensitive fields from a the message. +// +// The function will be called with a clone of the original message (via [proto.Clone]) only if: +// - the interceptor is created with the [WithAddMessage] option +// - the function is non-nil +// - the ttrpc request or response are of type [proto.Message] +// +// Since ttrpc is a gRPC replacement, we are guaranteed that the messages will +// implement [proto.Message]. +// +// [ServerInterceptor] only. +func WithAddMessageHook(f func(proto.Message)) Option { + return func(opts *options) { + opts.msgAttrHook = f + } +} + const metadataTraceContextKey = "octtrpc.tracecontext" func convertMethodName(name string) string { @@ -124,8 +171,8 @@ func ServerInterceptor(opts ...Option) ttrpc.UnaryServerInterceptor { } defer span.End() defer func() { - if err == nil { - span.AddAttributes(trace.StringAttribute("response", log.Format(ctx, resp))) + if o.addMsg && err == nil { + span.AddAttributes(trace.StringAttribute("response", log.Format(ctx, o.msgHook(resp)))) } setSpanStatus(span, err) }() @@ -133,9 +180,10 @@ func ServerInterceptor(opts ...Option) ttrpc.UnaryServerInterceptor { span.AddAttributes(o.attrs...) } - return method(ctx, func(req interface{}) (err error) { - if err = unmarshal(req); err == nil { - span.AddAttributes(trace.StringAttribute("request", log.Format(ctx, req))) + return method(ctx, func(req interface{}) error { + err := unmarshal(req) + if o.addMsg { + span.AddAttributes(trace.StringAttribute("request", log.Format(ctx, o.msgHook(req)))) } return err }) diff --git a/vendor/google.golang.org/protobuf/types/known/wrapperspb/wrappers.pb.go b/vendor/google.golang.org/protobuf/types/known/wrapperspb/wrappers.pb.go new file mode 100644 index 0000000000..762a87130f --- /dev/null +++ b/vendor/google.golang.org/protobuf/types/known/wrapperspb/wrappers.pb.go @@ -0,0 +1,760 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Wrappers for primitive (non-message) types. These types are useful +// for embedding primitives in the `google.protobuf.Any` type and for places +// where we need to distinguish between the absence of a primitive +// typed field and its default value. +// +// These wrappers have no meaningful use within repeated fields as they lack +// the ability to detect presence on individual elements. +// These wrappers have no meaningful use within a map or a oneof since +// individual entries of a map or fields of a oneof can already detect presence. + +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: google/protobuf/wrappers.proto + +package wrapperspb + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +// Wrapper message for `double`. +// +// The JSON representation for `DoubleValue` is JSON number. +type DoubleValue struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The double value. + Value float64 `protobuf:"fixed64,1,opt,name=value,proto3" json:"value,omitempty"` +} + +// Double stores v in a new DoubleValue and returns a pointer to it. +func Double(v float64) *DoubleValue { + return &DoubleValue{Value: v} +} + +func (x *DoubleValue) Reset() { + *x = DoubleValue{} + if protoimpl.UnsafeEnabled { + mi := &file_google_protobuf_wrappers_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DoubleValue) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DoubleValue) ProtoMessage() {} + +func (x *DoubleValue) ProtoReflect() protoreflect.Message { + mi := &file_google_protobuf_wrappers_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DoubleValue.ProtoReflect.Descriptor instead. +func (*DoubleValue) Descriptor() ([]byte, []int) { + return file_google_protobuf_wrappers_proto_rawDescGZIP(), []int{0} +} + +func (x *DoubleValue) GetValue() float64 { + if x != nil { + return x.Value + } + return 0 +} + +// Wrapper message for `float`. +// +// The JSON representation for `FloatValue` is JSON number. +type FloatValue struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The float value. + Value float32 `protobuf:"fixed32,1,opt,name=value,proto3" json:"value,omitempty"` +} + +// Float stores v in a new FloatValue and returns a pointer to it. +func Float(v float32) *FloatValue { + return &FloatValue{Value: v} +} + +func (x *FloatValue) Reset() { + *x = FloatValue{} + if protoimpl.UnsafeEnabled { + mi := &file_google_protobuf_wrappers_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *FloatValue) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FloatValue) ProtoMessage() {} + +func (x *FloatValue) ProtoReflect() protoreflect.Message { + mi := &file_google_protobuf_wrappers_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use FloatValue.ProtoReflect.Descriptor instead. +func (*FloatValue) Descriptor() ([]byte, []int) { + return file_google_protobuf_wrappers_proto_rawDescGZIP(), []int{1} +} + +func (x *FloatValue) GetValue() float32 { + if x != nil { + return x.Value + } + return 0 +} + +// Wrapper message for `int64`. +// +// The JSON representation for `Int64Value` is JSON string. +type Int64Value struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The int64 value. + Value int64 `protobuf:"varint,1,opt,name=value,proto3" json:"value,omitempty"` +} + +// Int64 stores v in a new Int64Value and returns a pointer to it. +func Int64(v int64) *Int64Value { + return &Int64Value{Value: v} +} + +func (x *Int64Value) Reset() { + *x = Int64Value{} + if protoimpl.UnsafeEnabled { + mi := &file_google_protobuf_wrappers_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Int64Value) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Int64Value) ProtoMessage() {} + +func (x *Int64Value) ProtoReflect() protoreflect.Message { + mi := &file_google_protobuf_wrappers_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Int64Value.ProtoReflect.Descriptor instead. +func (*Int64Value) Descriptor() ([]byte, []int) { + return file_google_protobuf_wrappers_proto_rawDescGZIP(), []int{2} +} + +func (x *Int64Value) GetValue() int64 { + if x != nil { + return x.Value + } + return 0 +} + +// Wrapper message for `uint64`. +// +// The JSON representation for `UInt64Value` is JSON string. +type UInt64Value struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The uint64 value. + Value uint64 `protobuf:"varint,1,opt,name=value,proto3" json:"value,omitempty"` +} + +// UInt64 stores v in a new UInt64Value and returns a pointer to it. +func UInt64(v uint64) *UInt64Value { + return &UInt64Value{Value: v} +} + +func (x *UInt64Value) Reset() { + *x = UInt64Value{} + if protoimpl.UnsafeEnabled { + mi := &file_google_protobuf_wrappers_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UInt64Value) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UInt64Value) ProtoMessage() {} + +func (x *UInt64Value) ProtoReflect() protoreflect.Message { + mi := &file_google_protobuf_wrappers_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UInt64Value.ProtoReflect.Descriptor instead. +func (*UInt64Value) Descriptor() ([]byte, []int) { + return file_google_protobuf_wrappers_proto_rawDescGZIP(), []int{3} +} + +func (x *UInt64Value) GetValue() uint64 { + if x != nil { + return x.Value + } + return 0 +} + +// Wrapper message for `int32`. +// +// The JSON representation for `Int32Value` is JSON number. +type Int32Value struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The int32 value. + Value int32 `protobuf:"varint,1,opt,name=value,proto3" json:"value,omitempty"` +} + +// Int32 stores v in a new Int32Value and returns a pointer to it. +func Int32(v int32) *Int32Value { + return &Int32Value{Value: v} +} + +func (x *Int32Value) Reset() { + *x = Int32Value{} + if protoimpl.UnsafeEnabled { + mi := &file_google_protobuf_wrappers_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Int32Value) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Int32Value) ProtoMessage() {} + +func (x *Int32Value) ProtoReflect() protoreflect.Message { + mi := &file_google_protobuf_wrappers_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Int32Value.ProtoReflect.Descriptor instead. +func (*Int32Value) Descriptor() ([]byte, []int) { + return file_google_protobuf_wrappers_proto_rawDescGZIP(), []int{4} +} + +func (x *Int32Value) GetValue() int32 { + if x != nil { + return x.Value + } + return 0 +} + +// Wrapper message for `uint32`. +// +// The JSON representation for `UInt32Value` is JSON number. +type UInt32Value struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The uint32 value. + Value uint32 `protobuf:"varint,1,opt,name=value,proto3" json:"value,omitempty"` +} + +// UInt32 stores v in a new UInt32Value and returns a pointer to it. +func UInt32(v uint32) *UInt32Value { + return &UInt32Value{Value: v} +} + +func (x *UInt32Value) Reset() { + *x = UInt32Value{} + if protoimpl.UnsafeEnabled { + mi := &file_google_protobuf_wrappers_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UInt32Value) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UInt32Value) ProtoMessage() {} + +func (x *UInt32Value) ProtoReflect() protoreflect.Message { + mi := &file_google_protobuf_wrappers_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UInt32Value.ProtoReflect.Descriptor instead. +func (*UInt32Value) Descriptor() ([]byte, []int) { + return file_google_protobuf_wrappers_proto_rawDescGZIP(), []int{5} +} + +func (x *UInt32Value) GetValue() uint32 { + if x != nil { + return x.Value + } + return 0 +} + +// Wrapper message for `bool`. +// +// The JSON representation for `BoolValue` is JSON `true` and `false`. +type BoolValue struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The bool value. + Value bool `protobuf:"varint,1,opt,name=value,proto3" json:"value,omitempty"` +} + +// Bool stores v in a new BoolValue and returns a pointer to it. +func Bool(v bool) *BoolValue { + return &BoolValue{Value: v} +} + +func (x *BoolValue) Reset() { + *x = BoolValue{} + if protoimpl.UnsafeEnabled { + mi := &file_google_protobuf_wrappers_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *BoolValue) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BoolValue) ProtoMessage() {} + +func (x *BoolValue) ProtoReflect() protoreflect.Message { + mi := &file_google_protobuf_wrappers_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use BoolValue.ProtoReflect.Descriptor instead. +func (*BoolValue) Descriptor() ([]byte, []int) { + return file_google_protobuf_wrappers_proto_rawDescGZIP(), []int{6} +} + +func (x *BoolValue) GetValue() bool { + if x != nil { + return x.Value + } + return false +} + +// Wrapper message for `string`. +// +// The JSON representation for `StringValue` is JSON string. +type StringValue struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The string value. + Value string `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty"` +} + +// String stores v in a new StringValue and returns a pointer to it. +func String(v string) *StringValue { + return &StringValue{Value: v} +} + +func (x *StringValue) Reset() { + *x = StringValue{} + if protoimpl.UnsafeEnabled { + mi := &file_google_protobuf_wrappers_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *StringValue) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*StringValue) ProtoMessage() {} + +func (x *StringValue) ProtoReflect() protoreflect.Message { + mi := &file_google_protobuf_wrappers_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use StringValue.ProtoReflect.Descriptor instead. +func (*StringValue) Descriptor() ([]byte, []int) { + return file_google_protobuf_wrappers_proto_rawDescGZIP(), []int{7} +} + +func (x *StringValue) GetValue() string { + if x != nil { + return x.Value + } + return "" +} + +// Wrapper message for `bytes`. +// +// The JSON representation for `BytesValue` is JSON string. +type BytesValue struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The bytes value. + Value []byte `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty"` +} + +// Bytes stores v in a new BytesValue and returns a pointer to it. +func Bytes(v []byte) *BytesValue { + return &BytesValue{Value: v} +} + +func (x *BytesValue) Reset() { + *x = BytesValue{} + if protoimpl.UnsafeEnabled { + mi := &file_google_protobuf_wrappers_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *BytesValue) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BytesValue) ProtoMessage() {} + +func (x *BytesValue) ProtoReflect() protoreflect.Message { + mi := &file_google_protobuf_wrappers_proto_msgTypes[8] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use BytesValue.ProtoReflect.Descriptor instead. +func (*BytesValue) Descriptor() ([]byte, []int) { + return file_google_protobuf_wrappers_proto_rawDescGZIP(), []int{8} +} + +func (x *BytesValue) GetValue() []byte { + if x != nil { + return x.Value + } + return nil +} + +var File_google_protobuf_wrappers_proto protoreflect.FileDescriptor + +var file_google_protobuf_wrappers_proto_rawDesc = []byte{ + 0x0a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2f, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x12, 0x0f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x22, 0x23, 0x0a, 0x0b, 0x44, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, + 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x01, 0x52, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x22, 0x0a, 0x0a, 0x46, 0x6c, 0x6f, 0x61, 0x74, 0x56, + 0x61, 0x6c, 0x75, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x02, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x22, 0x0a, 0x0a, 0x49, 0x6e, + 0x74, 0x36, 0x34, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x23, + 0x0a, 0x0b, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x14, 0x0a, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x22, 0x22, 0x0a, 0x0a, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, + 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, + 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x23, 0x0a, 0x0b, 0x55, 0x49, 0x6e, 0x74, 0x33, + 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x21, 0x0a, 0x09, + 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, + 0x23, 0x0a, 0x0b, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x14, + 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x22, 0x22, 0x0a, 0x0a, 0x42, 0x79, 0x74, 0x65, 0x73, 0x56, 0x61, 0x6c, + 0x75, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x83, 0x01, 0x0a, 0x13, 0x63, 0x6f, 0x6d, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x42, 0x0d, 0x57, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, + 0x01, 0x5a, 0x31, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, + 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x79, + 0x70, 0x65, 0x73, 0x2f, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x2f, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, + 0x72, 0x73, 0x70, 0x62, 0xf8, 0x01, 0x01, 0xa2, 0x02, 0x03, 0x47, 0x50, 0x42, 0xaa, 0x02, 0x1e, + 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, + 0x57, 0x65, 0x6c, 0x6c, 0x4b, 0x6e, 0x6f, 0x77, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x73, 0x62, 0x06, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_google_protobuf_wrappers_proto_rawDescOnce sync.Once + file_google_protobuf_wrappers_proto_rawDescData = file_google_protobuf_wrappers_proto_rawDesc +) + +func file_google_protobuf_wrappers_proto_rawDescGZIP() []byte { + file_google_protobuf_wrappers_proto_rawDescOnce.Do(func() { + file_google_protobuf_wrappers_proto_rawDescData = protoimpl.X.CompressGZIP(file_google_protobuf_wrappers_proto_rawDescData) + }) + return file_google_protobuf_wrappers_proto_rawDescData +} + +var file_google_protobuf_wrappers_proto_msgTypes = make([]protoimpl.MessageInfo, 9) +var file_google_protobuf_wrappers_proto_goTypes = []interface{}{ + (*DoubleValue)(nil), // 0: google.protobuf.DoubleValue + (*FloatValue)(nil), // 1: google.protobuf.FloatValue + (*Int64Value)(nil), // 2: google.protobuf.Int64Value + (*UInt64Value)(nil), // 3: google.protobuf.UInt64Value + (*Int32Value)(nil), // 4: google.protobuf.Int32Value + (*UInt32Value)(nil), // 5: google.protobuf.UInt32Value + (*BoolValue)(nil), // 6: google.protobuf.BoolValue + (*StringValue)(nil), // 7: google.protobuf.StringValue + (*BytesValue)(nil), // 8: google.protobuf.BytesValue +} +var file_google_protobuf_wrappers_proto_depIdxs = []int32{ + 0, // [0:0] is the sub-list for method output_type + 0, // [0:0] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_google_protobuf_wrappers_proto_init() } +func file_google_protobuf_wrappers_proto_init() { + if File_google_protobuf_wrappers_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_google_protobuf_wrappers_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DoubleValue); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_google_protobuf_wrappers_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*FloatValue); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_google_protobuf_wrappers_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Int64Value); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_google_protobuf_wrappers_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UInt64Value); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_google_protobuf_wrappers_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Int32Value); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_google_protobuf_wrappers_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UInt32Value); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_google_protobuf_wrappers_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*BoolValue); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_google_protobuf_wrappers_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*StringValue); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_google_protobuf_wrappers_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*BytesValue); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_google_protobuf_wrappers_proto_rawDesc, + NumEnums: 0, + NumMessages: 9, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_google_protobuf_wrappers_proto_goTypes, + DependencyIndexes: file_google_protobuf_wrappers_proto_depIdxs, + MessageInfos: file_google_protobuf_wrappers_proto_msgTypes, + }.Build() + File_google_protobuf_wrappers_proto = out.File + file_google_protobuf_wrappers_proto_rawDesc = nil + file_google_protobuf_wrappers_proto_goTypes = nil + file_google_protobuf_wrappers_proto_depIdxs = nil +} diff --git a/vendor/modules.txt b/vendor/modules.txt index 83a6d9f17c..904d7a645f 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -614,6 +614,7 @@ google.golang.org/protobuf/types/known/emptypb google.golang.org/protobuf/types/known/fieldmaskpb google.golang.org/protobuf/types/known/structpb google.golang.org/protobuf/types/known/timestamppb +google.golang.org/protobuf/types/known/wrapperspb google.golang.org/protobuf/types/pluginpb # gopkg.in/yaml.v2 v2.4.0 ## explicit; go 1.15