From bcfacf71aee479b07fe89fa0a6eaff03a27787f6 Mon Sep 17 00:00:00 2001 From: Danielle Maywood Date: Tue, 17 Sep 2024 11:14:01 +0000 Subject: [PATCH 01/56] feat: begin impl of agent script timings --- agent/agent.go | 4 + agent/agentscripts/agentscripts.go | 13 + agent/agentscripts/timings.go | 23 + agent/proto/agent.pb.go | 1125 ++++++++++------- agent/proto/agent.proto | 16 + agent/proto/agent_drpc.pb.go | 42 +- coderd/agentapi/api.go | 5 + coderd/agentapi/manifest.go | 1 + coderd/agentapi/scripts.go | 28 + coderd/database/dbauthz/dbauthz.go | 6 + coderd/database/dbmem/dbmem.go | 22 + coderd/database/dbmetrics/dbmetrics.go | 7 + coderd/database/dbmock/dbmock.go | 15 + coderd/database/dump.sql | 10 +- ...50_workspace_agent_script_timings.down.sql | 3 + ...0250_workspace_agent_script_timings.up.sql | 9 + coderd/database/models.go | 8 + coderd/database/querier.go | 1 + coderd/database/queries.sql.go | 49 +- coderd/database/queries/workspaceagents.sql | 11 + coderd/database/queries/workspacescripts.sql | 5 +- .../provisionerdserver/provisionerdserver.go | 3 + coderd/workspaceagents.go | 1 + codersdk/agentsdk/convert.go | 2 + codersdk/workspaceagents.go | 1 + site/src/api/typesGenerated.ts | 1 + site/src/testHelpers/entities.ts | 1 + 27 files changed, 960 insertions(+), 452 deletions(-) create mode 100644 agent/agentscripts/timings.go create mode 100644 coderd/agentapi/scripts.go create mode 100644 coderd/database/migrations/000250_workspace_agent_script_timings.down.sql create mode 100644 coderd/database/migrations/000250_workspace_agent_script_timings.up.sql diff --git a/agent/agent.go b/agent/agent.go index 2194e04dd1820..96c217d37e5d5 100644 --- a/agent/agent.go +++ b/agent/agent.go @@ -582,6 +582,10 @@ func (a *agent) reportMetadata(ctx context.Context, conn drpc.Conn) error { select { case <-ctx.Done(): return ctx.Err() + case timing := <-*a.scriptRunner.ScriptTimings(): + aAPI.ScriptCompleted(ctx, &proto.WorkspaceAgentScriptCompletedRequest{ + Timing: timing.ToProto(), + }) case mr := <-metadataResults: // This can overwrite unsent values, but that's fine because // we're only interested about up-to-date values. diff --git a/agent/agentscripts/agentscripts.go b/agent/agentscripts/agentscripts.go index 2df1bc0ca0418..2e22087e703ff 100644 --- a/agent/agentscripts/agentscripts.go +++ b/agent/agentscripts/agentscripts.go @@ -66,6 +66,7 @@ func New(opts Options) *Runner { cronCtxCancel: cronCtxCancel, cron: cron.New(cron.WithParser(parser)), closed: make(chan struct{}), + scriptTimings: make(chan timingSpan), dataDir: filepath.Join(opts.DataDirBase, "coder-script-data"), scriptsExecuted: prometheus.NewCounterVec(prometheus.CounterOpts{ Namespace: "agent", @@ -86,6 +87,7 @@ type Runner struct { cron *cron.Cron initialized atomic.Bool scripts []codersdk.WorkspaceAgentScript + scriptTimings chan timingSpan dataDir string // scriptsExecuted includes all scripts executed by the workspace agent. Agents @@ -94,6 +96,10 @@ type Runner struct { scriptsExecuted *prometheus.CounterVec } +func (r *Runner) ScriptTimings() *chan timingSpan { + return &r.scriptTimings +} + // DataDir returns the directory where scripts data is stored. func (r *Runner) DataDir() string { return r.dataDir @@ -314,6 +320,13 @@ func (r *Runner) run(ctx context.Context, script codersdk.WorkspaceAgentScript) } else { logger.Info(ctx, fmt.Sprintf("%s script completed", logPath), slog.F("execution_time", execTime), slog.F("exit_code", exitCode)) } + + r.scriptTimings <- timingSpan{ + displayName: script.DisplayName, + start: start, + end: end, + exitCode: int32(exitCode), + } }() err = cmd.Start() diff --git a/agent/agentscripts/timings.go b/agent/agentscripts/timings.go new file mode 100644 index 0000000000000..7171147ca50ef --- /dev/null +++ b/agent/agentscripts/timings.go @@ -0,0 +1,23 @@ +package agentscripts + +import ( + "time" + + "github.com/coder/coder/v2/agent/proto" + "google.golang.org/protobuf/types/known/timestamppb" +) + +type timingSpan struct { + displayName string + start, end time.Time + exitCode int32 +} + +func (ts *timingSpan) ToProto() *proto.Timing { + return &proto.Timing{ + DisplayName: ts.displayName, + Start: timestamppb.New(ts.start), + End: timestamppb.New(ts.end), + ExitCode: ts.exitCode, + } +} diff --git a/agent/proto/agent.pb.go b/agent/proto/agent.pb.go index 343987517e717..fd98440161783 100644 --- a/agent/proto/agent.pb.go +++ b/agent/proto/agent.pb.go @@ -570,6 +570,7 @@ type WorkspaceAgentScript struct { RunOnStop bool `protobuf:"varint,6,opt,name=run_on_stop,json=runOnStop,proto3" json:"run_on_stop,omitempty"` StartBlocksLogin bool `protobuf:"varint,7,opt,name=start_blocks_login,json=startBlocksLogin,proto3" json:"start_blocks_login,omitempty"` Timeout *durationpb.Duration `protobuf:"bytes,8,opt,name=timeout,proto3" json:"timeout,omitempty"` + DisplayName string `protobuf:"bytes,9,opt,name=display_name,json=displayName,proto3" json:"display_name,omitempty"` } func (x *WorkspaceAgentScript) Reset() { @@ -660,6 +661,13 @@ func (x *WorkspaceAgentScript) GetTimeout() *durationpb.Duration { return nil } +func (x *WorkspaceAgentScript) GetDisplayName() string { + if x != nil { + return x.DisplayName + } + return "" +} + type WorkspaceAgentMetadata struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -2015,6 +2023,162 @@ func (x *BannerConfig) GetBackgroundColor() string { return "" } +type WorkspaceAgentScriptCompletedRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Timing *Timing `protobuf:"bytes,1,opt,name=timing,proto3" json:"timing,omitempty"` +} + +func (x *WorkspaceAgentScriptCompletedRequest) Reset() { + *x = WorkspaceAgentScriptCompletedRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_agent_proto_agent_proto_msgTypes[25] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *WorkspaceAgentScriptCompletedRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*WorkspaceAgentScriptCompletedRequest) ProtoMessage() {} + +func (x *WorkspaceAgentScriptCompletedRequest) ProtoReflect() protoreflect.Message { + mi := &file_agent_proto_agent_proto_msgTypes[25] + 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 WorkspaceAgentScriptCompletedRequest.ProtoReflect.Descriptor instead. +func (*WorkspaceAgentScriptCompletedRequest) Descriptor() ([]byte, []int) { + return file_agent_proto_agent_proto_rawDescGZIP(), []int{25} +} + +func (x *WorkspaceAgentScriptCompletedRequest) GetTiming() *Timing { + if x != nil { + return x.Timing + } + return nil +} + +type WorkspaceAgentScriptCompletedResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *WorkspaceAgentScriptCompletedResponse) Reset() { + *x = WorkspaceAgentScriptCompletedResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_agent_proto_agent_proto_msgTypes[26] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *WorkspaceAgentScriptCompletedResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*WorkspaceAgentScriptCompletedResponse) ProtoMessage() {} + +func (x *WorkspaceAgentScriptCompletedResponse) ProtoReflect() protoreflect.Message { + mi := &file_agent_proto_agent_proto_msgTypes[26] + 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 WorkspaceAgentScriptCompletedResponse.ProtoReflect.Descriptor instead. +func (*WorkspaceAgentScriptCompletedResponse) Descriptor() ([]byte, []int) { + return file_agent_proto_agent_proto_rawDescGZIP(), []int{26} +} + +type Timing struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + DisplayName string `protobuf:"bytes,1,opt,name=display_name,json=displayName,proto3" json:"display_name,omitempty"` + Start *timestamppb.Timestamp `protobuf:"bytes,2,opt,name=start,proto3" json:"start,omitempty"` + End *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=end,proto3" json:"end,omitempty"` + ExitCode int32 `protobuf:"varint,4,opt,name=exit_code,json=exitCode,proto3" json:"exit_code,omitempty"` +} + +func (x *Timing) Reset() { + *x = Timing{} + if protoimpl.UnsafeEnabled { + mi := &file_agent_proto_agent_proto_msgTypes[27] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Timing) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Timing) ProtoMessage() {} + +func (x *Timing) ProtoReflect() protoreflect.Message { + mi := &file_agent_proto_agent_proto_msgTypes[27] + 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 Timing.ProtoReflect.Descriptor instead. +func (*Timing) Descriptor() ([]byte, []int) { + return file_agent_proto_agent_proto_rawDescGZIP(), []int{27} +} + +func (x *Timing) GetDisplayName() string { + if x != nil { + return x.DisplayName + } + return "" +} + +func (x *Timing) GetStart() *timestamppb.Timestamp { + if x != nil { + return x.Start + } + return nil +} + +func (x *Timing) GetEnd() *timestamppb.Timestamp { + if x != nil { + return x.End + } + return nil +} + +func (x *Timing) GetExitCode() int32 { + if x != nil { + return x.ExitCode + } + return 0 +} + type WorkspaceApp_Healthcheck struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -2028,7 +2192,7 @@ type WorkspaceApp_Healthcheck struct { func (x *WorkspaceApp_Healthcheck) Reset() { *x = WorkspaceApp_Healthcheck{} if protoimpl.UnsafeEnabled { - mi := &file_agent_proto_agent_proto_msgTypes[25] + mi := &file_agent_proto_agent_proto_msgTypes[28] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2041,7 +2205,7 @@ func (x *WorkspaceApp_Healthcheck) String() string { func (*WorkspaceApp_Healthcheck) ProtoMessage() {} func (x *WorkspaceApp_Healthcheck) ProtoReflect() protoreflect.Message { - mi := &file_agent_proto_agent_proto_msgTypes[25] + mi := &file_agent_proto_agent_proto_msgTypes[28] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2092,7 +2256,7 @@ type WorkspaceAgentMetadata_Result struct { func (x *WorkspaceAgentMetadata_Result) Reset() { *x = WorkspaceAgentMetadata_Result{} if protoimpl.UnsafeEnabled { - mi := &file_agent_proto_agent_proto_msgTypes[26] + mi := &file_agent_proto_agent_proto_msgTypes[29] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2105,7 +2269,7 @@ func (x *WorkspaceAgentMetadata_Result) String() string { func (*WorkspaceAgentMetadata_Result) ProtoMessage() {} func (x *WorkspaceAgentMetadata_Result) ProtoReflect() protoreflect.Message { - mi := &file_agent_proto_agent_proto_msgTypes[26] + mi := &file_agent_proto_agent_proto_msgTypes[29] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2164,7 +2328,7 @@ type WorkspaceAgentMetadata_Description struct { func (x *WorkspaceAgentMetadata_Description) Reset() { *x = WorkspaceAgentMetadata_Description{} if protoimpl.UnsafeEnabled { - mi := &file_agent_proto_agent_proto_msgTypes[27] + mi := &file_agent_proto_agent_proto_msgTypes[30] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2177,7 +2341,7 @@ func (x *WorkspaceAgentMetadata_Description) String() string { func (*WorkspaceAgentMetadata_Description) ProtoMessage() {} func (x *WorkspaceAgentMetadata_Description) ProtoReflect() protoreflect.Message { - mi := &file_agent_proto_agent_proto_msgTypes[27] + mi := &file_agent_proto_agent_proto_msgTypes[30] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2242,7 +2406,7 @@ type Stats_Metric struct { func (x *Stats_Metric) Reset() { *x = Stats_Metric{} if protoimpl.UnsafeEnabled { - mi := &file_agent_proto_agent_proto_msgTypes[30] + mi := &file_agent_proto_agent_proto_msgTypes[33] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2255,7 +2419,7 @@ func (x *Stats_Metric) String() string { func (*Stats_Metric) ProtoMessage() {} func (x *Stats_Metric) ProtoReflect() protoreflect.Message { - mi := &file_agent_proto_agent_proto_msgTypes[30] + mi := &file_agent_proto_agent_proto_msgTypes[33] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2311,7 +2475,7 @@ type Stats_Metric_Label struct { func (x *Stats_Metric_Label) Reset() { *x = Stats_Metric_Label{} if protoimpl.UnsafeEnabled { - mi := &file_agent_proto_agent_proto_msgTypes[31] + mi := &file_agent_proto_agent_proto_msgTypes[34] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2324,7 +2488,7 @@ func (x *Stats_Metric_Label) String() string { func (*Stats_Metric_Label) ProtoMessage() {} func (x *Stats_Metric_Label) ProtoReflect() protoreflect.Message { - mi := &file_agent_proto_agent_proto_msgTypes[31] + mi := &file_agent_proto_agent_proto_msgTypes[34] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2366,7 +2530,7 @@ type BatchUpdateAppHealthRequest_HealthUpdate struct { func (x *BatchUpdateAppHealthRequest_HealthUpdate) Reset() { *x = BatchUpdateAppHealthRequest_HealthUpdate{} if protoimpl.UnsafeEnabled { - mi := &file_agent_proto_agent_proto_msgTypes[32] + mi := &file_agent_proto_agent_proto_msgTypes[35] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2379,7 +2543,7 @@ func (x *BatchUpdateAppHealthRequest_HealthUpdate) String() string { func (*BatchUpdateAppHealthRequest_HealthUpdate) ProtoMessage() {} func (x *BatchUpdateAppHealthRequest_HealthUpdate) ProtoReflect() protoreflect.Message { - mi := &file_agent_proto_agent_proto_msgTypes[32] + mi := &file_agent_proto_agent_proto_msgTypes[35] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2469,7 +2633,7 @@ var file_agent_proto_agent_proto_rawDesc = []byte{ 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x44, 0x49, 0x53, 0x41, 0x42, 0x4c, 0x45, 0x44, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x49, 0x4e, 0x49, 0x54, 0x49, 0x41, 0x4c, 0x49, 0x5a, 0x49, 0x4e, 0x47, 0x10, 0x02, 0x12, 0x0b, 0x0a, 0x07, 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, 0x59, 0x10, 0x03, 0x12, - 0x0d, 0x0a, 0x09, 0x55, 0x4e, 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, 0x59, 0x10, 0x04, 0x22, 0xa6, + 0x0d, 0x0a, 0x09, 0x55, 0x4e, 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, 0x59, 0x10, 0x04, 0x22, 0xc9, 0x02, 0x0a, 0x14, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x12, 0x22, 0x0a, 0x0d, 0x6c, 0x6f, 0x67, 0x5f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, @@ -2488,351 +2652,380 @@ var file_agent_proto_agent_proto_rawDesc = []byte{ 0x69, 0x6e, 0x12, 0x33, 0x0a, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x07, - 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x22, 0x86, 0x04, 0x0a, 0x16, 0x57, 0x6f, 0x72, 0x6b, - 0x73, 0x70, 0x61, 0x63, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, - 0x74, 0x61, 0x12, 0x45, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, - 0x2e, 0x76, 0x32, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x41, 0x67, 0x65, - 0x6e, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6c, - 0x74, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x54, 0x0a, 0x0b, 0x64, 0x65, 0x73, - 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x32, - 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, - 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x4d, 0x65, - 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, - 0x6f, 0x6e, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x1a, - 0x85, 0x01, 0x0a, 0x06, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x3d, 0x0a, 0x0c, 0x63, 0x6f, - 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0b, 0x63, 0x6f, - 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x67, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x03, 0x61, 0x67, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x1a, 0xc6, 0x01, 0x0a, 0x0b, 0x44, 0x65, 0x73, 0x63, - 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x21, 0x0a, 0x0c, 0x64, 0x69, 0x73, 0x70, 0x6c, - 0x61, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, - 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, - 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x16, 0x0a, 0x06, - 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x63, - 0x72, 0x69, 0x70, 0x74, 0x12, 0x35, 0x0a, 0x08, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x52, 0x08, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x12, 0x33, 0x0a, 0x07, 0x74, - 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, - 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, - 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, - 0x22, 0xea, 0x06, 0x0a, 0x08, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x12, 0x19, 0x0a, - 0x08, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x07, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x67, 0x65, 0x6e, - 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x67, - 0x65, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x6f, 0x77, 0x6e, 0x65, 0x72, - 0x5f, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0d, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x55, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x21, - 0x0a, 0x0c, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x0e, - 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x49, - 0x64, 0x12, 0x25, 0x0a, 0x0e, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x6e, - 0x61, 0x6d, 0x65, 0x18, 0x10, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x77, 0x6f, 0x72, 0x6b, 0x73, - 0x70, 0x61, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x28, 0x0a, 0x10, 0x67, 0x69, 0x74, 0x5f, - 0x61, 0x75, 0x74, 0x68, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0d, 0x52, 0x0e, 0x67, 0x69, 0x74, 0x41, 0x75, 0x74, 0x68, 0x43, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x73, 0x12, 0x67, 0x0a, 0x15, 0x65, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, - 0x74, 0x5f, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, + 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x64, 0x69, 0x73, 0x70, 0x6c, + 0x61, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, + 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x86, 0x04, 0x0a, 0x16, 0x57, + 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x4d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x45, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, + 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, + 0x41, 0x67, 0x65, 0x6e, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x65, + 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x54, 0x0a, 0x0b, + 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, - 0x76, 0x32, 0x2e, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x2e, 0x45, 0x6e, 0x76, 0x69, - 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, - 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x14, 0x65, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, - 0x6e, 0x74, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x64, - 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, - 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x32, 0x0a, 0x16, 0x76, 0x73, 0x5f, - 0x63, 0x6f, 0x64, 0x65, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x5f, - 0x75, 0x72, 0x69, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x76, 0x73, 0x43, 0x6f, 0x64, - 0x65, 0x50, 0x6f, 0x72, 0x74, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x55, 0x72, 0x69, 0x12, 0x1b, 0x0a, - 0x09, 0x6d, 0x6f, 0x74, 0x64, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x08, 0x6d, 0x6f, 0x74, 0x64, 0x50, 0x61, 0x74, 0x68, 0x12, 0x3c, 0x0a, 0x1a, 0x64, 0x69, - 0x73, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x5f, 0x63, 0x6f, 0x6e, - 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x18, - 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x43, 0x6f, 0x6e, - 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x32, 0x0a, 0x15, 0x64, 0x65, 0x72, 0x70, - 0x5f, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x5f, 0x77, 0x65, 0x62, 0x73, 0x6f, 0x63, 0x6b, 0x65, 0x74, - 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x13, 0x64, 0x65, 0x72, 0x70, 0x46, 0x6f, 0x72, - 0x63, 0x65, 0x57, 0x65, 0x62, 0x73, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x12, 0x34, 0x0a, 0x08, - 0x64, 0x65, 0x72, 0x70, 0x5f, 0x6d, 0x61, 0x70, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, - 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x74, 0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74, 0x2e, 0x76, - 0x32, 0x2e, 0x44, 0x45, 0x52, 0x50, 0x4d, 0x61, 0x70, 0x52, 0x07, 0x64, 0x65, 0x72, 0x70, 0x4d, - 0x61, 0x70, 0x12, 0x3e, 0x0a, 0x07, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x73, 0x18, 0x0a, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, - 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x41, 0x67, - 0x65, 0x6e, 0x74, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x52, 0x07, 0x73, 0x63, 0x72, 0x69, 0x70, - 0x74, 0x73, 0x12, 0x30, 0x0a, 0x04, 0x61, 0x70, 0x70, 0x73, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x1c, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, - 0x32, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x41, 0x70, 0x70, 0x52, 0x04, - 0x61, 0x70, 0x70, 0x73, 0x12, 0x4e, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, - 0x18, 0x0c, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, + 0x76, 0x32, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x41, 0x67, 0x65, 0x6e, + 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x1a, 0x85, 0x01, 0x0a, 0x06, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x3d, 0x0a, + 0x0c, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, + 0x0b, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x10, 0x0a, 0x03, + 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x03, 0x61, 0x67, 0x65, 0x12, 0x14, + 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x1a, 0xc6, 0x01, 0x0a, 0x0b, 0x44, + 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x21, 0x0a, 0x0c, 0x64, 0x69, + 0x73, 0x70, 0x6c, 0x61, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x10, 0x0a, + 0x03, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, + 0x16, 0x0a, 0x06, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x06, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x12, 0x35, 0x0a, 0x08, 0x69, 0x6e, 0x74, 0x65, 0x72, + 0x76, 0x61, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x08, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x12, 0x33, + 0x0a, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x07, 0x74, 0x69, 0x6d, 0x65, + 0x6f, 0x75, 0x74, 0x22, 0xea, 0x06, 0x0a, 0x08, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, + 0x12, 0x19, 0x0a, 0x08, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x07, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x61, + 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x09, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x6f, 0x77, + 0x6e, 0x65, 0x72, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x0d, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0d, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x55, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, + 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x69, + 0x64, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x0e, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x10, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x77, 0x6f, + 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x28, 0x0a, 0x10, 0x67, + 0x69, 0x74, 0x5f, 0x61, 0x75, 0x74, 0x68, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0e, 0x67, 0x69, 0x74, 0x41, 0x75, 0x74, 0x68, 0x43, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x73, 0x12, 0x67, 0x0a, 0x15, 0x65, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, + 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x03, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, + 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x2e, 0x45, + 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, + 0x6c, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x14, 0x65, 0x6e, 0x76, 0x69, 0x72, 0x6f, + 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, 0x1c, + 0x0a, 0x09, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x09, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x32, 0x0a, 0x16, + 0x76, 0x73, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x70, 0x72, 0x6f, + 0x78, 0x79, 0x5f, 0x75, 0x72, 0x69, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x76, 0x73, + 0x43, 0x6f, 0x64, 0x65, 0x50, 0x6f, 0x72, 0x74, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x55, 0x72, 0x69, + 0x12, 0x1b, 0x0a, 0x09, 0x6d, 0x6f, 0x74, 0x64, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x06, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x08, 0x6d, 0x6f, 0x74, 0x64, 0x50, 0x61, 0x74, 0x68, 0x12, 0x3c, 0x0a, + 0x1a, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x5f, + 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x18, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, + 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x32, 0x0a, 0x15, 0x64, + 0x65, 0x72, 0x70, 0x5f, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x5f, 0x77, 0x65, 0x62, 0x73, 0x6f, 0x63, + 0x6b, 0x65, 0x74, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x13, 0x64, 0x65, 0x72, 0x70, + 0x46, 0x6f, 0x72, 0x63, 0x65, 0x57, 0x65, 0x62, 0x73, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x12, + 0x34, 0x0a, 0x08, 0x64, 0x65, 0x72, 0x70, 0x5f, 0x6d, 0x61, 0x70, 0x18, 0x09, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x74, 0x61, 0x69, 0x6c, 0x6e, 0x65, + 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x44, 0x45, 0x52, 0x50, 0x4d, 0x61, 0x70, 0x52, 0x07, 0x64, 0x65, + 0x72, 0x70, 0x4d, 0x61, 0x70, 0x12, 0x3e, 0x0a, 0x07, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x73, + 0x18, 0x0a, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, - 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x44, - 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, - 0x64, 0x61, 0x74, 0x61, 0x1a, 0x47, 0x0a, 0x19, 0x45, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, - 0x65, 0x6e, 0x74, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, - 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, - 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x14, 0x0a, - 0x12, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x22, 0x6e, 0x0a, 0x0d, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x42, 0x61, - 0x6e, 0x6e, 0x65, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x18, - 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x29, 0x0a, 0x10, 0x62, 0x61, 0x63, 0x6b, - 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0f, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x43, 0x6f, - 0x6c, 0x6f, 0x72, 0x22, 0x19, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0xb3, - 0x07, 0x0a, 0x05, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x5f, 0x0a, 0x14, 0x63, 0x6f, 0x6e, 0x6e, - 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x5f, 0x62, 0x79, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, - 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x73, 0x2e, 0x43, 0x6f, - 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x42, 0x79, 0x50, 0x72, 0x6f, 0x74, 0x6f, - 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x12, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x42, 0x79, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x29, 0x0a, 0x10, 0x63, 0x6f, 0x6e, - 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x03, 0x52, 0x0f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x43, - 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x3f, 0x0a, 0x1c, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x5f, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x6e, 0x5f, 0x6c, 0x61, 0x74, 0x65, 0x6e, 0x63, - 0x79, 0x5f, 0x6d, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x01, 0x52, 0x19, 0x63, 0x6f, 0x6e, 0x6e, - 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x64, 0x69, 0x61, 0x6e, 0x4c, 0x61, 0x74, 0x65, - 0x6e, 0x63, 0x79, 0x4d, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x78, 0x5f, 0x70, 0x61, 0x63, 0x6b, - 0x65, 0x74, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x72, 0x78, 0x50, 0x61, 0x63, - 0x6b, 0x65, 0x74, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x72, 0x78, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, - 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x72, 0x78, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, - 0x1d, 0x0a, 0x0a, 0x74, 0x78, 0x5f, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x18, 0x06, 0x20, - 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x78, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x12, 0x19, - 0x0a, 0x08, 0x74, 0x78, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, - 0x52, 0x07, 0x74, 0x78, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x30, 0x0a, 0x14, 0x73, 0x65, 0x73, - 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x76, 0x73, 0x63, 0x6f, 0x64, - 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x03, 0x52, 0x12, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, - 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x56, 0x73, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x36, 0x0a, 0x17, 0x73, - 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x6a, 0x65, 0x74, - 0x62, 0x72, 0x61, 0x69, 0x6e, 0x73, 0x18, 0x09, 0x20, 0x01, 0x28, 0x03, 0x52, 0x15, 0x73, 0x65, - 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x4a, 0x65, 0x74, 0x62, 0x72, 0x61, - 0x69, 0x6e, 0x73, 0x12, 0x43, 0x0a, 0x1e, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x63, - 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x72, 0x65, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6e, - 0x67, 0x5f, 0x70, 0x74, 0x79, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x03, 0x52, 0x1b, 0x73, 0x65, 0x73, - 0x73, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x63, 0x6f, 0x6e, 0x6e, 0x65, - 0x63, 0x74, 0x69, 0x6e, 0x67, 0x50, 0x74, 0x79, 0x12, 0x2a, 0x0a, 0x11, 0x73, 0x65, 0x73, 0x73, - 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x73, 0x73, 0x68, 0x18, 0x0b, 0x20, - 0x01, 0x28, 0x03, 0x52, 0x0f, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x75, 0x6e, - 0x74, 0x53, 0x73, 0x68, 0x12, 0x36, 0x0a, 0x07, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x18, - 0x0c, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, - 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x73, 0x2e, 0x4d, 0x65, 0x74, - 0x72, 0x69, 0x63, 0x52, 0x07, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x1a, 0x45, 0x0a, 0x17, - 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x42, 0x79, 0x50, 0x72, 0x6f, - 0x74, 0x6f, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, - 0x02, 0x38, 0x01, 0x1a, 0x8e, 0x02, 0x0a, 0x06, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x12, 0x12, - 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, - 0x6d, 0x65, 0x12, 0x35, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, - 0x32, 0x21, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, - 0x32, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x73, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x54, - 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x01, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, - 0x3a, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x22, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, - 0x2e, 0x53, 0x74, 0x61, 0x74, 0x73, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x4c, 0x61, - 0x62, 0x65, 0x6c, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x1a, 0x31, 0x0a, 0x05, 0x4c, - 0x61, 0x62, 0x65, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x34, - 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, - 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, - 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x47, 0x41, 0x55, - 0x47, 0x45, 0x10, 0x02, 0x22, 0x41, 0x0a, 0x12, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, - 0x61, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2b, 0x0a, 0x05, 0x73, 0x74, - 0x61, 0x74, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x63, 0x6f, 0x64, 0x65, + 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x52, 0x07, 0x73, 0x63, + 0x72, 0x69, 0x70, 0x74, 0x73, 0x12, 0x30, 0x0a, 0x04, 0x61, 0x70, 0x70, 0x73, 0x18, 0x0b, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, + 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x41, 0x70, + 0x70, 0x52, 0x04, 0x61, 0x70, 0x70, 0x73, 0x12, 0x4e, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x18, 0x0c, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x63, 0x6f, 0x64, 0x65, + 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, + 0x70, 0x61, 0x63, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0x2e, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x08, 0x6d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x1a, 0x47, 0x0a, 0x19, 0x45, 0x6e, 0x76, 0x69, 0x72, + 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x45, + 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, + 0x22, 0x14, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x6e, 0x0a, 0x0d, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, + 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, + 0x64, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x29, 0x0a, 0x10, 0x62, + 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, + 0x64, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x22, 0x19, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x53, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x22, 0xb3, 0x07, 0x0a, 0x05, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x5f, 0x0a, 0x14, 0x63, + 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x5f, 0x62, 0x79, 0x5f, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x73, - 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x73, 0x22, 0x59, 0x0a, 0x13, 0x55, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x42, - 0x0a, 0x0f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, - 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x52, 0x0e, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, - 0x61, 0x6c, 0x22, 0xae, 0x02, 0x0a, 0x09, 0x4c, 0x69, 0x66, 0x65, 0x63, 0x79, 0x63, 0x6c, 0x65, - 0x12, 0x35, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, - 0x1f, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, - 0x2e, 0x4c, 0x69, 0x66, 0x65, 0x63, 0x79, 0x63, 0x6c, 0x65, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, - 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x68, 0x61, 0x6e, 0x67, - 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, - 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, - 0x41, 0x74, 0x22, 0xae, 0x01, 0x0a, 0x05, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x15, 0x0a, 0x11, - 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, - 0x44, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x44, 0x10, 0x01, - 0x12, 0x0c, 0x0a, 0x08, 0x53, 0x54, 0x41, 0x52, 0x54, 0x49, 0x4e, 0x47, 0x10, 0x02, 0x12, 0x11, - 0x0a, 0x0d, 0x53, 0x54, 0x41, 0x52, 0x54, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x4f, 0x55, 0x54, 0x10, - 0x03, 0x12, 0x0f, 0x0a, 0x0b, 0x53, 0x54, 0x41, 0x52, 0x54, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, - 0x10, 0x04, 0x12, 0x09, 0x0a, 0x05, 0x52, 0x45, 0x41, 0x44, 0x59, 0x10, 0x05, 0x12, 0x11, 0x0a, - 0x0d, 0x53, 0x48, 0x55, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x5f, 0x44, 0x4f, 0x57, 0x4e, 0x10, 0x06, - 0x12, 0x14, 0x0a, 0x10, 0x53, 0x48, 0x55, 0x54, 0x44, 0x4f, 0x57, 0x4e, 0x5f, 0x54, 0x49, 0x4d, - 0x45, 0x4f, 0x55, 0x54, 0x10, 0x07, 0x12, 0x12, 0x0a, 0x0e, 0x53, 0x48, 0x55, 0x54, 0x44, 0x4f, - 0x57, 0x4e, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x08, 0x12, 0x07, 0x0a, 0x03, 0x4f, 0x46, - 0x46, 0x10, 0x09, 0x22, 0x51, 0x0a, 0x16, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4c, 0x69, 0x66, - 0x65, 0x63, 0x79, 0x63, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x37, 0x0a, - 0x09, 0x6c, 0x69, 0x66, 0x65, 0x63, 0x79, 0x63, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x19, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, - 0x32, 0x2e, 0x4c, 0x69, 0x66, 0x65, 0x63, 0x79, 0x63, 0x6c, 0x65, 0x52, 0x09, 0x6c, 0x69, 0x66, - 0x65, 0x63, 0x79, 0x63, 0x6c, 0x65, 0x22, 0xc4, 0x01, 0x0a, 0x1b, 0x42, 0x61, 0x74, 0x63, 0x68, - 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x70, 0x70, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x52, 0x0a, 0x07, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x38, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, - 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x55, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x41, 0x70, 0x70, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x52, 0x07, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x1a, 0x51, 0x0a, 0x0c, 0x48, 0x65, - 0x61, 0x6c, 0x74, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, 0x69, 0x64, 0x12, 0x31, 0x0a, 0x06, 0x68, 0x65, - 0x61, 0x6c, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x19, 0x2e, 0x63, 0x6f, 0x64, - 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x41, 0x70, 0x70, 0x48, - 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, 0x06, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x22, 0x1e, 0x0a, - 0x1c, 0x42, 0x61, 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x70, 0x70, 0x48, - 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xe8, 0x01, - 0x0a, 0x07, 0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, - 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, - 0x69, 0x6f, 0x6e, 0x12, 0x2d, 0x0a, 0x12, 0x65, 0x78, 0x70, 0x61, 0x6e, 0x64, 0x65, 0x64, 0x5f, - 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x11, 0x65, 0x78, 0x70, 0x61, 0x6e, 0x64, 0x65, 0x64, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, - 0x72, 0x79, 0x12, 0x41, 0x0a, 0x0a, 0x73, 0x75, 0x62, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x73, - 0x18, 0x03, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x21, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, - 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x2e, - 0x53, 0x75, 0x62, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x52, 0x0a, 0x73, 0x75, 0x62, 0x73, 0x79, - 0x73, 0x74, 0x65, 0x6d, 0x73, 0x22, 0x51, 0x0a, 0x09, 0x53, 0x75, 0x62, 0x73, 0x79, 0x73, 0x74, - 0x65, 0x6d, 0x12, 0x19, 0x0a, 0x15, 0x53, 0x55, 0x42, 0x53, 0x59, 0x53, 0x54, 0x45, 0x4d, 0x5f, - 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0a, 0x0a, - 0x06, 0x45, 0x4e, 0x56, 0x42, 0x4f, 0x58, 0x10, 0x01, 0x12, 0x0e, 0x0a, 0x0a, 0x45, 0x4e, 0x56, - 0x42, 0x55, 0x49, 0x4c, 0x44, 0x45, 0x52, 0x10, 0x02, 0x12, 0x0d, 0x0a, 0x09, 0x45, 0x58, 0x45, - 0x43, 0x54, 0x52, 0x41, 0x43, 0x45, 0x10, 0x03, 0x22, 0x49, 0x0a, 0x14, 0x55, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x31, 0x0a, 0x07, 0x73, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x17, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, - 0x76, 0x32, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x52, 0x07, 0x73, 0x74, 0x61, 0x72, - 0x74, 0x75, 0x70, 0x22, 0x63, 0x0a, 0x08, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, - 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, - 0x79, 0x12, 0x45, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x2d, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, - 0x76, 0x32, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x41, 0x67, 0x65, 0x6e, - 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, - 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x52, 0x0a, 0x1a, 0x42, 0x61, 0x74, 0x63, - 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x34, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, - 0x74, 0x61, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, - 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, - 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x22, 0x1d, 0x0a, 0x1b, - 0x42, 0x61, 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, - 0x61, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xde, 0x01, 0x0a, 0x03, - 0x4c, 0x6f, 0x67, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, - 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, - 0x61, 0x6d, 0x70, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x16, - 0x0a, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, - 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x12, 0x2f, 0x0a, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x19, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, - 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x4c, 0x6f, 0x67, 0x2e, 0x4c, 0x65, 0x76, 0x65, 0x6c, - 0x52, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x22, 0x53, 0x0a, 0x05, 0x4c, 0x65, 0x76, 0x65, 0x6c, - 0x12, 0x15, 0x0a, 0x11, 0x4c, 0x45, 0x56, 0x45, 0x4c, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, - 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x54, 0x52, 0x41, 0x43, 0x45, - 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x44, 0x45, 0x42, 0x55, 0x47, 0x10, 0x02, 0x12, 0x08, 0x0a, - 0x04, 0x49, 0x4e, 0x46, 0x4f, 0x10, 0x03, 0x12, 0x08, 0x0a, 0x04, 0x57, 0x41, 0x52, 0x4e, 0x10, - 0x04, 0x12, 0x09, 0x0a, 0x05, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x05, 0x22, 0x65, 0x0a, 0x16, - 0x42, 0x61, 0x74, 0x63, 0x68, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4c, 0x6f, 0x67, 0x73, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x22, 0x0a, 0x0d, 0x6c, 0x6f, 0x67, 0x5f, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x6c, - 0x6f, 0x67, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x64, 0x12, 0x27, 0x0a, 0x04, 0x6c, 0x6f, - 0x67, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, - 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x4c, 0x6f, 0x67, 0x52, 0x04, 0x6c, - 0x6f, 0x67, 0x73, 0x22, 0x47, 0x0a, 0x17, 0x42, 0x61, 0x74, 0x63, 0x68, 0x43, 0x72, 0x65, 0x61, - 0x74, 0x65, 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2c, - 0x0a, 0x12, 0x6c, 0x6f, 0x67, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x5f, 0x65, 0x78, 0x63, 0x65, - 0x65, 0x64, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x6c, 0x6f, 0x67, 0x4c, - 0x69, 0x6d, 0x69, 0x74, 0x45, 0x78, 0x63, 0x65, 0x65, 0x64, 0x65, 0x64, 0x22, 0x1f, 0x0a, 0x1d, - 0x47, 0x65, 0x74, 0x41, 0x6e, 0x6e, 0x6f, 0x75, 0x6e, 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, - 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x71, 0x0a, - 0x1e, 0x47, 0x65, 0x74, 0x41, 0x6e, 0x6e, 0x6f, 0x75, 0x6e, 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, - 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x4f, 0x0a, 0x14, 0x61, 0x6e, 0x6e, 0x6f, 0x75, 0x6e, 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x5f, - 0x62, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, - 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x42, - 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x13, 0x61, 0x6e, 0x6e, - 0x6f, 0x75, 0x6e, 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x73, - 0x22, 0x6d, 0x0a, 0x0c, 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, - 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, - 0x73, 0x61, 0x67, 0x65, 0x12, 0x29, 0x0a, 0x10, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, - 0x6e, 0x64, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, - 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x2a, - 0x63, 0x0a, 0x09, 0x41, 0x70, 0x70, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x12, 0x1a, 0x0a, 0x16, - 0x41, 0x50, 0x50, 0x5f, 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, - 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x44, 0x49, 0x53, 0x41, - 0x42, 0x4c, 0x45, 0x44, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x49, 0x4e, 0x49, 0x54, 0x49, 0x41, - 0x4c, 0x49, 0x5a, 0x49, 0x4e, 0x47, 0x10, 0x02, 0x12, 0x0b, 0x0a, 0x07, 0x48, 0x45, 0x41, 0x4c, - 0x54, 0x48, 0x59, 0x10, 0x03, 0x12, 0x0d, 0x0a, 0x09, 0x55, 0x4e, 0x48, 0x45, 0x41, 0x4c, 0x54, - 0x48, 0x59, 0x10, 0x04, 0x32, 0xef, 0x06, 0x0a, 0x05, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x12, 0x4b, - 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x12, 0x22, 0x2e, - 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x47, - 0x65, 0x74, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x18, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, - 0x76, 0x32, 0x2e, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x12, 0x5a, 0x0a, 0x10, 0x47, - 0x65, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x12, - 0x27, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, - 0x2e, 0x47, 0x65, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x42, 0x61, 0x6e, 0x6e, 0x65, - 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, - 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x12, 0x56, 0x0a, 0x0b, 0x55, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x22, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, - 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, - 0x61, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x63, 0x6f, 0x64, - 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x54, 0x0a, 0x0f, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4c, 0x69, 0x66, 0x65, 0x63, 0x79, 0x63, - 0x6c, 0x65, 0x12, 0x26, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, - 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4c, 0x69, 0x66, 0x65, 0x63, 0x79, - 0x63, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x63, 0x6f, 0x64, - 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x4c, 0x69, 0x66, 0x65, - 0x63, 0x79, 0x63, 0x6c, 0x65, 0x12, 0x72, 0x0a, 0x15, 0x42, 0x61, 0x74, 0x63, 0x68, 0x55, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x41, 0x70, 0x70, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x73, 0x12, 0x2b, + 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x42, 0x79, 0x50, 0x72, + 0x6f, 0x74, 0x6f, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x12, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x42, 0x79, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x29, 0x0a, 0x10, + 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x3f, 0x0a, 0x1c, 0x63, 0x6f, 0x6e, 0x6e, 0x65, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x6e, 0x5f, 0x6c, 0x61, 0x74, + 0x65, 0x6e, 0x63, 0x79, 0x5f, 0x6d, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x01, 0x52, 0x19, 0x63, + 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x64, 0x69, 0x61, 0x6e, 0x4c, + 0x61, 0x74, 0x65, 0x6e, 0x63, 0x79, 0x4d, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x78, 0x5f, 0x70, + 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x72, 0x78, + 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x72, 0x78, 0x5f, 0x62, 0x79, + 0x74, 0x65, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x72, 0x78, 0x42, 0x79, 0x74, + 0x65, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x74, 0x78, 0x5f, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, + 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x78, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, + 0x73, 0x12, 0x19, 0x0a, 0x08, 0x74, 0x78, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x07, 0x20, + 0x01, 0x28, 0x03, 0x52, 0x07, 0x74, 0x78, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x30, 0x0a, 0x14, + 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x76, 0x73, + 0x63, 0x6f, 0x64, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x03, 0x52, 0x12, 0x73, 0x65, 0x73, 0x73, + 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x56, 0x73, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x36, + 0x0a, 0x17, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, + 0x6a, 0x65, 0x74, 0x62, 0x72, 0x61, 0x69, 0x6e, 0x73, 0x18, 0x09, 0x20, 0x01, 0x28, 0x03, 0x52, + 0x15, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x4a, 0x65, 0x74, + 0x62, 0x72, 0x61, 0x69, 0x6e, 0x73, 0x12, 0x43, 0x0a, 0x1e, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, + 0x6e, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x72, 0x65, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, + 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x70, 0x74, 0x79, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x03, 0x52, 0x1b, + 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x63, 0x6f, + 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6e, 0x67, 0x50, 0x74, 0x79, 0x12, 0x2a, 0x0a, 0x11, 0x73, + 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x73, 0x73, 0x68, + 0x18, 0x0b, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0f, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x43, + 0x6f, 0x75, 0x6e, 0x74, 0x53, 0x73, 0x68, 0x12, 0x36, 0x0a, 0x07, 0x6d, 0x65, 0x74, 0x72, 0x69, + 0x63, 0x73, 0x18, 0x0c, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, + 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x73, 0x2e, + 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x52, 0x07, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x1a, + 0x45, 0x0a, 0x17, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x42, 0x79, + 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, + 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x8e, 0x02, 0x0a, 0x06, 0x4d, 0x65, 0x74, 0x72, 0x69, + 0x63, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x35, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0e, 0x32, 0x21, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, + 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x73, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, + 0x63, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x01, 0x52, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x12, 0x3a, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x04, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, + 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x73, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, + 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x1a, 0x31, + 0x0a, 0x05, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x22, 0x34, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x59, 0x50, + 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, + 0x0b, 0x0a, 0x07, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, + 0x47, 0x41, 0x55, 0x47, 0x45, 0x10, 0x02, 0x22, 0x41, 0x0a, 0x12, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2b, 0x0a, + 0x05, 0x73, 0x74, 0x61, 0x74, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x63, + 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x74, + 0x61, 0x74, 0x73, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x73, 0x22, 0x59, 0x0a, 0x13, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x42, 0x0a, 0x0f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x69, 0x6e, 0x74, 0x65, + 0x72, 0x76, 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0e, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x49, 0x6e, 0x74, + 0x65, 0x72, 0x76, 0x61, 0x6c, 0x22, 0xae, 0x02, 0x0a, 0x09, 0x4c, 0x69, 0x66, 0x65, 0x63, 0x79, + 0x63, 0x6c, 0x65, 0x12, 0x35, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0e, 0x32, 0x1f, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, + 0x2e, 0x76, 0x32, 0x2e, 0x4c, 0x69, 0x66, 0x65, 0x63, 0x79, 0x63, 0x6c, 0x65, 0x2e, 0x53, 0x74, + 0x61, 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x68, + 0x61, 0x6e, 0x67, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x63, 0x68, 0x61, 0x6e, + 0x67, 0x65, 0x64, 0x41, 0x74, 0x22, 0xae, 0x01, 0x0a, 0x05, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, + 0x15, 0x0a, 0x11, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, + 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, + 0x44, 0x10, 0x01, 0x12, 0x0c, 0x0a, 0x08, 0x53, 0x54, 0x41, 0x52, 0x54, 0x49, 0x4e, 0x47, 0x10, + 0x02, 0x12, 0x11, 0x0a, 0x0d, 0x53, 0x54, 0x41, 0x52, 0x54, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x4f, + 0x55, 0x54, 0x10, 0x03, 0x12, 0x0f, 0x0a, 0x0b, 0x53, 0x54, 0x41, 0x52, 0x54, 0x5f, 0x45, 0x52, + 0x52, 0x4f, 0x52, 0x10, 0x04, 0x12, 0x09, 0x0a, 0x05, 0x52, 0x45, 0x41, 0x44, 0x59, 0x10, 0x05, + 0x12, 0x11, 0x0a, 0x0d, 0x53, 0x48, 0x55, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x5f, 0x44, 0x4f, 0x57, + 0x4e, 0x10, 0x06, 0x12, 0x14, 0x0a, 0x10, 0x53, 0x48, 0x55, 0x54, 0x44, 0x4f, 0x57, 0x4e, 0x5f, + 0x54, 0x49, 0x4d, 0x45, 0x4f, 0x55, 0x54, 0x10, 0x07, 0x12, 0x12, 0x0a, 0x0e, 0x53, 0x48, 0x55, + 0x54, 0x44, 0x4f, 0x57, 0x4e, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x08, 0x12, 0x07, 0x0a, + 0x03, 0x4f, 0x46, 0x46, 0x10, 0x09, 0x22, 0x51, 0x0a, 0x16, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x4c, 0x69, 0x66, 0x65, 0x63, 0x79, 0x63, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x37, 0x0a, 0x09, 0x6c, 0x69, 0x66, 0x65, 0x63, 0x79, 0x63, 0x6c, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, + 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x4c, 0x69, 0x66, 0x65, 0x63, 0x79, 0x63, 0x6c, 0x65, 0x52, 0x09, + 0x6c, 0x69, 0x66, 0x65, 0x63, 0x79, 0x63, 0x6c, 0x65, 0x22, 0xc4, 0x01, 0x0a, 0x1b, 0x42, 0x61, + 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x70, 0x70, 0x48, 0x65, 0x61, 0x6c, + 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x52, 0x0a, 0x07, 0x75, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x38, 0x2e, 0x63, 0x6f, 0x64, + 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x42, 0x61, 0x74, 0x63, + 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x70, 0x70, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x52, 0x07, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x1a, 0x51, 0x0a, + 0x0c, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x0e, 0x0a, + 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, 0x69, 0x64, 0x12, 0x31, 0x0a, + 0x06, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x19, 0x2e, + 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x41, + 0x70, 0x70, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, 0x06, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, + 0x22, 0x1e, 0x0a, 0x1c, 0x42, 0x61, 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, + 0x70, 0x70, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0xe8, 0x01, 0x0a, 0x07, 0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x12, 0x18, 0x0a, 0x07, + 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, + 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x2d, 0x0a, 0x12, 0x65, 0x78, 0x70, 0x61, 0x6e, 0x64, + 0x65, 0x64, 0x5f, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x11, 0x65, 0x78, 0x70, 0x61, 0x6e, 0x64, 0x65, 0x64, 0x44, 0x69, 0x72, 0x65, + 0x63, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x41, 0x0a, 0x0a, 0x73, 0x75, 0x62, 0x73, 0x79, 0x73, 0x74, + 0x65, 0x6d, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x21, 0x2e, 0x63, 0x6f, 0x64, 0x65, + 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, + 0x75, 0x70, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x52, 0x0a, 0x73, 0x75, + 0x62, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x73, 0x22, 0x51, 0x0a, 0x09, 0x53, 0x75, 0x62, 0x73, + 0x79, 0x73, 0x74, 0x65, 0x6d, 0x12, 0x19, 0x0a, 0x15, 0x53, 0x55, 0x42, 0x53, 0x59, 0x53, 0x54, + 0x45, 0x4d, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, + 0x12, 0x0a, 0x0a, 0x06, 0x45, 0x4e, 0x56, 0x42, 0x4f, 0x58, 0x10, 0x01, 0x12, 0x0e, 0x0a, 0x0a, + 0x45, 0x4e, 0x56, 0x42, 0x55, 0x49, 0x4c, 0x44, 0x45, 0x52, 0x10, 0x02, 0x12, 0x0d, 0x0a, 0x09, + 0x45, 0x58, 0x45, 0x43, 0x54, 0x52, 0x41, 0x43, 0x45, 0x10, 0x03, 0x22, 0x49, 0x0a, 0x14, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x31, 0x0a, 0x07, 0x73, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, + 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x52, 0x07, 0x73, + 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x22, 0x63, 0x0a, 0x08, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, + 0x74, 0x61, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x03, 0x6b, 0x65, 0x79, 0x12, 0x45, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, + 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x41, + 0x67, 0x65, 0x6e, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x65, 0x73, + 0x75, 0x6c, 0x74, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x52, 0x0a, 0x1a, 0x42, + 0x61, 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, + 0x74, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x34, 0x0a, 0x08, 0x6d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x63, 0x6f, + 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x4d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x22, + 0x1d, 0x0a, 0x1b, 0x42, 0x61, 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xde, + 0x01, 0x0a, 0x03, 0x4c, 0x6f, 0x67, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x64, 0x5f, 0x61, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, + 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, + 0x74, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x12, 0x2f, 0x0a, 0x05, 0x6c, 0x65, 0x76, + 0x65, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x19, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, + 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x4c, 0x6f, 0x67, 0x2e, 0x4c, 0x65, + 0x76, 0x65, 0x6c, 0x52, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x22, 0x53, 0x0a, 0x05, 0x4c, 0x65, + 0x76, 0x65, 0x6c, 0x12, 0x15, 0x0a, 0x11, 0x4c, 0x45, 0x56, 0x45, 0x4c, 0x5f, 0x55, 0x4e, 0x53, + 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x54, 0x52, + 0x41, 0x43, 0x45, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x44, 0x45, 0x42, 0x55, 0x47, 0x10, 0x02, + 0x12, 0x08, 0x0a, 0x04, 0x49, 0x4e, 0x46, 0x4f, 0x10, 0x03, 0x12, 0x08, 0x0a, 0x04, 0x57, 0x41, + 0x52, 0x4e, 0x10, 0x04, 0x12, 0x09, 0x0a, 0x05, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x05, 0x22, + 0x65, 0x0a, 0x16, 0x42, 0x61, 0x74, 0x63, 0x68, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4c, 0x6f, + 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x22, 0x0a, 0x0d, 0x6c, 0x6f, 0x67, + 0x5f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x0b, 0x6c, 0x6f, 0x67, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x64, 0x12, 0x27, 0x0a, + 0x04, 0x6c, 0x6f, 0x67, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x63, 0x6f, + 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x4c, 0x6f, 0x67, + 0x52, 0x04, 0x6c, 0x6f, 0x67, 0x73, 0x22, 0x47, 0x0a, 0x17, 0x42, 0x61, 0x74, 0x63, 0x68, 0x43, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x2c, 0x0a, 0x12, 0x6c, 0x6f, 0x67, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x5f, 0x65, + 0x78, 0x63, 0x65, 0x65, 0x64, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x6c, + 0x6f, 0x67, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x45, 0x78, 0x63, 0x65, 0x65, 0x64, 0x65, 0x64, 0x22, + 0x1f, 0x0a, 0x1d, 0x47, 0x65, 0x74, 0x41, 0x6e, 0x6e, 0x6f, 0x75, 0x6e, 0x63, 0x65, 0x6d, 0x65, + 0x6e, 0x74, 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x22, 0x71, 0x0a, 0x1e, 0x47, 0x65, 0x74, 0x41, 0x6e, 0x6e, 0x6f, 0x75, 0x6e, 0x63, 0x65, 0x6d, + 0x65, 0x6e, 0x74, 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x4f, 0x0a, 0x14, 0x61, 0x6e, 0x6e, 0x6f, 0x75, 0x6e, 0x63, 0x65, 0x6d, 0x65, + 0x6e, 0x74, 0x5f, 0x62, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x1c, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, + 0x32, 0x2e, 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x13, + 0x61, 0x6e, 0x6e, 0x6f, 0x75, 0x6e, 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x61, 0x6e, 0x6e, + 0x65, 0x72, 0x73, 0x22, 0x6d, 0x0a, 0x0c, 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x43, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x18, 0x0a, + 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, + 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x29, 0x0a, 0x10, 0x62, 0x61, 0x63, 0x6b, 0x67, + 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0f, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x43, 0x6f, 0x6c, + 0x6f, 0x72, 0x22, 0x56, 0x0a, 0x24, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x41, + 0x67, 0x65, 0x6e, 0x74, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, + 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2e, 0x0a, 0x06, 0x74, 0x69, + 0x6d, 0x69, 0x6e, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x63, 0x6f, 0x64, + 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x54, 0x69, 0x6d, 0x69, + 0x6e, 0x67, 0x52, 0x06, 0x74, 0x69, 0x6d, 0x69, 0x6e, 0x67, 0x22, 0x27, 0x0a, 0x25, 0x57, 0x6f, + 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x53, 0x63, 0x72, 0x69, + 0x70, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0xa8, 0x01, 0x0a, 0x06, 0x54, 0x69, 0x6d, 0x69, 0x6e, 0x67, 0x12, 0x21, + 0x0a, 0x0c, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, + 0x65, 0x12, 0x30, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x05, 0x73, 0x74, + 0x61, 0x72, 0x74, 0x12, 0x2c, 0x0a, 0x03, 0x65, 0x6e, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x03, 0x65, 0x6e, + 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x65, 0x78, 0x69, 0x74, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x65, 0x78, 0x69, 0x74, 0x43, 0x6f, 0x64, 0x65, 0x2a, 0x63, + 0x0a, 0x09, 0x41, 0x70, 0x70, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x12, 0x1a, 0x0a, 0x16, 0x41, + 0x50, 0x50, 0x5f, 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, + 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x44, 0x49, 0x53, 0x41, 0x42, + 0x4c, 0x45, 0x44, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x49, 0x4e, 0x49, 0x54, 0x49, 0x41, 0x4c, + 0x49, 0x5a, 0x49, 0x4e, 0x47, 0x10, 0x02, 0x12, 0x0b, 0x0a, 0x07, 0x48, 0x45, 0x41, 0x4c, 0x54, + 0x48, 0x59, 0x10, 0x03, 0x12, 0x0d, 0x0a, 0x09, 0x55, 0x4e, 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, + 0x59, 0x10, 0x04, 0x32, 0xef, 0x07, 0x0a, 0x05, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x12, 0x4b, 0x0a, + 0x0b, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x12, 0x22, 0x2e, 0x63, + 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, + 0x74, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x18, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, + 0x32, 0x2e, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x12, 0x5a, 0x0a, 0x10, 0x47, 0x65, + 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x12, 0x27, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, - 0x42, 0x61, 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x70, 0x70, 0x48, 0x65, - 0x61, 0x6c, 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x63, 0x6f, + 0x47, 0x65, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, + 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x12, 0x56, 0x0a, 0x0b, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x22, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, + 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, + 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x63, 0x6f, 0x64, 0x65, + 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x54, + 0x0a, 0x0f, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4c, 0x69, 0x66, 0x65, 0x63, 0x79, 0x63, 0x6c, + 0x65, 0x12, 0x26, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, + 0x76, 0x32, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4c, 0x69, 0x66, 0x65, 0x63, 0x79, 0x63, + 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x63, 0x6f, 0x64, 0x65, + 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x4c, 0x69, 0x66, 0x65, 0x63, + 0x79, 0x63, 0x6c, 0x65, 0x12, 0x72, 0x0a, 0x15, 0x42, 0x61, 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x41, 0x70, 0x70, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x73, 0x12, 0x2b, 0x2e, + 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x42, + 0x61, 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x70, 0x70, 0x48, 0x65, 0x61, + 0x6c, 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x63, 0x6f, 0x64, + 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x42, 0x61, 0x74, 0x63, + 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x70, 0x70, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4e, 0x0a, 0x0d, 0x55, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x12, 0x24, 0x2e, 0x63, 0x6f, 0x64, 0x65, + 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x17, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, + 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x12, 0x6e, 0x0a, 0x13, 0x42, 0x61, 0x74, 0x63, + 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, + 0x2a, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, + 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x42, 0x61, 0x74, - 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x70, 0x70, 0x48, 0x65, 0x61, 0x6c, 0x74, - 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4e, 0x0a, 0x0d, 0x55, 0x70, 0x64, - 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x12, 0x24, 0x2e, 0x63, 0x6f, 0x64, - 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x17, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, - 0x32, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x12, 0x6e, 0x0a, 0x13, 0x42, 0x61, 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, - 0x12, 0x2a, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, - 0x32, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x74, - 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x63, - 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x42, 0x61, - 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, - 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x62, 0x0a, 0x0f, 0x42, 0x61, 0x74, - 0x63, 0x68, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4c, 0x6f, 0x67, 0x73, 0x12, 0x26, 0x2e, 0x63, - 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x42, 0x61, - 0x74, 0x63, 0x68, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, - 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x43, 0x72, 0x65, 0x61, 0x74, - 0x65, 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x77, 0x0a, - 0x16, 0x47, 0x65, 0x74, 0x41, 0x6e, 0x6e, 0x6f, 0x75, 0x6e, 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, - 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x73, 0x12, 0x2d, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, - 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x6e, 0x6e, 0x6f, - 0x75, 0x6e, 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x73, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x62, 0x0a, 0x0f, 0x42, 0x61, 0x74, 0x63, + 0x68, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4c, 0x6f, 0x67, 0x73, 0x12, 0x26, 0x2e, 0x63, 0x6f, + 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x42, 0x61, 0x74, + 0x63, 0x68, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, + 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x77, 0x0a, 0x16, + 0x47, 0x65, 0x74, 0x41, 0x6e, 0x6e, 0x6f, 0x75, 0x6e, 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, + 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x73, 0x12, 0x2d, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x6e, 0x6e, 0x6f, 0x75, 0x6e, 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x73, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x27, 0x5a, 0x25, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, - 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2f, 0x63, 0x6f, 0x64, 0x65, 0x72, - 0x2f, 0x76, 0x32, 0x2f, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, + 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x6e, 0x6e, 0x6f, 0x75, 0x6e, + 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7e, 0x0a, 0x0f, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x43, + 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x12, 0x34, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, + 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, + 0x61, 0x63, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x43, 0x6f, + 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x35, + 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, + 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x53, 0x63, + 0x72, 0x69, 0x70, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x27, 0x5a, 0x25, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, + 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2f, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2f, + 0x76, 0x32, 0x2f, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -2848,110 +3041,118 @@ func file_agent_proto_agent_proto_rawDescGZIP() []byte { } var file_agent_proto_agent_proto_enumTypes = make([]protoimpl.EnumInfo, 7) -var file_agent_proto_agent_proto_msgTypes = make([]protoimpl.MessageInfo, 33) +var file_agent_proto_agent_proto_msgTypes = make([]protoimpl.MessageInfo, 36) var file_agent_proto_agent_proto_goTypes = []interface{}{ - (AppHealth)(0), // 0: coder.agent.v2.AppHealth - (WorkspaceApp_SharingLevel)(0), // 1: coder.agent.v2.WorkspaceApp.SharingLevel - (WorkspaceApp_Health)(0), // 2: coder.agent.v2.WorkspaceApp.Health - (Stats_Metric_Type)(0), // 3: coder.agent.v2.Stats.Metric.Type - (Lifecycle_State)(0), // 4: coder.agent.v2.Lifecycle.State - (Startup_Subsystem)(0), // 5: coder.agent.v2.Startup.Subsystem - (Log_Level)(0), // 6: coder.agent.v2.Log.Level - (*WorkspaceApp)(nil), // 7: coder.agent.v2.WorkspaceApp - (*WorkspaceAgentScript)(nil), // 8: coder.agent.v2.WorkspaceAgentScript - (*WorkspaceAgentMetadata)(nil), // 9: coder.agent.v2.WorkspaceAgentMetadata - (*Manifest)(nil), // 10: coder.agent.v2.Manifest - (*GetManifestRequest)(nil), // 11: coder.agent.v2.GetManifestRequest - (*ServiceBanner)(nil), // 12: coder.agent.v2.ServiceBanner - (*GetServiceBannerRequest)(nil), // 13: coder.agent.v2.GetServiceBannerRequest - (*Stats)(nil), // 14: coder.agent.v2.Stats - (*UpdateStatsRequest)(nil), // 15: coder.agent.v2.UpdateStatsRequest - (*UpdateStatsResponse)(nil), // 16: coder.agent.v2.UpdateStatsResponse - (*Lifecycle)(nil), // 17: coder.agent.v2.Lifecycle - (*UpdateLifecycleRequest)(nil), // 18: coder.agent.v2.UpdateLifecycleRequest - (*BatchUpdateAppHealthRequest)(nil), // 19: coder.agent.v2.BatchUpdateAppHealthRequest - (*BatchUpdateAppHealthResponse)(nil), // 20: coder.agent.v2.BatchUpdateAppHealthResponse - (*Startup)(nil), // 21: coder.agent.v2.Startup - (*UpdateStartupRequest)(nil), // 22: coder.agent.v2.UpdateStartupRequest - (*Metadata)(nil), // 23: coder.agent.v2.Metadata - (*BatchUpdateMetadataRequest)(nil), // 24: coder.agent.v2.BatchUpdateMetadataRequest - (*BatchUpdateMetadataResponse)(nil), // 25: coder.agent.v2.BatchUpdateMetadataResponse - (*Log)(nil), // 26: coder.agent.v2.Log - (*BatchCreateLogsRequest)(nil), // 27: coder.agent.v2.BatchCreateLogsRequest - (*BatchCreateLogsResponse)(nil), // 28: coder.agent.v2.BatchCreateLogsResponse - (*GetAnnouncementBannersRequest)(nil), // 29: coder.agent.v2.GetAnnouncementBannersRequest - (*GetAnnouncementBannersResponse)(nil), // 30: coder.agent.v2.GetAnnouncementBannersResponse - (*BannerConfig)(nil), // 31: coder.agent.v2.BannerConfig - (*WorkspaceApp_Healthcheck)(nil), // 32: coder.agent.v2.WorkspaceApp.Healthcheck - (*WorkspaceAgentMetadata_Result)(nil), // 33: coder.agent.v2.WorkspaceAgentMetadata.Result - (*WorkspaceAgentMetadata_Description)(nil), // 34: coder.agent.v2.WorkspaceAgentMetadata.Description - nil, // 35: coder.agent.v2.Manifest.EnvironmentVariablesEntry - nil, // 36: coder.agent.v2.Stats.ConnectionsByProtoEntry - (*Stats_Metric)(nil), // 37: coder.agent.v2.Stats.Metric - (*Stats_Metric_Label)(nil), // 38: coder.agent.v2.Stats.Metric.Label - (*BatchUpdateAppHealthRequest_HealthUpdate)(nil), // 39: coder.agent.v2.BatchUpdateAppHealthRequest.HealthUpdate - (*durationpb.Duration)(nil), // 40: google.protobuf.Duration - (*proto.DERPMap)(nil), // 41: coder.tailnet.v2.DERPMap - (*timestamppb.Timestamp)(nil), // 42: google.protobuf.Timestamp + (AppHealth)(0), // 0: coder.agent.v2.AppHealth + (WorkspaceApp_SharingLevel)(0), // 1: coder.agent.v2.WorkspaceApp.SharingLevel + (WorkspaceApp_Health)(0), // 2: coder.agent.v2.WorkspaceApp.Health + (Stats_Metric_Type)(0), // 3: coder.agent.v2.Stats.Metric.Type + (Lifecycle_State)(0), // 4: coder.agent.v2.Lifecycle.State + (Startup_Subsystem)(0), // 5: coder.agent.v2.Startup.Subsystem + (Log_Level)(0), // 6: coder.agent.v2.Log.Level + (*WorkspaceApp)(nil), // 7: coder.agent.v2.WorkspaceApp + (*WorkspaceAgentScript)(nil), // 8: coder.agent.v2.WorkspaceAgentScript + (*WorkspaceAgentMetadata)(nil), // 9: coder.agent.v2.WorkspaceAgentMetadata + (*Manifest)(nil), // 10: coder.agent.v2.Manifest + (*GetManifestRequest)(nil), // 11: coder.agent.v2.GetManifestRequest + (*ServiceBanner)(nil), // 12: coder.agent.v2.ServiceBanner + (*GetServiceBannerRequest)(nil), // 13: coder.agent.v2.GetServiceBannerRequest + (*Stats)(nil), // 14: coder.agent.v2.Stats + (*UpdateStatsRequest)(nil), // 15: coder.agent.v2.UpdateStatsRequest + (*UpdateStatsResponse)(nil), // 16: coder.agent.v2.UpdateStatsResponse + (*Lifecycle)(nil), // 17: coder.agent.v2.Lifecycle + (*UpdateLifecycleRequest)(nil), // 18: coder.agent.v2.UpdateLifecycleRequest + (*BatchUpdateAppHealthRequest)(nil), // 19: coder.agent.v2.BatchUpdateAppHealthRequest + (*BatchUpdateAppHealthResponse)(nil), // 20: coder.agent.v2.BatchUpdateAppHealthResponse + (*Startup)(nil), // 21: coder.agent.v2.Startup + (*UpdateStartupRequest)(nil), // 22: coder.agent.v2.UpdateStartupRequest + (*Metadata)(nil), // 23: coder.agent.v2.Metadata + (*BatchUpdateMetadataRequest)(nil), // 24: coder.agent.v2.BatchUpdateMetadataRequest + (*BatchUpdateMetadataResponse)(nil), // 25: coder.agent.v2.BatchUpdateMetadataResponse + (*Log)(nil), // 26: coder.agent.v2.Log + (*BatchCreateLogsRequest)(nil), // 27: coder.agent.v2.BatchCreateLogsRequest + (*BatchCreateLogsResponse)(nil), // 28: coder.agent.v2.BatchCreateLogsResponse + (*GetAnnouncementBannersRequest)(nil), // 29: coder.agent.v2.GetAnnouncementBannersRequest + (*GetAnnouncementBannersResponse)(nil), // 30: coder.agent.v2.GetAnnouncementBannersResponse + (*BannerConfig)(nil), // 31: coder.agent.v2.BannerConfig + (*WorkspaceAgentScriptCompletedRequest)(nil), // 32: coder.agent.v2.WorkspaceAgentScriptCompletedRequest + (*WorkspaceAgentScriptCompletedResponse)(nil), // 33: coder.agent.v2.WorkspaceAgentScriptCompletedResponse + (*Timing)(nil), // 34: coder.agent.v2.Timing + (*WorkspaceApp_Healthcheck)(nil), // 35: coder.agent.v2.WorkspaceApp.Healthcheck + (*WorkspaceAgentMetadata_Result)(nil), // 36: coder.agent.v2.WorkspaceAgentMetadata.Result + (*WorkspaceAgentMetadata_Description)(nil), // 37: coder.agent.v2.WorkspaceAgentMetadata.Description + nil, // 38: coder.agent.v2.Manifest.EnvironmentVariablesEntry + nil, // 39: coder.agent.v2.Stats.ConnectionsByProtoEntry + (*Stats_Metric)(nil), // 40: coder.agent.v2.Stats.Metric + (*Stats_Metric_Label)(nil), // 41: coder.agent.v2.Stats.Metric.Label + (*BatchUpdateAppHealthRequest_HealthUpdate)(nil), // 42: coder.agent.v2.BatchUpdateAppHealthRequest.HealthUpdate + (*durationpb.Duration)(nil), // 43: google.protobuf.Duration + (*proto.DERPMap)(nil), // 44: coder.tailnet.v2.DERPMap + (*timestamppb.Timestamp)(nil), // 45: google.protobuf.Timestamp } var file_agent_proto_agent_proto_depIdxs = []int32{ 1, // 0: coder.agent.v2.WorkspaceApp.sharing_level:type_name -> coder.agent.v2.WorkspaceApp.SharingLevel - 32, // 1: coder.agent.v2.WorkspaceApp.healthcheck:type_name -> coder.agent.v2.WorkspaceApp.Healthcheck + 35, // 1: coder.agent.v2.WorkspaceApp.healthcheck:type_name -> coder.agent.v2.WorkspaceApp.Healthcheck 2, // 2: coder.agent.v2.WorkspaceApp.health:type_name -> coder.agent.v2.WorkspaceApp.Health - 40, // 3: coder.agent.v2.WorkspaceAgentScript.timeout:type_name -> google.protobuf.Duration - 33, // 4: coder.agent.v2.WorkspaceAgentMetadata.result:type_name -> coder.agent.v2.WorkspaceAgentMetadata.Result - 34, // 5: coder.agent.v2.WorkspaceAgentMetadata.description:type_name -> coder.agent.v2.WorkspaceAgentMetadata.Description - 35, // 6: coder.agent.v2.Manifest.environment_variables:type_name -> coder.agent.v2.Manifest.EnvironmentVariablesEntry - 41, // 7: coder.agent.v2.Manifest.derp_map:type_name -> coder.tailnet.v2.DERPMap + 43, // 3: coder.agent.v2.WorkspaceAgentScript.timeout:type_name -> google.protobuf.Duration + 36, // 4: coder.agent.v2.WorkspaceAgentMetadata.result:type_name -> coder.agent.v2.WorkspaceAgentMetadata.Result + 37, // 5: coder.agent.v2.WorkspaceAgentMetadata.description:type_name -> coder.agent.v2.WorkspaceAgentMetadata.Description + 38, // 6: coder.agent.v2.Manifest.environment_variables:type_name -> coder.agent.v2.Manifest.EnvironmentVariablesEntry + 44, // 7: coder.agent.v2.Manifest.derp_map:type_name -> coder.tailnet.v2.DERPMap 8, // 8: coder.agent.v2.Manifest.scripts:type_name -> coder.agent.v2.WorkspaceAgentScript 7, // 9: coder.agent.v2.Manifest.apps:type_name -> coder.agent.v2.WorkspaceApp - 34, // 10: coder.agent.v2.Manifest.metadata:type_name -> coder.agent.v2.WorkspaceAgentMetadata.Description - 36, // 11: coder.agent.v2.Stats.connections_by_proto:type_name -> coder.agent.v2.Stats.ConnectionsByProtoEntry - 37, // 12: coder.agent.v2.Stats.metrics:type_name -> coder.agent.v2.Stats.Metric + 37, // 10: coder.agent.v2.Manifest.metadata:type_name -> coder.agent.v2.WorkspaceAgentMetadata.Description + 39, // 11: coder.agent.v2.Stats.connections_by_proto:type_name -> coder.agent.v2.Stats.ConnectionsByProtoEntry + 40, // 12: coder.agent.v2.Stats.metrics:type_name -> coder.agent.v2.Stats.Metric 14, // 13: coder.agent.v2.UpdateStatsRequest.stats:type_name -> coder.agent.v2.Stats - 40, // 14: coder.agent.v2.UpdateStatsResponse.report_interval:type_name -> google.protobuf.Duration + 43, // 14: coder.agent.v2.UpdateStatsResponse.report_interval:type_name -> google.protobuf.Duration 4, // 15: coder.agent.v2.Lifecycle.state:type_name -> coder.agent.v2.Lifecycle.State - 42, // 16: coder.agent.v2.Lifecycle.changed_at:type_name -> google.protobuf.Timestamp + 45, // 16: coder.agent.v2.Lifecycle.changed_at:type_name -> google.protobuf.Timestamp 17, // 17: coder.agent.v2.UpdateLifecycleRequest.lifecycle:type_name -> coder.agent.v2.Lifecycle - 39, // 18: coder.agent.v2.BatchUpdateAppHealthRequest.updates:type_name -> coder.agent.v2.BatchUpdateAppHealthRequest.HealthUpdate + 42, // 18: coder.agent.v2.BatchUpdateAppHealthRequest.updates:type_name -> coder.agent.v2.BatchUpdateAppHealthRequest.HealthUpdate 5, // 19: coder.agent.v2.Startup.subsystems:type_name -> coder.agent.v2.Startup.Subsystem 21, // 20: coder.agent.v2.UpdateStartupRequest.startup:type_name -> coder.agent.v2.Startup - 33, // 21: coder.agent.v2.Metadata.result:type_name -> coder.agent.v2.WorkspaceAgentMetadata.Result + 36, // 21: coder.agent.v2.Metadata.result:type_name -> coder.agent.v2.WorkspaceAgentMetadata.Result 23, // 22: coder.agent.v2.BatchUpdateMetadataRequest.metadata:type_name -> coder.agent.v2.Metadata - 42, // 23: coder.agent.v2.Log.created_at:type_name -> google.protobuf.Timestamp + 45, // 23: coder.agent.v2.Log.created_at:type_name -> google.protobuf.Timestamp 6, // 24: coder.agent.v2.Log.level:type_name -> coder.agent.v2.Log.Level 26, // 25: coder.agent.v2.BatchCreateLogsRequest.logs:type_name -> coder.agent.v2.Log 31, // 26: coder.agent.v2.GetAnnouncementBannersResponse.announcement_banners:type_name -> coder.agent.v2.BannerConfig - 40, // 27: coder.agent.v2.WorkspaceApp.Healthcheck.interval:type_name -> google.protobuf.Duration - 42, // 28: coder.agent.v2.WorkspaceAgentMetadata.Result.collected_at:type_name -> google.protobuf.Timestamp - 40, // 29: coder.agent.v2.WorkspaceAgentMetadata.Description.interval:type_name -> google.protobuf.Duration - 40, // 30: coder.agent.v2.WorkspaceAgentMetadata.Description.timeout:type_name -> google.protobuf.Duration - 3, // 31: coder.agent.v2.Stats.Metric.type:type_name -> coder.agent.v2.Stats.Metric.Type - 38, // 32: coder.agent.v2.Stats.Metric.labels:type_name -> coder.agent.v2.Stats.Metric.Label - 0, // 33: coder.agent.v2.BatchUpdateAppHealthRequest.HealthUpdate.health:type_name -> coder.agent.v2.AppHealth - 11, // 34: coder.agent.v2.Agent.GetManifest:input_type -> coder.agent.v2.GetManifestRequest - 13, // 35: coder.agent.v2.Agent.GetServiceBanner:input_type -> coder.agent.v2.GetServiceBannerRequest - 15, // 36: coder.agent.v2.Agent.UpdateStats:input_type -> coder.agent.v2.UpdateStatsRequest - 18, // 37: coder.agent.v2.Agent.UpdateLifecycle:input_type -> coder.agent.v2.UpdateLifecycleRequest - 19, // 38: coder.agent.v2.Agent.BatchUpdateAppHealths:input_type -> coder.agent.v2.BatchUpdateAppHealthRequest - 22, // 39: coder.agent.v2.Agent.UpdateStartup:input_type -> coder.agent.v2.UpdateStartupRequest - 24, // 40: coder.agent.v2.Agent.BatchUpdateMetadata:input_type -> coder.agent.v2.BatchUpdateMetadataRequest - 27, // 41: coder.agent.v2.Agent.BatchCreateLogs:input_type -> coder.agent.v2.BatchCreateLogsRequest - 29, // 42: coder.agent.v2.Agent.GetAnnouncementBanners:input_type -> coder.agent.v2.GetAnnouncementBannersRequest - 10, // 43: coder.agent.v2.Agent.GetManifest:output_type -> coder.agent.v2.Manifest - 12, // 44: coder.agent.v2.Agent.GetServiceBanner:output_type -> coder.agent.v2.ServiceBanner - 16, // 45: coder.agent.v2.Agent.UpdateStats:output_type -> coder.agent.v2.UpdateStatsResponse - 17, // 46: coder.agent.v2.Agent.UpdateLifecycle:output_type -> coder.agent.v2.Lifecycle - 20, // 47: coder.agent.v2.Agent.BatchUpdateAppHealths:output_type -> coder.agent.v2.BatchUpdateAppHealthResponse - 21, // 48: coder.agent.v2.Agent.UpdateStartup:output_type -> coder.agent.v2.Startup - 25, // 49: coder.agent.v2.Agent.BatchUpdateMetadata:output_type -> coder.agent.v2.BatchUpdateMetadataResponse - 28, // 50: coder.agent.v2.Agent.BatchCreateLogs:output_type -> coder.agent.v2.BatchCreateLogsResponse - 30, // 51: coder.agent.v2.Agent.GetAnnouncementBanners:output_type -> coder.agent.v2.GetAnnouncementBannersResponse - 43, // [43:52] is the sub-list for method output_type - 34, // [34:43] is the sub-list for method input_type - 34, // [34:34] is the sub-list for extension type_name - 34, // [34:34] is the sub-list for extension extendee - 0, // [0:34] is the sub-list for field type_name + 34, // 27: coder.agent.v2.WorkspaceAgentScriptCompletedRequest.timing:type_name -> coder.agent.v2.Timing + 45, // 28: coder.agent.v2.Timing.start:type_name -> google.protobuf.Timestamp + 45, // 29: coder.agent.v2.Timing.end:type_name -> google.protobuf.Timestamp + 43, // 30: coder.agent.v2.WorkspaceApp.Healthcheck.interval:type_name -> google.protobuf.Duration + 45, // 31: coder.agent.v2.WorkspaceAgentMetadata.Result.collected_at:type_name -> google.protobuf.Timestamp + 43, // 32: coder.agent.v2.WorkspaceAgentMetadata.Description.interval:type_name -> google.protobuf.Duration + 43, // 33: coder.agent.v2.WorkspaceAgentMetadata.Description.timeout:type_name -> google.protobuf.Duration + 3, // 34: coder.agent.v2.Stats.Metric.type:type_name -> coder.agent.v2.Stats.Metric.Type + 41, // 35: coder.agent.v2.Stats.Metric.labels:type_name -> coder.agent.v2.Stats.Metric.Label + 0, // 36: coder.agent.v2.BatchUpdateAppHealthRequest.HealthUpdate.health:type_name -> coder.agent.v2.AppHealth + 11, // 37: coder.agent.v2.Agent.GetManifest:input_type -> coder.agent.v2.GetManifestRequest + 13, // 38: coder.agent.v2.Agent.GetServiceBanner:input_type -> coder.agent.v2.GetServiceBannerRequest + 15, // 39: coder.agent.v2.Agent.UpdateStats:input_type -> coder.agent.v2.UpdateStatsRequest + 18, // 40: coder.agent.v2.Agent.UpdateLifecycle:input_type -> coder.agent.v2.UpdateLifecycleRequest + 19, // 41: coder.agent.v2.Agent.BatchUpdateAppHealths:input_type -> coder.agent.v2.BatchUpdateAppHealthRequest + 22, // 42: coder.agent.v2.Agent.UpdateStartup:input_type -> coder.agent.v2.UpdateStartupRequest + 24, // 43: coder.agent.v2.Agent.BatchUpdateMetadata:input_type -> coder.agent.v2.BatchUpdateMetadataRequest + 27, // 44: coder.agent.v2.Agent.BatchCreateLogs:input_type -> coder.agent.v2.BatchCreateLogsRequest + 29, // 45: coder.agent.v2.Agent.GetAnnouncementBanners:input_type -> coder.agent.v2.GetAnnouncementBannersRequest + 32, // 46: coder.agent.v2.Agent.ScriptCompleted:input_type -> coder.agent.v2.WorkspaceAgentScriptCompletedRequest + 10, // 47: coder.agent.v2.Agent.GetManifest:output_type -> coder.agent.v2.Manifest + 12, // 48: coder.agent.v2.Agent.GetServiceBanner:output_type -> coder.agent.v2.ServiceBanner + 16, // 49: coder.agent.v2.Agent.UpdateStats:output_type -> coder.agent.v2.UpdateStatsResponse + 17, // 50: coder.agent.v2.Agent.UpdateLifecycle:output_type -> coder.agent.v2.Lifecycle + 20, // 51: coder.agent.v2.Agent.BatchUpdateAppHealths:output_type -> coder.agent.v2.BatchUpdateAppHealthResponse + 21, // 52: coder.agent.v2.Agent.UpdateStartup:output_type -> coder.agent.v2.Startup + 25, // 53: coder.agent.v2.Agent.BatchUpdateMetadata:output_type -> coder.agent.v2.BatchUpdateMetadataResponse + 28, // 54: coder.agent.v2.Agent.BatchCreateLogs:output_type -> coder.agent.v2.BatchCreateLogsResponse + 30, // 55: coder.agent.v2.Agent.GetAnnouncementBanners:output_type -> coder.agent.v2.GetAnnouncementBannersResponse + 33, // 56: coder.agent.v2.Agent.ScriptCompleted:output_type -> coder.agent.v2.WorkspaceAgentScriptCompletedResponse + 47, // [47:57] is the sub-list for method output_type + 37, // [37:47] is the sub-list for method input_type + 37, // [37:37] is the sub-list for extension type_name + 37, // [37:37] is the sub-list for extension extendee + 0, // [0:37] is the sub-list for field type_name } func init() { file_agent_proto_agent_proto_init() } @@ -3261,7 +3462,7 @@ func file_agent_proto_agent_proto_init() { } } file_agent_proto_agent_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*WorkspaceApp_Healthcheck); i { + switch v := v.(*WorkspaceAgentScriptCompletedRequest); i { case 0: return &v.state case 1: @@ -3273,7 +3474,7 @@ func file_agent_proto_agent_proto_init() { } } file_agent_proto_agent_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*WorkspaceAgentMetadata_Result); i { + switch v := v.(*WorkspaceAgentScriptCompletedResponse); i { case 0: return &v.state case 1: @@ -3285,7 +3486,31 @@ func file_agent_proto_agent_proto_init() { } } file_agent_proto_agent_proto_msgTypes[27].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*WorkspaceAgentMetadata_Description); i { + switch v := v.(*Timing); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_agent_proto_agent_proto_msgTypes[28].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*WorkspaceApp_Healthcheck); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_agent_proto_agent_proto_msgTypes[29].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*WorkspaceAgentMetadata_Result); i { case 0: return &v.state case 1: @@ -3297,6 +3522,18 @@ func file_agent_proto_agent_proto_init() { } } file_agent_proto_agent_proto_msgTypes[30].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*WorkspaceAgentMetadata_Description); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_agent_proto_agent_proto_msgTypes[33].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Stats_Metric); i { case 0: return &v.state @@ -3308,7 +3545,7 @@ func file_agent_proto_agent_proto_init() { return nil } } - file_agent_proto_agent_proto_msgTypes[31].Exporter = func(v interface{}, i int) interface{} { + file_agent_proto_agent_proto_msgTypes[34].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Stats_Metric_Label); i { case 0: return &v.state @@ -3320,7 +3557,7 @@ func file_agent_proto_agent_proto_init() { return nil } } - file_agent_proto_agent_proto_msgTypes[32].Exporter = func(v interface{}, i int) interface{} { + file_agent_proto_agent_proto_msgTypes[35].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*BatchUpdateAppHealthRequest_HealthUpdate); i { case 0: return &v.state @@ -3339,7 +3576,7 @@ func file_agent_proto_agent_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_agent_proto_agent_proto_rawDesc, NumEnums: 7, - NumMessages: 33, + NumMessages: 36, NumExtensions: 0, NumServices: 1, }, diff --git a/agent/proto/agent.proto b/agent/proto/agent.proto index 82e13330ea67f..21e6dd6b2b91a 100644 --- a/agent/proto/agent.proto +++ b/agent/proto/agent.proto @@ -53,6 +53,7 @@ message WorkspaceAgentScript { bool run_on_stop = 6; bool start_blocks_login = 7; google.protobuf.Duration timeout = 8; + string display_name = 9; } message WorkspaceAgentMetadata { @@ -264,6 +265,20 @@ message BannerConfig { string background_color = 3; } +message WorkspaceAgentScriptCompletedRequest { + Timing timing = 1; +} + +message WorkspaceAgentScriptCompletedResponse { +} + +message Timing { + string display_name = 1; + google.protobuf.Timestamp start = 2; + google.protobuf.Timestamp end = 3; + int32 exit_code = 4; +} + service Agent { rpc GetManifest(GetManifestRequest) returns (Manifest); rpc GetServiceBanner(GetServiceBannerRequest) returns (ServiceBanner); @@ -274,4 +289,5 @@ service Agent { rpc BatchUpdateMetadata(BatchUpdateMetadataRequest) returns (BatchUpdateMetadataResponse); rpc BatchCreateLogs(BatchCreateLogsRequest) returns (BatchCreateLogsResponse); rpc GetAnnouncementBanners(GetAnnouncementBannersRequest) returns (GetAnnouncementBannersResponse); + rpc ScriptCompleted(WorkspaceAgentScriptCompletedRequest) returns (WorkspaceAgentScriptCompletedResponse); } diff --git a/agent/proto/agent_drpc.pb.go b/agent/proto/agent_drpc.pb.go index 09b3c972c2ce6..7bb1957230d76 100644 --- a/agent/proto/agent_drpc.pb.go +++ b/agent/proto/agent_drpc.pb.go @@ -47,6 +47,7 @@ type DRPCAgentClient interface { BatchUpdateMetadata(ctx context.Context, in *BatchUpdateMetadataRequest) (*BatchUpdateMetadataResponse, error) BatchCreateLogs(ctx context.Context, in *BatchCreateLogsRequest) (*BatchCreateLogsResponse, error) GetAnnouncementBanners(ctx context.Context, in *GetAnnouncementBannersRequest) (*GetAnnouncementBannersResponse, error) + ScriptCompleted(ctx context.Context, in *WorkspaceAgentScriptCompletedRequest) (*WorkspaceAgentScriptCompletedResponse, error) } type drpcAgentClient struct { @@ -140,6 +141,15 @@ func (c *drpcAgentClient) GetAnnouncementBanners(ctx context.Context, in *GetAnn return out, nil } +func (c *drpcAgentClient) ScriptCompleted(ctx context.Context, in *WorkspaceAgentScriptCompletedRequest) (*WorkspaceAgentScriptCompletedResponse, error) { + out := new(WorkspaceAgentScriptCompletedResponse) + err := c.cc.Invoke(ctx, "/coder.agent.v2.Agent/ScriptCompleted", drpcEncoding_File_agent_proto_agent_proto{}, in, out) + if err != nil { + return nil, err + } + return out, nil +} + type DRPCAgentServer interface { GetManifest(context.Context, *GetManifestRequest) (*Manifest, error) GetServiceBanner(context.Context, *GetServiceBannerRequest) (*ServiceBanner, error) @@ -150,6 +160,7 @@ type DRPCAgentServer interface { BatchUpdateMetadata(context.Context, *BatchUpdateMetadataRequest) (*BatchUpdateMetadataResponse, error) BatchCreateLogs(context.Context, *BatchCreateLogsRequest) (*BatchCreateLogsResponse, error) GetAnnouncementBanners(context.Context, *GetAnnouncementBannersRequest) (*GetAnnouncementBannersResponse, error) + ScriptCompleted(context.Context, *WorkspaceAgentScriptCompletedRequest) (*WorkspaceAgentScriptCompletedResponse, error) } type DRPCAgentUnimplementedServer struct{} @@ -190,9 +201,13 @@ func (s *DRPCAgentUnimplementedServer) GetAnnouncementBanners(context.Context, * return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented) } +func (s *DRPCAgentUnimplementedServer) ScriptCompleted(context.Context, *WorkspaceAgentScriptCompletedRequest) (*WorkspaceAgentScriptCompletedResponse, error) { + return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented) +} + type DRPCAgentDescription struct{} -func (DRPCAgentDescription) NumMethods() int { return 9 } +func (DRPCAgentDescription) NumMethods() int { return 10 } func (DRPCAgentDescription) Method(n int) (string, drpc.Encoding, drpc.Receiver, interface{}, bool) { switch n { @@ -277,6 +292,15 @@ func (DRPCAgentDescription) Method(n int) (string, drpc.Encoding, drpc.Receiver, in1.(*GetAnnouncementBannersRequest), ) }, DRPCAgentServer.GetAnnouncementBanners, true + case 9: + return "/coder.agent.v2.Agent/ScriptCompleted", drpcEncoding_File_agent_proto_agent_proto{}, + func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) { + return srv.(DRPCAgentServer). + ScriptCompleted( + ctx, + in1.(*WorkspaceAgentScriptCompletedRequest), + ) + }, DRPCAgentServer.ScriptCompleted, true default: return "", nil, nil, nil, false } @@ -429,3 +453,19 @@ func (x *drpcAgent_GetAnnouncementBannersStream) SendAndClose(m *GetAnnouncement } return x.CloseSend() } + +type DRPCAgent_ScriptCompletedStream interface { + drpc.Stream + SendAndClose(*WorkspaceAgentScriptCompletedResponse) error +} + +type drpcAgent_ScriptCompletedStream struct { + drpc.Stream +} + +func (x *drpcAgent_ScriptCompletedStream) SendAndClose(m *WorkspaceAgentScriptCompletedResponse) error { + if err := x.MsgSend(m, drpcEncoding_File_agent_proto_agent_proto{}); err != nil { + return err + } + return x.CloseSend() +} diff --git a/coderd/agentapi/api.go b/coderd/agentapi/api.go index 7aeb3a7de9d78..bea1fa5d881a3 100644 --- a/coderd/agentapi/api.go +++ b/coderd/agentapi/api.go @@ -42,6 +42,7 @@ type API struct { *AppsAPI *MetadataAPI *LogsAPI + *ScriptsAPI *tailnet.DRPCService mu sync.Mutex @@ -152,6 +153,10 @@ func New(opts Options) *API { PublishWorkspaceAgentLogsUpdateFn: opts.PublishWorkspaceAgentLogsUpdateFn, } + api.ScriptsAPI = &ScriptsAPI{ + Database: opts.Database, + } + api.DRPCService = &tailnet.DRPCService{ CoordPtr: opts.TailnetCoordinator, Logger: opts.Log, diff --git a/coderd/agentapi/manifest.go b/coderd/agentapi/manifest.go index 6791fe168b4f5..a78a07ccac8ed 100644 --- a/coderd/agentapi/manifest.go +++ b/coderd/agentapi/manifest.go @@ -178,6 +178,7 @@ func dbAgentScriptsToProto(scripts []database.WorkspaceAgentScript) []*agentprot func dbAgentScriptToProto(script database.WorkspaceAgentScript) *agentproto.WorkspaceAgentScript { return &agentproto.WorkspaceAgentScript{ + DisplayName: script.DisplayName, LogSourceId: script.LogSourceID[:], LogPath: script.LogPath, Script: script.Script, diff --git a/coderd/agentapi/scripts.go b/coderd/agentapi/scripts.go new file mode 100644 index 0000000000000..1d3791e03b6fd --- /dev/null +++ b/coderd/agentapi/scripts.go @@ -0,0 +1,28 @@ +package agentapi + +import ( + "context" + + agentproto "github.com/coder/coder/v2/agent/proto" + "github.com/coder/coder/v2/coderd/database" +) + +type ScriptsAPI struct { + Database database.Store +} + +func (s *ScriptsAPI) ScriptCompleted(ctx context.Context, req *agentproto.WorkspaceAgentScriptCompletedRequest) (*agentproto.WorkspaceAgentScriptCompletedResponse, error) { + res := &agentproto.WorkspaceAgentScriptCompletedResponse{} + + _, err := s.Database.InsertWorkspaceAgentScriptTimings(ctx, database.InsertWorkspaceAgentScriptTimingsParams{ + DisplayName: req.Timing.DisplayName, + StartedAt: req.Timing.Start.AsTime(), + EndedAt: req.Timing.End.AsTime(), + ExitCode: req.Timing.ExitCode, + }) + if err != nil { + return nil, err + } + + return res, nil +} diff --git a/coderd/database/dbauthz/dbauthz.go b/coderd/database/dbauthz/dbauthz.go index 568b988e054c8..02d4efb054a20 100644 --- a/coderd/database/dbauthz/dbauthz.go +++ b/coderd/database/dbauthz/dbauthz.go @@ -3027,6 +3027,12 @@ func (q *querier) InsertWorkspaceAgentMetadata(ctx context.Context, arg database return q.db.InsertWorkspaceAgentMetadata(ctx, arg) } +func (q *querier) InsertWorkspaceAgentScriptTimings(ctx context.Context, arg database.InsertWorkspaceAgentScriptTimingsParams) (database.WorkspaceAgentScriptTiming, error) { + // TODO: I have no idea what to add here. + + return q.db.InsertWorkspaceAgentScriptTimings(ctx, arg) +} + func (q *querier) InsertWorkspaceAgentScripts(ctx context.Context, arg database.InsertWorkspaceAgentScriptsParams) ([]database.WorkspaceAgentScript, error) { if err := q.authorizeContext(ctx, policy.ActionCreate, rbac.ResourceSystem); err != nil { return []database.WorkspaceAgentScript{}, err diff --git a/coderd/database/dbmem/dbmem.go b/coderd/database/dbmem/dbmem.go index 7a85fa4143a01..25f64448c5d78 100644 --- a/coderd/database/dbmem/dbmem.go +++ b/coderd/database/dbmem/dbmem.go @@ -222,6 +222,7 @@ type data struct { workspaceAgentLogs []database.WorkspaceAgentLog workspaceAgentLogSources []database.WorkspaceAgentLogSource workspaceAgentPortShares []database.WorkspaceAgentPortShare + workspaceAgentScriptTimings []database.WorkspaceAgentScriptTiming workspaceAgentScripts []database.WorkspaceAgentScript workspaceAgentStats []database.WorkspaceAgentStat workspaceApps []database.WorkspaceApp @@ -7826,6 +7827,26 @@ func (q *FakeQuerier) InsertWorkspaceAgentMetadata(_ context.Context, arg databa return nil } +func (q *FakeQuerier) InsertWorkspaceAgentScriptTimings(ctx context.Context, arg database.InsertWorkspaceAgentScriptTimingsParams) (database.WorkspaceAgentScriptTiming, error) { + err := validateDatabaseType(arg) + if err != nil { + return database.WorkspaceAgentScriptTiming{}, err + } + + q.mutex.Lock() + defer q.mutex.Unlock() + + scriptTiming := database.WorkspaceAgentScriptTiming{ + StartedAt: arg.StartedAt, + EndedAt: arg.EndedAt, + ExitCode: arg.ExitCode, + } + + q.workspaceAgentScriptTimings = append(q.workspaceAgentScriptTimings, scriptTiming) + + return scriptTiming, nil +} + func (q *FakeQuerier) InsertWorkspaceAgentScripts(_ context.Context, arg database.InsertWorkspaceAgentScriptsParams) ([]database.WorkspaceAgentScript, error) { err := validateDatabaseType(arg) if err != nil { @@ -7840,6 +7861,7 @@ func (q *FakeQuerier) InsertWorkspaceAgentScripts(_ context.Context, arg databas script := database.WorkspaceAgentScript{ LogSourceID: source, WorkspaceAgentID: arg.WorkspaceAgentID, + DisplayName: arg.DisplayName[index], LogPath: arg.LogPath[index], Script: arg.Script[index], Cron: arg.Cron[index], diff --git a/coderd/database/dbmetrics/dbmetrics.go b/coderd/database/dbmetrics/dbmetrics.go index f982c1db51686..37855f29aed18 100644 --- a/coderd/database/dbmetrics/dbmetrics.go +++ b/coderd/database/dbmetrics/dbmetrics.go @@ -1929,6 +1929,13 @@ func (m metricsStore) InsertWorkspaceAgentMetadata(ctx context.Context, arg data return err } +func (m metricsStore) InsertWorkspaceAgentScriptTimings(ctx context.Context, arg database.InsertWorkspaceAgentScriptTimingsParams) (database.WorkspaceAgentScriptTiming, error) { + start := time.Now() + r0, r1 := m.s.InsertWorkspaceAgentScriptTimings(ctx, arg) + m.queryLatencies.WithLabelValues("InsertWorkspaceAgentScriptTimings").Observe(time.Since(start).Seconds()) + return r0, r1 +} + func (m metricsStore) InsertWorkspaceAgentScripts(ctx context.Context, arg database.InsertWorkspaceAgentScriptsParams) ([]database.WorkspaceAgentScript, error) { start := time.Now() r0, r1 := m.s.InsertWorkspaceAgentScripts(ctx, arg) diff --git a/coderd/database/dbmock/dbmock.go b/coderd/database/dbmock/dbmock.go index 470e9cb491c47..7647aef27271f 100644 --- a/coderd/database/dbmock/dbmock.go +++ b/coderd/database/dbmock/dbmock.go @@ -4064,6 +4064,21 @@ func (mr *MockStoreMockRecorder) InsertWorkspaceAgentMetadata(arg0, arg1 any) *g return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InsertWorkspaceAgentMetadata", reflect.TypeOf((*MockStore)(nil).InsertWorkspaceAgentMetadata), arg0, arg1) } +// InsertWorkspaceAgentScriptTimings mocks base method. +func (m *MockStore) InsertWorkspaceAgentScriptTimings(arg0 context.Context, arg1 database.InsertWorkspaceAgentScriptTimingsParams) (database.WorkspaceAgentScriptTiming, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "InsertWorkspaceAgentScriptTimings", arg0, arg1) + ret0, _ := ret[0].(database.WorkspaceAgentScriptTiming) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// InsertWorkspaceAgentScriptTimings indicates an expected call of InsertWorkspaceAgentScriptTimings. +func (mr *MockStoreMockRecorder) InsertWorkspaceAgentScriptTimings(arg0, arg1 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InsertWorkspaceAgentScriptTimings", reflect.TypeOf((*MockStore)(nil).InsertWorkspaceAgentScriptTimings), arg0, arg1) +} + // InsertWorkspaceAgentScripts mocks base method. func (m *MockStore) InsertWorkspaceAgentScripts(arg0 context.Context, arg1 database.InsertWorkspaceAgentScriptsParams) ([]database.WorkspaceAgentScript, error) { m.ctrl.T.Helper() diff --git a/coderd/database/dump.sql b/coderd/database/dump.sql index fd0511d356552..d8d454af248fe 100644 --- a/coderd/database/dump.sql +++ b/coderd/database/dump.sql @@ -1355,6 +1355,13 @@ CREATE TABLE workspace_agent_port_share ( protocol port_share_protocol DEFAULT 'http'::port_share_protocol NOT NULL ); +CREATE TABLE workspace_agent_script_timings ( + display_name text NOT NULL, + started_at timestamp with time zone NOT NULL, + ended_at timestamp with time zone NOT NULL, + exit_code integer NOT NULL +); + CREATE TABLE workspace_agent_scripts ( workspace_agent_id uuid NOT NULL, log_source_id uuid NOT NULL, @@ -1365,7 +1372,8 @@ CREATE TABLE workspace_agent_scripts ( start_blocks_login boolean NOT NULL, run_on_start boolean NOT NULL, run_on_stop boolean NOT NULL, - timeout_seconds integer NOT NULL + timeout_seconds integer NOT NULL, + display_name text DEFAULT ''::text NOT NULL ); CREATE SEQUENCE workspace_agent_startup_logs_id_seq diff --git a/coderd/database/migrations/000250_workspace_agent_script_timings.down.sql b/coderd/database/migrations/000250_workspace_agent_script_timings.down.sql new file mode 100644 index 0000000000000..6be79a649ffed --- /dev/null +++ b/coderd/database/migrations/000250_workspace_agent_script_timings.down.sql @@ -0,0 +1,3 @@ +DROP TABLE IF EXISTS workspace_agent_script_timings; + +ALTER TABLE workspace_apps DROP COLUMN display_name; diff --git a/coderd/database/migrations/000250_workspace_agent_script_timings.up.sql b/coderd/database/migrations/000250_workspace_agent_script_timings.up.sql new file mode 100644 index 0000000000000..313a7d05a468a --- /dev/null +++ b/coderd/database/migrations/000250_workspace_agent_script_timings.up.sql @@ -0,0 +1,9 @@ +CREATE TABLE workspace_agent_script_timings +( + display_name text not null, + started_at timestamp with time zone not null, + ended_at timestamp with time zone not null, + exit_code int not null +); + +ALTER TABLE workspace_agent_scripts ADD COLUMN display_name text not null default ''; diff --git a/coderd/database/models.go b/coderd/database/models.go index b6a390ab8dfd5..79ac986ea07b2 100644 --- a/coderd/database/models.go +++ b/coderd/database/models.go @@ -2880,6 +2880,14 @@ type WorkspaceAgentScript struct { RunOnStart bool `db:"run_on_start" json:"run_on_start"` RunOnStop bool `db:"run_on_stop" json:"run_on_stop"` TimeoutSeconds int32 `db:"timeout_seconds" json:"timeout_seconds"` + DisplayName string `db:"display_name" json:"display_name"` +} + +type WorkspaceAgentScriptTiming struct { + DisplayName string `db:"display_name" json:"display_name"` + StartedAt time.Time `db:"started_at" json:"started_at"` + EndedAt time.Time `db:"ended_at" json:"ended_at"` + ExitCode int32 `db:"exit_code" json:"exit_code"` } type WorkspaceAgentStat struct { diff --git a/coderd/database/querier.go b/coderd/database/querier.go index cad3df1cd6834..1505d084c1dc4 100644 --- a/coderd/database/querier.go +++ b/coderd/database/querier.go @@ -394,6 +394,7 @@ type sqlcQuerier interface { InsertWorkspaceAgentLogSources(ctx context.Context, arg InsertWorkspaceAgentLogSourcesParams) ([]WorkspaceAgentLogSource, error) InsertWorkspaceAgentLogs(ctx context.Context, arg InsertWorkspaceAgentLogsParams) ([]WorkspaceAgentLog, error) InsertWorkspaceAgentMetadata(ctx context.Context, arg InsertWorkspaceAgentMetadataParams) error + InsertWorkspaceAgentScriptTimings(ctx context.Context, arg InsertWorkspaceAgentScriptTimingsParams) (WorkspaceAgentScriptTiming, error) InsertWorkspaceAgentScripts(ctx context.Context, arg InsertWorkspaceAgentScriptsParams) ([]WorkspaceAgentScript, error) InsertWorkspaceAgentStats(ctx context.Context, arg InsertWorkspaceAgentStatsParams) error InsertWorkspaceApp(ctx context.Context, arg InsertWorkspaceAppParams) (WorkspaceApp, error) diff --git a/coderd/database/queries.sql.go b/coderd/database/queries.sql.go index 129ef0298e4cd..c54d6be7779e5 100644 --- a/coderd/database/queries.sql.go +++ b/coderd/database/queries.sql.go @@ -11802,6 +11802,42 @@ func (q *sqlQuerier) InsertWorkspaceAgentMetadata(ctx context.Context, arg Inser return err } +const insertWorkspaceAgentScriptTimings = `-- name: InsertWorkspaceAgentScriptTimings :one +INSERT INTO + workspace_agent_script_timings ( + display_name, + started_at, + ended_at, + exit_code + ) +VALUES + ($1, $2, $3, $4) RETURNING display_name, started_at, ended_at, exit_code +` + +type InsertWorkspaceAgentScriptTimingsParams struct { + DisplayName string `db:"display_name" json:"display_name"` + StartedAt time.Time `db:"started_at" json:"started_at"` + EndedAt time.Time `db:"ended_at" json:"ended_at"` + ExitCode int32 `db:"exit_code" json:"exit_code"` +} + +func (q *sqlQuerier) InsertWorkspaceAgentScriptTimings(ctx context.Context, arg InsertWorkspaceAgentScriptTimingsParams) (WorkspaceAgentScriptTiming, error) { + row := q.db.QueryRowContext(ctx, insertWorkspaceAgentScriptTimings, + arg.DisplayName, + arg.StartedAt, + arg.EndedAt, + arg.ExitCode, + ) + var i WorkspaceAgentScriptTiming + err := row.Scan( + &i.DisplayName, + &i.StartedAt, + &i.EndedAt, + &i.ExitCode, + ) + return i, err +} + const updateWorkspaceAgentConnectionByID = `-- name: UpdateWorkspaceAgentConnectionByID :exec UPDATE workspace_agents @@ -15492,7 +15528,7 @@ func (q *sqlQuerier) UpdateWorkspacesDormantDeletingAtByTemplateID(ctx context.C } const getWorkspaceAgentScriptsByAgentIDs = `-- name: GetWorkspaceAgentScriptsByAgentIDs :many -SELECT workspace_agent_id, log_source_id, log_path, created_at, script, cron, start_blocks_login, run_on_start, run_on_stop, timeout_seconds FROM workspace_agent_scripts WHERE workspace_agent_id = ANY($1 :: uuid [ ]) +SELECT workspace_agent_id, log_source_id, log_path, created_at, script, cron, start_blocks_login, run_on_start, run_on_stop, timeout_seconds, display_name FROM workspace_agent_scripts WHERE workspace_agent_id = ANY($1 :: uuid [ ]) ` func (q *sqlQuerier) GetWorkspaceAgentScriptsByAgentIDs(ctx context.Context, ids []uuid.UUID) ([]WorkspaceAgentScript, error) { @@ -15515,6 +15551,7 @@ func (q *sqlQuerier) GetWorkspaceAgentScriptsByAgentIDs(ctx context.Context, ids &i.RunOnStart, &i.RunOnStop, &i.TimeoutSeconds, + &i.DisplayName, ); err != nil { return nil, err } @@ -15531,7 +15568,7 @@ func (q *sqlQuerier) GetWorkspaceAgentScriptsByAgentIDs(ctx context.Context, ids const insertWorkspaceAgentScripts = `-- name: InsertWorkspaceAgentScripts :many INSERT INTO - workspace_agent_scripts (workspace_agent_id, created_at, log_source_id, log_path, script, cron, start_blocks_login, run_on_start, run_on_stop, timeout_seconds) + workspace_agent_scripts ( workspace_agent_id, created_at, log_source_id, log_path, script, cron, start_blocks_login, run_on_start, run_on_stop, timeout_seconds, display_name ) SELECT $1 :: uuid AS workspace_agent_id, $2 :: timestamptz AS created_at, @@ -15542,8 +15579,9 @@ SELECT unnest($7 :: boolean [ ]) AS start_blocks_login, unnest($8 :: boolean [ ]) AS run_on_start, unnest($9 :: boolean [ ]) AS run_on_stop, - unnest($10 :: integer [ ]) AS timeout_seconds -RETURNING workspace_agent_scripts.workspace_agent_id, workspace_agent_scripts.log_source_id, workspace_agent_scripts.log_path, workspace_agent_scripts.created_at, workspace_agent_scripts.script, workspace_agent_scripts.cron, workspace_agent_scripts.start_blocks_login, workspace_agent_scripts.run_on_start, workspace_agent_scripts.run_on_stop, workspace_agent_scripts.timeout_seconds + unnest($10 :: integer [ ]) AS timeout_seconds, + unnest($11 :: text [ ]) AS display_name +RETURNING workspace_agent_scripts.workspace_agent_id, workspace_agent_scripts.log_source_id, workspace_agent_scripts.log_path, workspace_agent_scripts.created_at, workspace_agent_scripts.script, workspace_agent_scripts.cron, workspace_agent_scripts.start_blocks_login, workspace_agent_scripts.run_on_start, workspace_agent_scripts.run_on_stop, workspace_agent_scripts.timeout_seconds, workspace_agent_scripts.display_name ` type InsertWorkspaceAgentScriptsParams struct { @@ -15557,6 +15595,7 @@ type InsertWorkspaceAgentScriptsParams struct { RunOnStart []bool `db:"run_on_start" json:"run_on_start"` RunOnStop []bool `db:"run_on_stop" json:"run_on_stop"` TimeoutSeconds []int32 `db:"timeout_seconds" json:"timeout_seconds"` + DisplayName []string `db:"display_name" json:"display_name"` } func (q *sqlQuerier) InsertWorkspaceAgentScripts(ctx context.Context, arg InsertWorkspaceAgentScriptsParams) ([]WorkspaceAgentScript, error) { @@ -15571,6 +15610,7 @@ func (q *sqlQuerier) InsertWorkspaceAgentScripts(ctx context.Context, arg Insert pq.Array(arg.RunOnStart), pq.Array(arg.RunOnStop), pq.Array(arg.TimeoutSeconds), + pq.Array(arg.DisplayName), ) if err != nil { return nil, err @@ -15590,6 +15630,7 @@ func (q *sqlQuerier) InsertWorkspaceAgentScripts(ctx context.Context, arg Insert &i.RunOnStart, &i.RunOnStop, &i.TimeoutSeconds, + &i.DisplayName, ); err != nil { return nil, err } diff --git a/coderd/database/queries/workspaceagents.sql b/coderd/database/queries/workspaceagents.sql index 9c5860bf494a6..ce79f9f7b0034 100644 --- a/coderd/database/queries/workspaceagents.sql +++ b/coderd/database/queries/workspaceagents.sql @@ -287,3 +287,14 @@ WHERE workspace_id = workspace_build_with_user.workspace_id ) ; + +-- name: InsertWorkspaceAgentScriptTimings :one +INSERT INTO + workspace_agent_script_timings ( + display_name, + started_at, + ended_at, + exit_code + ) +VALUES + ($1, $2, $3, $4) RETURNING *; diff --git a/coderd/database/queries/workspacescripts.sql b/coderd/database/queries/workspacescripts.sql index 8dc234afd37d3..3e8d1fb07bd45 100644 --- a/coderd/database/queries/workspacescripts.sql +++ b/coderd/database/queries/workspacescripts.sql @@ -1,6 +1,6 @@ -- name: InsertWorkspaceAgentScripts :many INSERT INTO - workspace_agent_scripts (workspace_agent_id, created_at, log_source_id, log_path, script, cron, start_blocks_login, run_on_start, run_on_stop, timeout_seconds) + workspace_agent_scripts ( workspace_agent_id, created_at, log_source_id, log_path, script, cron, start_blocks_login, run_on_start, run_on_stop, timeout_seconds, display_name ) SELECT @workspace_agent_id :: uuid AS workspace_agent_id, @created_at :: timestamptz AS created_at, @@ -11,7 +11,8 @@ SELECT unnest(@start_blocks_login :: boolean [ ]) AS start_blocks_login, unnest(@run_on_start :: boolean [ ]) AS run_on_start, unnest(@run_on_stop :: boolean [ ]) AS run_on_stop, - unnest(@timeout_seconds :: integer [ ]) AS timeout_seconds + unnest(@timeout_seconds :: integer [ ]) AS timeout_seconds, + unnest(@display_name :: text [ ]) AS display_name RETURNING workspace_agent_scripts.*; -- name: GetWorkspaceAgentScriptsByAgentIDs :many diff --git a/coderd/provisionerdserver/provisionerdserver.go b/coderd/provisionerdserver/provisionerdserver.go index c575be43c2310..84739ac9cd78a 100644 --- a/coderd/provisionerdserver/provisionerdserver.go +++ b/coderd/provisionerdserver/provisionerdserver.go @@ -1818,6 +1818,7 @@ func InsertWorkspaceResource(ctx context.Context, db database.Store, jobID uuid. logSourceIDs := make([]uuid.UUID, 0, len(prAgent.Scripts)) logSourceDisplayNames := make([]string, 0, len(prAgent.Scripts)) logSourceIcons := make([]string, 0, len(prAgent.Scripts)) + scriptDisplayName := make([]string, 0, len(prAgent.Scripts)) scriptLogPaths := make([]string, 0, len(prAgent.Scripts)) scriptSources := make([]string, 0, len(prAgent.Scripts)) scriptCron := make([]string, 0, len(prAgent.Scripts)) @@ -1830,6 +1831,7 @@ func InsertWorkspaceResource(ctx context.Context, db database.Store, jobID uuid. logSourceIDs = append(logSourceIDs, uuid.New()) logSourceDisplayNames = append(logSourceDisplayNames, script.DisplayName) logSourceIcons = append(logSourceIcons, script.Icon) + scriptDisplayName = append(scriptDisplayName, script.DisplayName) scriptLogPaths = append(scriptLogPaths, script.LogPath) scriptSources = append(scriptSources, script.Script) scriptCron = append(scriptCron, script.Cron) @@ -1861,6 +1863,7 @@ func InsertWorkspaceResource(ctx context.Context, db database.Store, jobID uuid. StartBlocksLogin: scriptStartBlocksLogin, RunOnStart: scriptRunOnStart, RunOnStop: scriptRunOnStop, + DisplayName: scriptDisplayName, }) if err != nil { return xerrors.Errorf("insert agent scripts: %w", err) diff --git a/coderd/workspaceagents.go b/coderd/workspaceagents.go index eaf06a643a3e0..be1a1c1069252 100644 --- a/coderd/workspaceagents.go +++ b/coderd/workspaceagents.go @@ -969,6 +969,7 @@ func convertScripts(dbScripts []database.WorkspaceAgentScript) []codersdk.Worksp scripts := make([]codersdk.WorkspaceAgentScript, 0) for _, dbScript := range dbScripts { scripts = append(scripts, codersdk.WorkspaceAgentScript{ + DisplayName: dbScript.DisplayName, LogPath: dbScript.LogPath, LogSourceID: dbScript.LogSourceID, Script: dbScript.Script, diff --git a/codersdk/agentsdk/convert.go b/codersdk/agentsdk/convert.go index 3dd6549762f10..e648645a6b731 100644 --- a/codersdk/agentsdk/convert.go +++ b/codersdk/agentsdk/convert.go @@ -165,6 +165,7 @@ func AgentScriptFromProto(protoScript *proto.WorkspaceAgentScript) (codersdk.Wor return codersdk.WorkspaceAgentScript{ LogSourceID: id, + DisplayName: protoScript.DisplayName, LogPath: protoScript.LogPath, Script: protoScript.Script, Cron: protoScript.Cron, @@ -177,6 +178,7 @@ func AgentScriptFromProto(protoScript *proto.WorkspaceAgentScript) (codersdk.Wor func ProtoFromScript(s codersdk.WorkspaceAgentScript) *proto.WorkspaceAgentScript { return &proto.WorkspaceAgentScript{ + DisplayName: s.DisplayName, LogSourceId: s.LogSourceID[:], LogPath: s.LogPath, Script: s.Script, diff --git a/codersdk/workspaceagents.go b/codersdk/workspaceagents.go index 6eab57bb3c4ad..497b4f79995f2 100644 --- a/codersdk/workspaceagents.go +++ b/codersdk/workspaceagents.go @@ -185,6 +185,7 @@ type WorkspaceAgentLogSource struct { } type WorkspaceAgentScript struct { + DisplayName string `json:"display_name"` LogSourceID uuid.UUID `json:"log_source_id" format:"uuid"` LogPath string `json:"log_path"` Script string `json:"script"` diff --git a/site/src/api/typesGenerated.ts b/site/src/api/typesGenerated.ts index 41664495a5750..8959b7076b2f0 100644 --- a/site/src/api/typesGenerated.ts +++ b/site/src/api/typesGenerated.ts @@ -1887,6 +1887,7 @@ export interface WorkspaceAgentPortShares { // From codersdk/workspaceagents.go export interface WorkspaceAgentScript { + readonly display_name: string; readonly log_source_id: string; readonly log_path: string; readonly script: string; diff --git a/site/src/testHelpers/entities.ts b/site/src/testHelpers/entities.ts index 13baf9449aba9..b2ef350907fbb 100644 --- a/site/src/testHelpers/entities.ts +++ b/site/src/testHelpers/entities.ts @@ -886,6 +886,7 @@ export const MockWorkspaceAgentLogSource: TypesGen.WorkspaceAgentLogSource = { }; export const MockWorkspaceAgentScript: TypesGen.WorkspaceAgentScript = { + display_name: "", log_source_id: MockWorkspaceAgentLogSource.id, cron: "", log_path: "", From d55b2e6c64e675c7800d7b21ff6c2e447e9452d1 Mon Sep 17 00:00:00 2001 From: Danielle Maywood Date: Tue, 17 Sep 2024 14:28:17 +0000 Subject: [PATCH 02/56] feat: add job_id and display_name to script timings --- coderd/agentapi/api.go | 1 + coderd/agentapi/scripts.go | 15 ++++++++++++++- coderd/apidoc/docs.go | 3 +++ coderd/apidoc/swagger.json | 3 +++ coderd/database/dbmem/dbmem.go | 8 +++++--- coderd/database/dump.sql | 4 ++++ coderd/database/foreign_key_constraint.go | 1 + .../000250_workspace_agent_script_timings.up.sql | 1 + coderd/database/models.go | 1 + coderd/database/queries.sql.go | 6 +++++- coderd/database/queries/workspaceagents.sql | 3 ++- docs/reference/api/agents.md | 1 + docs/reference/api/builds.md | 8 ++++++++ docs/reference/api/schemas.md | 7 +++++++ docs/reference/api/templates.md | 4 ++++ docs/reference/api/workspaces.md | 6 ++++++ 16 files changed, 66 insertions(+), 6 deletions(-) diff --git a/coderd/agentapi/api.go b/coderd/agentapi/api.go index bea1fa5d881a3..dca1ce96712bb 100644 --- a/coderd/agentapi/api.go +++ b/coderd/agentapi/api.go @@ -154,6 +154,7 @@ func New(opts Options) *API { } api.ScriptsAPI = &ScriptsAPI{ + AgentID: opts.AgentID, Database: opts.Database, } diff --git a/coderd/agentapi/scripts.go b/coderd/agentapi/scripts.go index 1d3791e03b6fd..50d9455c1d4b6 100644 --- a/coderd/agentapi/scripts.go +++ b/coderd/agentapi/scripts.go @@ -5,16 +5,29 @@ import ( agentproto "github.com/coder/coder/v2/agent/proto" "github.com/coder/coder/v2/coderd/database" + "github.com/google/uuid" ) type ScriptsAPI struct { + AgentID uuid.UUID Database database.Store } func (s *ScriptsAPI) ScriptCompleted(ctx context.Context, req *agentproto.WorkspaceAgentScriptCompletedRequest) (*agentproto.WorkspaceAgentScriptCompletedResponse, error) { res := &agentproto.WorkspaceAgentScriptCompletedResponse{} - _, err := s.Database.InsertWorkspaceAgentScriptTimings(ctx, database.InsertWorkspaceAgentScriptTimingsParams{ + agent, err := s.Database.GetWorkspaceAgentByID(ctx, s.AgentID) + if err != nil { + return nil, err + } + + resource, err := s.Database.GetWorkspaceResourceByID(ctx, agent.ResourceID) + if err != nil { + return nil, err + } + + _, err = s.Database.InsertWorkspaceAgentScriptTimings(ctx, database.InsertWorkspaceAgentScriptTimingsParams{ + JobID: resource.JobID, DisplayName: req.Timing.DisplayName, StartedAt: req.Timing.Start.AsTime(), EndedAt: req.Timing.End.AsTime(), diff --git a/coderd/apidoc/docs.go b/coderd/apidoc/docs.go index bd951f8485d84..37afc0ec80653 100644 --- a/coderd/apidoc/docs.go +++ b/coderd/apidoc/docs.go @@ -14260,6 +14260,9 @@ const docTemplate = `{ "cron": { "type": "string" }, + "display_name": { + "type": "string" + }, "log_path": { "type": "string" }, diff --git a/coderd/apidoc/swagger.json b/coderd/apidoc/swagger.json index c7c5bb1a16588..9c511d9f07068 100644 --- a/coderd/apidoc/swagger.json +++ b/coderd/apidoc/swagger.json @@ -12986,6 +12986,9 @@ "cron": { "type": "string" }, + "display_name": { + "type": "string" + }, "log_path": { "type": "string" }, diff --git a/coderd/database/dbmem/dbmem.go b/coderd/database/dbmem/dbmem.go index 25f64448c5d78..19bc2a4c5f0e7 100644 --- a/coderd/database/dbmem/dbmem.go +++ b/coderd/database/dbmem/dbmem.go @@ -7837,9 +7837,11 @@ func (q *FakeQuerier) InsertWorkspaceAgentScriptTimings(ctx context.Context, arg defer q.mutex.Unlock() scriptTiming := database.WorkspaceAgentScriptTiming{ - StartedAt: arg.StartedAt, - EndedAt: arg.EndedAt, - ExitCode: arg.ExitCode, + StartedAt: arg.StartedAt, + EndedAt: arg.EndedAt, + ExitCode: arg.ExitCode, + DisplayName: arg.DisplayName, + JobID: arg.JobID, } q.workspaceAgentScriptTimings = append(q.workspaceAgentScriptTimings, scriptTiming) diff --git a/coderd/database/dump.sql b/coderd/database/dump.sql index d8d454af248fe..f41635e6541ff 100644 --- a/coderd/database/dump.sql +++ b/coderd/database/dump.sql @@ -1356,6 +1356,7 @@ CREATE TABLE workspace_agent_port_share ( ); CREATE TABLE workspace_agent_script_timings ( + job_id uuid NOT NULL, display_name text NOT NULL, started_at timestamp with time zone NOT NULL, ended_at timestamp with time zone NOT NULL, @@ -2232,6 +2233,9 @@ ALTER TABLE ONLY workspace_agent_metadata ALTER TABLE ONLY workspace_agent_port_share ADD CONSTRAINT workspace_agent_port_share_workspace_id_fkey FOREIGN KEY (workspace_id) REFERENCES workspaces(id) ON DELETE CASCADE; +ALTER TABLE ONLY workspace_agent_script_timings + ADD CONSTRAINT workspace_agent_script_timings_job_id_fkey FOREIGN KEY (job_id) REFERENCES provisioner_jobs(id) ON DELETE CASCADE; + ALTER TABLE ONLY workspace_agent_scripts ADD CONSTRAINT workspace_agent_scripts_workspace_agent_id_fkey FOREIGN KEY (workspace_agent_id) REFERENCES workspace_agents(id) ON DELETE CASCADE; diff --git a/coderd/database/foreign_key_constraint.go b/coderd/database/foreign_key_constraint.go index 907cebed6d8e0..ad731575a1385 100644 --- a/coderd/database/foreign_key_constraint.go +++ b/coderd/database/foreign_key_constraint.go @@ -53,6 +53,7 @@ const ( ForeignKeyWorkspaceAgentLogSourcesWorkspaceAgentID ForeignKeyConstraint = "workspace_agent_log_sources_workspace_agent_id_fkey" // ALTER TABLE ONLY workspace_agent_log_sources ADD CONSTRAINT workspace_agent_log_sources_workspace_agent_id_fkey FOREIGN KEY (workspace_agent_id) REFERENCES workspace_agents(id) ON DELETE CASCADE; ForeignKeyWorkspaceAgentMetadataWorkspaceAgentID ForeignKeyConstraint = "workspace_agent_metadata_workspace_agent_id_fkey" // ALTER TABLE ONLY workspace_agent_metadata ADD CONSTRAINT workspace_agent_metadata_workspace_agent_id_fkey FOREIGN KEY (workspace_agent_id) REFERENCES workspace_agents(id) ON DELETE CASCADE; ForeignKeyWorkspaceAgentPortShareWorkspaceID ForeignKeyConstraint = "workspace_agent_port_share_workspace_id_fkey" // ALTER TABLE ONLY workspace_agent_port_share ADD CONSTRAINT workspace_agent_port_share_workspace_id_fkey FOREIGN KEY (workspace_id) REFERENCES workspaces(id) ON DELETE CASCADE; + ForeignKeyWorkspaceAgentScriptTimingsJobID ForeignKeyConstraint = "workspace_agent_script_timings_job_id_fkey" // ALTER TABLE ONLY workspace_agent_script_timings ADD CONSTRAINT workspace_agent_script_timings_job_id_fkey FOREIGN KEY (job_id) REFERENCES provisioner_jobs(id) ON DELETE CASCADE; ForeignKeyWorkspaceAgentScriptsWorkspaceAgentID ForeignKeyConstraint = "workspace_agent_scripts_workspace_agent_id_fkey" // ALTER TABLE ONLY workspace_agent_scripts ADD CONSTRAINT workspace_agent_scripts_workspace_agent_id_fkey FOREIGN KEY (workspace_agent_id) REFERENCES workspace_agents(id) ON DELETE CASCADE; ForeignKeyWorkspaceAgentStartupLogsAgentID ForeignKeyConstraint = "workspace_agent_startup_logs_agent_id_fkey" // ALTER TABLE ONLY workspace_agent_logs ADD CONSTRAINT workspace_agent_startup_logs_agent_id_fkey FOREIGN KEY (agent_id) REFERENCES workspace_agents(id) ON DELETE CASCADE; ForeignKeyWorkspaceAgentsResourceID ForeignKeyConstraint = "workspace_agents_resource_id_fkey" // ALTER TABLE ONLY workspace_agents ADD CONSTRAINT workspace_agents_resource_id_fkey FOREIGN KEY (resource_id) REFERENCES workspace_resources(id) ON DELETE CASCADE; diff --git a/coderd/database/migrations/000250_workspace_agent_script_timings.up.sql b/coderd/database/migrations/000250_workspace_agent_script_timings.up.sql index 313a7d05a468a..9eaa00c62d21f 100644 --- a/coderd/database/migrations/000250_workspace_agent_script_timings.up.sql +++ b/coderd/database/migrations/000250_workspace_agent_script_timings.up.sql @@ -1,5 +1,6 @@ CREATE TABLE workspace_agent_script_timings ( + job_id uuid not null references provisioner_jobs (id) on delete cascade, display_name text not null, started_at timestamp with time zone not null, ended_at timestamp with time zone not null, diff --git a/coderd/database/models.go b/coderd/database/models.go index 79ac986ea07b2..8ab682d102e65 100644 --- a/coderd/database/models.go +++ b/coderd/database/models.go @@ -2884,6 +2884,7 @@ type WorkspaceAgentScript struct { } type WorkspaceAgentScriptTiming struct { + JobID uuid.UUID `db:"job_id" json:"job_id"` DisplayName string `db:"display_name" json:"display_name"` StartedAt time.Time `db:"started_at" json:"started_at"` EndedAt time.Time `db:"ended_at" json:"ended_at"` diff --git a/coderd/database/queries.sql.go b/coderd/database/queries.sql.go index c54d6be7779e5..cc6337796f57c 100644 --- a/coderd/database/queries.sql.go +++ b/coderd/database/queries.sql.go @@ -11805,16 +11805,18 @@ func (q *sqlQuerier) InsertWorkspaceAgentMetadata(ctx context.Context, arg Inser const insertWorkspaceAgentScriptTimings = `-- name: InsertWorkspaceAgentScriptTimings :one INSERT INTO workspace_agent_script_timings ( + job_id, display_name, started_at, ended_at, exit_code ) VALUES - ($1, $2, $3, $4) RETURNING display_name, started_at, ended_at, exit_code + ($1, $2, $3, $4, $5) RETURNING job_id, display_name, started_at, ended_at, exit_code ` type InsertWorkspaceAgentScriptTimingsParams struct { + JobID uuid.UUID `db:"job_id" json:"job_id"` DisplayName string `db:"display_name" json:"display_name"` StartedAt time.Time `db:"started_at" json:"started_at"` EndedAt time.Time `db:"ended_at" json:"ended_at"` @@ -11823,6 +11825,7 @@ type InsertWorkspaceAgentScriptTimingsParams struct { func (q *sqlQuerier) InsertWorkspaceAgentScriptTimings(ctx context.Context, arg InsertWorkspaceAgentScriptTimingsParams) (WorkspaceAgentScriptTiming, error) { row := q.db.QueryRowContext(ctx, insertWorkspaceAgentScriptTimings, + arg.JobID, arg.DisplayName, arg.StartedAt, arg.EndedAt, @@ -11830,6 +11833,7 @@ func (q *sqlQuerier) InsertWorkspaceAgentScriptTimings(ctx context.Context, arg ) var i WorkspaceAgentScriptTiming err := row.Scan( + &i.JobID, &i.DisplayName, &i.StartedAt, &i.EndedAt, diff --git a/coderd/database/queries/workspaceagents.sql b/coderd/database/queries/workspaceagents.sql index ce79f9f7b0034..3466acb20b8db 100644 --- a/coderd/database/queries/workspaceagents.sql +++ b/coderd/database/queries/workspaceagents.sql @@ -291,10 +291,11 @@ WHERE -- name: InsertWorkspaceAgentScriptTimings :one INSERT INTO workspace_agent_script_timings ( + job_id, display_name, started_at, ended_at, exit_code ) VALUES - ($1, $2, $3, $4) RETURNING *; + ($1, $2, $3, $4, $5) RETURNING *; diff --git a/docs/reference/api/agents.md b/docs/reference/api/agents.md index 30c5881081499..ee15d88b2b3be 100644 --- a/docs/reference/api/agents.md +++ b/docs/reference/api/agents.md @@ -487,6 +487,7 @@ curl -X GET http://coder-server:8080/api/v2/workspaceagents/{workspaceagent} \ "scripts": [ { "cron": "string", + "display_name": "string", "log_path": "string", "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a", "run_on_start": true, diff --git a/docs/reference/api/builds.md b/docs/reference/api/builds.md index 07747b5551590..c40e5171ddb52 100644 --- a/docs/reference/api/builds.md +++ b/docs/reference/api/builds.md @@ -128,6 +128,7 @@ curl -X GET http://coder-server:8080/api/v2/users/{user}/workspace/{workspacenam "scripts": [ { "cron": "string", + "display_name": "string", "log_path": "string", "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a", "run_on_start": true, @@ -311,6 +312,7 @@ curl -X GET http://coder-server:8080/api/v2/workspacebuilds/{workspacebuild} \ "scripts": [ { "cron": "string", + "display_name": "string", "log_path": "string", "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a", "run_on_start": true, @@ -633,6 +635,7 @@ curl -X GET http://coder-server:8080/api/v2/workspacebuilds/{workspacebuild}/res "scripts": [ { "cron": "string", + "display_name": "string", "log_path": "string", "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a", "run_on_start": true, @@ -738,6 +741,7 @@ Status Code **200** | `»» resource_id` | string(uuid) | false | | | | `»» scripts` | array | false | | | | `»»» cron` | string | false | | | +| `»»» display_name` | string | false | | | | `»»» log_path` | string | false | | | | `»»» log_source_id` | string(uuid) | false | | | | `»»» run_on_start` | boolean | false | | | @@ -924,6 +928,7 @@ curl -X GET http://coder-server:8080/api/v2/workspacebuilds/{workspacebuild}/sta "scripts": [ { "cron": "string", + "display_name": "string", "log_path": "string", "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a", "run_on_start": true, @@ -1112,6 +1117,7 @@ curl -X GET http://coder-server:8080/api/v2/workspaces/{workspace}/builds \ "scripts": [ { "cron": "string", + "display_name": "string", "log_path": "string", "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a", "run_on_start": true, @@ -1254,6 +1260,7 @@ Status Code **200** | `»»» resource_id` | string(uuid) | false | | | | `»»» scripts` | array | false | | | | `»»»» cron` | string | false | | | +| `»»»» display_name` | string | false | | | | `»»»» log_path` | string | false | | | | `»»»» log_source_id` | string(uuid) | false | | | | `»»»» run_on_start` | boolean | false | | | @@ -1494,6 +1501,7 @@ curl -X POST http://coder-server:8080/api/v2/workspaces/{workspace}/builds \ "scripts": [ { "cron": "string", + "display_name": "string", "log_path": "string", "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a", "run_on_start": true, diff --git a/docs/reference/api/schemas.md b/docs/reference/api/schemas.md index 9a53d3bfcba47..7e440d977da7e 100644 --- a/docs/reference/api/schemas.md +++ b/docs/reference/api/schemas.md @@ -6454,6 +6454,7 @@ If the schedule is empty, the user will be updated to use the default schedule.| "scripts": [ { "cron": "string", + "display_name": "string", "log_path": "string", "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a", "run_on_start": true, @@ -6633,6 +6634,7 @@ If the schedule is empty, the user will be updated to use the default schedule.| "scripts": [ { "cron": "string", + "display_name": "string", "log_path": "string", "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a", "run_on_start": true, @@ -6901,6 +6903,7 @@ If the schedule is empty, the user will be updated to use the default schedule.| ```json { "cron": "string", + "display_name": "string", "log_path": "string", "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a", "run_on_start": true, @@ -6916,6 +6919,7 @@ If the schedule is empty, the user will be updated to use the default schedule.| | Name | Type | Required | Restrictions | Description | | -------------------- | ------- | -------- | ------------ | ----------- | | `cron` | string | false | | | +| `display_name` | string | false | | | | `log_path` | string | false | | | | `log_source_id` | string | false | | | | `run_on_start` | boolean | false | | | @@ -7144,6 +7148,7 @@ If the schedule is empty, the user will be updated to use the default schedule.| "scripts": [ { "cron": "string", + "display_name": "string", "log_path": "string", "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a", "run_on_start": true, @@ -7479,6 +7484,7 @@ If the schedule is empty, the user will be updated to use the default schedule.| "scripts": [ { "cron": "string", + "display_name": "string", "log_path": "string", "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a", "run_on_start": true, @@ -7739,6 +7745,7 @@ If the schedule is empty, the user will be updated to use the default schedule.| "scripts": [ { "cron": "string", + "display_name": "string", "log_path": "string", "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a", "run_on_start": true, diff --git a/docs/reference/api/templates.md b/docs/reference/api/templates.md index e2bd980268e2b..bd346e5b5a542 100644 --- a/docs/reference/api/templates.md +++ b/docs/reference/api/templates.md @@ -2000,6 +2000,7 @@ curl -X GET http://coder-server:8080/api/v2/templateversions/{templateversion}/d "scripts": [ { "cron": "string", + "display_name": "string", "log_path": "string", "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a", "run_on_start": true, @@ -2105,6 +2106,7 @@ Status Code **200** | `»» resource_id` | string(uuid) | false | | | | `»» scripts` | array | false | | | | `»»» cron` | string | false | | | +| `»»» display_name` | string | false | | | | `»»» log_path` | string | false | | | | `»»» log_source_id` | string(uuid) | false | | | | `»»» run_on_start` | boolean | false | | | @@ -2422,6 +2424,7 @@ curl -X GET http://coder-server:8080/api/v2/templateversions/{templateversion}/r "scripts": [ { "cron": "string", + "display_name": "string", "log_path": "string", "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a", "run_on_start": true, @@ -2527,6 +2530,7 @@ Status Code **200** | `»» resource_id` | string(uuid) | false | | | | `»» scripts` | array | false | | | | `»»» cron` | string | false | | | +| `»»» display_name` | string | false | | | | `»»» log_path` | string | false | | | | `»»» log_source_id` | string(uuid) | false | | | | `»»» run_on_start` | boolean | false | | | diff --git a/docs/reference/api/workspaces.md b/docs/reference/api/workspaces.md index 92ce677e6ece9..387c221639401 100644 --- a/docs/reference/api/workspaces.md +++ b/docs/reference/api/workspaces.md @@ -167,6 +167,7 @@ of the template will be used. "scripts": [ { "cron": "string", + "display_name": "string", "log_path": "string", "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a", "run_on_start": true, @@ -383,6 +384,7 @@ curl -X GET http://coder-server:8080/api/v2/users/{user}/workspace/{workspacenam "scripts": [ { "cron": "string", + "display_name": "string", "log_path": "string", "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a", "run_on_start": true, @@ -623,6 +625,7 @@ of the template will be used. "scripts": [ { "cron": "string", + "display_name": "string", "log_path": "string", "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a", "run_on_start": true, @@ -838,6 +841,7 @@ curl -X GET http://coder-server:8080/api/v2/workspaces \ "scripts": [ { "cron": "string", + "display_name": "string", "log_path": "string", "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a", "run_on_start": true, @@ -1055,6 +1059,7 @@ curl -X GET http://coder-server:8080/api/v2/workspaces/{workspace} \ "scripts": [ { "cron": "string", + "display_name": "string", "log_path": "string", "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a", "run_on_start": true, @@ -1387,6 +1392,7 @@ curl -X PUT http://coder-server:8080/api/v2/workspaces/{workspace}/dormant \ "scripts": [ { "cron": "string", + "display_name": "string", "log_path": "string", "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a", "run_on_start": true, From 05d8a8b2ffd4b068349242d9c61ebde05e61f1bd Mon Sep 17 00:00:00 2001 From: Danielle Maywood Date: Tue, 17 Sep 2024 15:48:05 +0000 Subject: [PATCH 03/56] fix: increment migration number --- ...gs.down.sql => 000251_workspace_agent_script_timings.down.sql} | 0 ...imings.up.sql => 000251_workspace_agent_script_timings.up.sql} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename coderd/database/migrations/{000250_workspace_agent_script_timings.down.sql => 000251_workspace_agent_script_timings.down.sql} (100%) rename coderd/database/migrations/{000250_workspace_agent_script_timings.up.sql => 000251_workspace_agent_script_timings.up.sql} (100%) diff --git a/coderd/database/migrations/000250_workspace_agent_script_timings.down.sql b/coderd/database/migrations/000251_workspace_agent_script_timings.down.sql similarity index 100% rename from coderd/database/migrations/000250_workspace_agent_script_timings.down.sql rename to coderd/database/migrations/000251_workspace_agent_script_timings.down.sql diff --git a/coderd/database/migrations/000250_workspace_agent_script_timings.up.sql b/coderd/database/migrations/000251_workspace_agent_script_timings.up.sql similarity index 100% rename from coderd/database/migrations/000250_workspace_agent_script_timings.up.sql rename to coderd/database/migrations/000251_workspace_agent_script_timings.up.sql From d54f6c34dd9cc8e0f03ef29c5bd757935ba9a747 Mon Sep 17 00:00:00 2001 From: Danielle Maywood Date: Wed, 18 Sep 2024 08:47:10 +0000 Subject: [PATCH 04/56] fix: rename migrations from 251 to 254 --- ...gs.down.sql => 000254_workspace_agent_script_timings.down.sql} | 0 ...imings.up.sql => 000254_workspace_agent_script_timings.up.sql} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename coderd/database/migrations/{000251_workspace_agent_script_timings.down.sql => 000254_workspace_agent_script_timings.down.sql} (100%) rename coderd/database/migrations/{000251_workspace_agent_script_timings.up.sql => 000254_workspace_agent_script_timings.up.sql} (100%) diff --git a/coderd/database/migrations/000251_workspace_agent_script_timings.down.sql b/coderd/database/migrations/000254_workspace_agent_script_timings.down.sql similarity index 100% rename from coderd/database/migrations/000251_workspace_agent_script_timings.down.sql rename to coderd/database/migrations/000254_workspace_agent_script_timings.down.sql diff --git a/coderd/database/migrations/000251_workspace_agent_script_timings.up.sql b/coderd/database/migrations/000254_workspace_agent_script_timings.up.sql similarity index 100% rename from coderd/database/migrations/000251_workspace_agent_script_timings.up.sql rename to coderd/database/migrations/000254_workspace_agent_script_timings.up.sql From d573c67027620f40f5e095d4a4f35df3d9a75e23 Mon Sep 17 00:00:00 2001 From: Danielle Maywood Date: Wed, 18 Sep 2024 09:28:44 +0000 Subject: [PATCH 05/56] test: get tests compiling --- agent/agenttest/client.go | 4 ++++ coderd/database/dbauthz/dbauthz.go | 5 +++-- coderd/database/dbauthz/dbauthz_test.go | 6 ++++++ 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/agent/agenttest/client.go b/agent/agenttest/client.go index decb43ae9d05a..51da04892dbc3 100644 --- a/agent/agenttest/client.go +++ b/agent/agenttest/client.go @@ -301,6 +301,10 @@ func (f *FakeAgentAPI) BatchCreateLogs(ctx context.Context, req *agentproto.Batc return &agentproto.BatchCreateLogsResponse{}, nil } +func (f *FakeAgentAPI) ScriptCompleted(ctx context.Context, req *agentproto.WorkspaceAgentScriptCompletedRequest) (*agentproto.WorkspaceAgentScriptCompletedResponse, error) { + return &agentproto.WorkspaceAgentScriptCompletedResponse{}, nil +} + func NewFakeAgentAPI(t testing.TB, logger slog.Logger, manifest *agentproto.Manifest, statsCh chan *agentproto.Stats) *FakeAgentAPI { return &FakeAgentAPI{ t: t, diff --git a/coderd/database/dbauthz/dbauthz.go b/coderd/database/dbauthz/dbauthz.go index 02d4efb054a20..9565ebc1eda7d 100644 --- a/coderd/database/dbauthz/dbauthz.go +++ b/coderd/database/dbauthz/dbauthz.go @@ -3028,8 +3028,9 @@ func (q *querier) InsertWorkspaceAgentMetadata(ctx context.Context, arg database } func (q *querier) InsertWorkspaceAgentScriptTimings(ctx context.Context, arg database.InsertWorkspaceAgentScriptTimingsParams) (database.WorkspaceAgentScriptTiming, error) { - // TODO: I have no idea what to add here. - + // if err := q.authorizeContext(ctx, policy.ActionCreate, rbac.ResourceSystem); err != nil { + // return nil, err + // } return q.db.InsertWorkspaceAgentScriptTimings(ctx, arg) } diff --git a/coderd/database/dbauthz/dbauthz_test.go b/coderd/database/dbauthz/dbauthz_test.go index 85bd179a95f44..87b592dacebd8 100644 --- a/coderd/database/dbauthz/dbauthz_test.go +++ b/coderd/database/dbauthz/dbauthz_test.go @@ -2632,6 +2632,12 @@ func (s *MethodTestSuite) TestSystemFunctions() { s.Run("InsertWorkspaceAppStats", s.Subtest(func(db database.Store, check *expects) { check.Args(database.InsertWorkspaceAppStatsParams{}).Asserts(rbac.ResourceSystem, policy.ActionCreate) })) + s.Run("InsertWorkspaceAgentScriptTimings", s.Subtest(func(db database.Store, check *expects) { + j := dbgen.ProvisionerJob(s.T(), db, nil, database.ProvisionerJob{}) + check.Args(database.InsertWorkspaceAgentScriptTimingsParams{ + JobID: j.ID, + }).Asserts( /* rbac.ResourceSystem, policy.ActionCreate */ ) + })) s.Run("InsertWorkspaceAgentScripts", s.Subtest(func(db database.Store, check *expects) { check.Args(database.InsertWorkspaceAgentScriptsParams{}).Asserts(rbac.ResourceSystem, policy.ActionCreate) })) From 09a1a42ef888012f2214938c41a265d206c22aa5 Mon Sep 17 00:00:00 2001 From: Danielle Maywood Date: Wed, 18 Sep 2024 09:42:51 +0000 Subject: [PATCH 06/56] fix: appease the linter --- agent/agent.go | 3 ++- agent/agentscripts/agentscripts.go | 8 ++++---- agent/agentscripts/timings.go | 7 ++++--- agent/agenttest/client.go | 2 +- cli/organizationsettings.go | 8 ++++---- coderd/agentapi/scripts.go | 3 ++- coderd/database/dbmem/dbmem.go | 3 ++- 7 files changed, 19 insertions(+), 15 deletions(-) diff --git a/agent/agent.go b/agent/agent.go index 96c217d37e5d5..c07cbe7e96851 100644 --- a/agent/agent.go +++ b/agent/agent.go @@ -583,9 +583,10 @@ func (a *agent) reportMetadata(ctx context.Context, conn drpc.Conn) error { case <-ctx.Done(): return ctx.Err() case timing := <-*a.scriptRunner.ScriptTimings(): - aAPI.ScriptCompleted(ctx, &proto.WorkspaceAgentScriptCompletedRequest{ + _, err := aAPI.ScriptCompleted(ctx, &proto.WorkspaceAgentScriptCompletedRequest{ Timing: timing.ToProto(), }) + return err case mr := <-metadataResults: // This can overwrite unsent values, but that's fine because // we're only interested about up-to-date values. diff --git a/agent/agentscripts/agentscripts.go b/agent/agentscripts/agentscripts.go index 2e22087e703ff..4673c8f7e3f15 100644 --- a/agent/agentscripts/agentscripts.go +++ b/agent/agentscripts/agentscripts.go @@ -66,7 +66,7 @@ func New(opts Options) *Runner { cronCtxCancel: cronCtxCancel, cron: cron.New(cron.WithParser(parser)), closed: make(chan struct{}), - scriptTimings: make(chan timingSpan), + scriptTimings: make(chan TimingSpan), dataDir: filepath.Join(opts.DataDirBase, "coder-script-data"), scriptsExecuted: prometheus.NewCounterVec(prometheus.CounterOpts{ Namespace: "agent", @@ -87,7 +87,7 @@ type Runner struct { cron *cron.Cron initialized atomic.Bool scripts []codersdk.WorkspaceAgentScript - scriptTimings chan timingSpan + scriptTimings chan TimingSpan dataDir string // scriptsExecuted includes all scripts executed by the workspace agent. Agents @@ -96,7 +96,7 @@ type Runner struct { scriptsExecuted *prometheus.CounterVec } -func (r *Runner) ScriptTimings() *chan timingSpan { +func (r *Runner) ScriptTimings() *chan TimingSpan { return &r.scriptTimings } @@ -321,7 +321,7 @@ func (r *Runner) run(ctx context.Context, script codersdk.WorkspaceAgentScript) logger.Info(ctx, fmt.Sprintf("%s script completed", logPath), slog.F("execution_time", execTime), slog.F("exit_code", exitCode)) } - r.scriptTimings <- timingSpan{ + r.scriptTimings <- TimingSpan{ displayName: script.DisplayName, start: start, end: end, diff --git a/agent/agentscripts/timings.go b/agent/agentscripts/timings.go index 7171147ca50ef..802aeb2cabaea 100644 --- a/agent/agentscripts/timings.go +++ b/agent/agentscripts/timings.go @@ -3,17 +3,18 @@ package agentscripts import ( "time" - "github.com/coder/coder/v2/agent/proto" "google.golang.org/protobuf/types/known/timestamppb" + + "github.com/coder/coder/v2/agent/proto" ) -type timingSpan struct { +type TimingSpan struct { displayName string start, end time.Time exitCode int32 } -func (ts *timingSpan) ToProto() *proto.Timing { +func (ts *TimingSpan) ToProto() *proto.Timing { return &proto.Timing{ DisplayName: ts.displayName, Start: timestamppb.New(ts.start), diff --git a/agent/agenttest/client.go b/agent/agenttest/client.go index 51da04892dbc3..e75631c2316c6 100644 --- a/agent/agenttest/client.go +++ b/agent/agenttest/client.go @@ -301,7 +301,7 @@ func (f *FakeAgentAPI) BatchCreateLogs(ctx context.Context, req *agentproto.Batc return &agentproto.BatchCreateLogsResponse{}, nil } -func (f *FakeAgentAPI) ScriptCompleted(ctx context.Context, req *agentproto.WorkspaceAgentScriptCompletedRequest) (*agentproto.WorkspaceAgentScriptCompletedResponse, error) { +func (*FakeAgentAPI) ScriptCompleted(_ context.Context, _ *agentproto.WorkspaceAgentScriptCompletedRequest) (*agentproto.WorkspaceAgentScriptCompletedResponse, error) { return &agentproto.WorkspaceAgentScriptCompletedResponse{}, nil } diff --git a/cli/organizationsettings.go b/cli/organizationsettings.go index c4422c8d372c6..2c6b901de10ca 100644 --- a/cli/organizationsettings.go +++ b/cli/organizationsettings.go @@ -125,13 +125,13 @@ func (r *RootCmd) setOrganizationSettings(orgContext *OrganizationContext, setti settingJSON, err := json.Marshal(output) if err != nil { - return fmt.Errorf("failed to marshal organization setting %s: %w", inv.Args[0], err) + return xerrors.Errorf("failed to marshal organization setting %s: %w", inv.Args[0], err) } var dst bytes.Buffer err = json.Indent(&dst, settingJSON, "", "\t") if err != nil { - return fmt.Errorf("failed to indent organization setting as json %s: %w", inv.Args[0], err) + return xerrors.Errorf("failed to indent organization setting as json %s: %w", inv.Args[0], err) } _, err = fmt.Fprintln(inv.Stdout, dst.String()) @@ -190,13 +190,13 @@ func (r *RootCmd) printOrganizationSetting(orgContext *OrganizationContext, sett settingJSON, err := json.Marshal(output) if err != nil { - return fmt.Errorf("failed to marshal organization setting %s: %w", inv.Args[0], err) + return xerrors.Errorf("failed to marshal organization setting %s: %w", inv.Args[0], err) } var dst bytes.Buffer err = json.Indent(&dst, settingJSON, "", "\t") if err != nil { - return fmt.Errorf("failed to indent organization setting as json %s: %w", inv.Args[0], err) + return xerrors.Errorf("failed to indent organization setting as json %s: %w", inv.Args[0], err) } _, err = fmt.Fprintln(inv.Stdout, dst.String()) diff --git a/coderd/agentapi/scripts.go b/coderd/agentapi/scripts.go index 50d9455c1d4b6..5f87b58e404dc 100644 --- a/coderd/agentapi/scripts.go +++ b/coderd/agentapi/scripts.go @@ -3,9 +3,10 @@ package agentapi import ( "context" + "github.com/google/uuid" + agentproto "github.com/coder/coder/v2/agent/proto" "github.com/coder/coder/v2/coderd/database" - "github.com/google/uuid" ) type ScriptsAPI struct { diff --git a/coderd/database/dbmem/dbmem.go b/coderd/database/dbmem/dbmem.go index 19bc2a4c5f0e7..c1d1be1f6f4d0 100644 --- a/coderd/database/dbmem/dbmem.go +++ b/coderd/database/dbmem/dbmem.go @@ -7827,7 +7827,7 @@ func (q *FakeQuerier) InsertWorkspaceAgentMetadata(_ context.Context, arg databa return nil } -func (q *FakeQuerier) InsertWorkspaceAgentScriptTimings(ctx context.Context, arg database.InsertWorkspaceAgentScriptTimingsParams) (database.WorkspaceAgentScriptTiming, error) { +func (q *FakeQuerier) InsertWorkspaceAgentScriptTimings(_ context.Context, arg database.InsertWorkspaceAgentScriptTimingsParams) (database.WorkspaceAgentScriptTiming, error) { err := validateDatabaseType(arg) if err != nil { return database.WorkspaceAgentScriptTiming{}, err @@ -7836,6 +7836,7 @@ func (q *FakeQuerier) InsertWorkspaceAgentScriptTimings(ctx context.Context, arg q.mutex.Lock() defer q.mutex.Unlock() + //nolint:gosimple scriptTiming := database.WorkspaceAgentScriptTiming{ StartedAt: arg.StartedAt, EndedAt: arg.EndedAt, From 6d829f3cd20083e75ddf1199366f98b258e303b8 Mon Sep 17 00:00:00 2001 From: Danielle Maywood Date: Wed, 18 Sep 2024 10:23:45 +0000 Subject: [PATCH 07/56] fix: get tests passing again --- agent/agent.go | 7 +--- agent/agentscripts/agentscripts.go | 46 +++++++++++++------------ agent/agentscripts/agentscripts_test.go | 10 ++++-- agent/agentscripts/timings.go | 24 ------------- 4 files changed, 32 insertions(+), 55 deletions(-) delete mode 100644 agent/agentscripts/timings.go diff --git a/agent/agent.go b/agent/agent.go index c07cbe7e96851..1f88666ade522 100644 --- a/agent/agent.go +++ b/agent/agent.go @@ -582,11 +582,6 @@ func (a *agent) reportMetadata(ctx context.Context, conn drpc.Conn) error { select { case <-ctx.Done(): return ctx.Err() - case timing := <-*a.scriptRunner.ScriptTimings(): - _, err := aAPI.ScriptCompleted(ctx, &proto.WorkspaceAgentScriptCompletedRequest{ - Timing: timing.ToProto(), - }) - return err case mr := <-metadataResults: // This can overwrite unsent values, but that's fine because // we're only interested about up-to-date values. @@ -946,7 +941,7 @@ func (a *agent) handleManifest(manifestOK *checkpoint) func(ctx context.Context, } } - err = a.scriptRunner.Init(manifest.Scripts) + err = a.scriptRunner.Init(manifest.Scripts, aAPI.ScriptCompleted) if err != nil { return xerrors.Errorf("init script runner: %w", err) } diff --git a/agent/agentscripts/agentscripts.go b/agent/agentscripts/agentscripts.go index 4673c8f7e3f15..a60ab9e0ab77f 100644 --- a/agent/agentscripts/agentscripts.go +++ b/agent/agentscripts/agentscripts.go @@ -19,10 +19,12 @@ import ( "github.com/spf13/afero" "golang.org/x/sync/errgroup" "golang.org/x/xerrors" + "google.golang.org/protobuf/types/known/timestamppb" "cdr.dev/slog" "github.com/coder/coder/v2/agent/agentssh" + "github.com/coder/coder/v2/agent/proto" "github.com/coder/coder/v2/codersdk" "github.com/coder/coder/v2/codersdk/agentsdk" ) @@ -66,7 +68,6 @@ func New(opts Options) *Runner { cronCtxCancel: cronCtxCancel, cron: cron.New(cron.WithParser(parser)), closed: make(chan struct{}), - scriptTimings: make(chan TimingSpan), dataDir: filepath.Join(opts.DataDirBase, "coder-script-data"), scriptsExecuted: prometheus.NewCounterVec(prometheus.CounterOpts{ Namespace: "agent", @@ -76,19 +77,21 @@ func New(opts Options) *Runner { } } +type ScriptCompletedFunc func(context.Context, *proto.WorkspaceAgentScriptCompletedRequest) (*proto.WorkspaceAgentScriptCompletedResponse, error) + type Runner struct { Options - cronCtx context.Context - cronCtxCancel context.CancelFunc - cmdCloseWait sync.WaitGroup - closed chan struct{} - closeMutex sync.Mutex - cron *cron.Cron - initialized atomic.Bool - scripts []codersdk.WorkspaceAgentScript - scriptTimings chan TimingSpan - dataDir string + cronCtx context.Context + cronCtxCancel context.CancelFunc + cmdCloseWait sync.WaitGroup + closed chan struct{} + closeMutex sync.Mutex + cron *cron.Cron + initialized atomic.Bool + scripts []codersdk.WorkspaceAgentScript + dataDir string + scriptCompleted ScriptCompletedFunc // scriptsExecuted includes all scripts executed by the workspace agent. Agents // execute startup scripts, and scripts on a cron schedule. Both will increment @@ -96,10 +99,6 @@ type Runner struct { scriptsExecuted *prometheus.CounterVec } -func (r *Runner) ScriptTimings() *chan TimingSpan { - return &r.scriptTimings -} - // DataDir returns the directory where scripts data is stored. func (r *Runner) DataDir() string { return r.dataDir @@ -122,12 +121,13 @@ func (r *Runner) RegisterMetrics(reg prometheus.Registerer) { // Init initializes the runner with the provided scripts. // It also schedules any scripts that have a schedule. // This function must be called before Execute. -func (r *Runner) Init(scripts []codersdk.WorkspaceAgentScript) error { +func (r *Runner) Init(scripts []codersdk.WorkspaceAgentScript, scriptCompleted ScriptCompletedFunc) error { if r.initialized.Load() { return xerrors.New("init: already initialized") } r.initialized.Store(true) r.scripts = scripts + r.scriptCompleted = scriptCompleted r.Logger.Info(r.cronCtx, "initializing agent scripts", slog.F("script_count", len(scripts)), slog.F("log_dir", r.LogDir)) err := r.Filesystem.MkdirAll(r.ScriptBinDir(), 0o700) @@ -321,12 +321,14 @@ func (r *Runner) run(ctx context.Context, script codersdk.WorkspaceAgentScript) logger.Info(ctx, fmt.Sprintf("%s script completed", logPath), slog.F("execution_time", execTime), slog.F("exit_code", exitCode)) } - r.scriptTimings <- TimingSpan{ - displayName: script.DisplayName, - start: start, - end: end, - exitCode: int32(exitCode), - } + _, err = r.scriptCompleted(ctx, &proto.WorkspaceAgentScriptCompletedRequest{ + Timing: &proto.Timing{ + DisplayName: script.DisplayName, + Start: timestamppb.New(start), + End: timestamppb.New(end), + ExitCode: int32(exitCode), + }, + }) }() err = cmd.Start() diff --git a/agent/agentscripts/agentscripts_test.go b/agent/agentscripts/agentscripts_test.go index 2be7e76c54f6a..5e428de972efc 100644 --- a/agent/agentscripts/agentscripts_test.go +++ b/agent/agentscripts/agentscripts_test.go @@ -17,6 +17,7 @@ import ( "cdr.dev/slog/sloggers/slogtest" "github.com/coder/coder/v2/agent/agentscripts" "github.com/coder/coder/v2/agent/agentssh" + "github.com/coder/coder/v2/agent/agenttest" "github.com/coder/coder/v2/codersdk" "github.com/coder/coder/v2/codersdk/agentsdk" "github.com/coder/coder/v2/testutil" @@ -34,10 +35,11 @@ func TestExecuteBasic(t *testing.T) { return fLogger }) defer runner.Close() + aAPI := agenttest.NewFakeAgentAPI(t, slogtest.Make(t, nil), nil, nil) err := runner.Init([]codersdk.WorkspaceAgentScript{{ LogSourceID: uuid.New(), Script: "echo hello", - }}) + }}, aAPI.ScriptCompleted) require.NoError(t, err) require.NoError(t, runner.Execute(context.Background(), func(script codersdk.WorkspaceAgentScript) bool { return true @@ -61,10 +63,11 @@ func TestEnv(t *testing.T) { cmd.exe /c echo %CODER_SCRIPT_BIN_DIR% ` } + aAPI := agenttest.NewFakeAgentAPI(t, slogtest.Make(t, nil), nil, nil) err := runner.Init([]codersdk.WorkspaceAgentScript{{ LogSourceID: id, Script: script, - }}) + }}, aAPI.ScriptCompleted) require.NoError(t, err) ctx := testutil.Context(t, testutil.WaitLong) @@ -103,11 +106,12 @@ func TestTimeout(t *testing.T) { t.Parallel() runner := setup(t, nil) defer runner.Close() + aAPI := agenttest.NewFakeAgentAPI(t, slogtest.Make(t, nil), nil, nil) err := runner.Init([]codersdk.WorkspaceAgentScript{{ LogSourceID: uuid.New(), Script: "sleep infinity", Timeout: time.Millisecond, - }}) + }}, aAPI.ScriptCompleted) require.NoError(t, err) require.ErrorIs(t, runner.Execute(context.Background(), nil), agentscripts.ErrTimeout) } diff --git a/agent/agentscripts/timings.go b/agent/agentscripts/timings.go deleted file mode 100644 index 802aeb2cabaea..0000000000000 --- a/agent/agentscripts/timings.go +++ /dev/null @@ -1,24 +0,0 @@ -package agentscripts - -import ( - "time" - - "google.golang.org/protobuf/types/known/timestamppb" - - "github.com/coder/coder/v2/agent/proto" -) - -type TimingSpan struct { - displayName string - start, end time.Time - exitCode int32 -} - -func (ts *TimingSpan) ToProto() *proto.Timing { - return &proto.Timing{ - DisplayName: ts.displayName, - Start: timestamppb.New(ts.start), - End: timestamppb.New(ts.end), - ExitCode: ts.exitCode, - } -} From 4df7831533ec819973d2fbda5190900813a24961 Mon Sep 17 00:00:00 2001 From: Danielle Maywood Date: Wed, 18 Sep 2024 10:32:29 +0000 Subject: [PATCH 08/56] fix: drop column from correct table --- .../migrations/000254_workspace_agent_script_timings.down.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coderd/database/migrations/000254_workspace_agent_script_timings.down.sql b/coderd/database/migrations/000254_workspace_agent_script_timings.down.sql index 6be79a649ffed..219871e3e1e1d 100644 --- a/coderd/database/migrations/000254_workspace_agent_script_timings.down.sql +++ b/coderd/database/migrations/000254_workspace_agent_script_timings.down.sql @@ -1,3 +1,3 @@ DROP TABLE IF EXISTS workspace_agent_script_timings; -ALTER TABLE workspace_apps DROP COLUMN display_name; +ALTER TABLE workspace_agent_scripts DROP COLUMN display_name; From 2565f0ab51567ab4005929fb3e07a9a7742610cc Mon Sep 17 00:00:00 2001 From: Danielle Maywood Date: Wed, 18 Sep 2024 10:43:39 +0000 Subject: [PATCH 09/56] test: add fixture for agent script timings --- .../fixtures/000254_workspace_agent_script_timings.up.sql | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 coderd/database/migrations/testdata/fixtures/000254_workspace_agent_script_timings.up.sql diff --git a/coderd/database/migrations/testdata/fixtures/000254_workspace_agent_script_timings.up.sql b/coderd/database/migrations/testdata/fixtures/000254_workspace_agent_script_timings.up.sql new file mode 100644 index 0000000000000..f5fb322639142 --- /dev/null +++ b/coderd/database/migrations/testdata/fixtures/000254_workspace_agent_script_timings.up.sql @@ -0,0 +1,3 @@ +INSERT INTO workspace_agent_sscript_timings (job_id, display_name, started_at, ended_at, exit_code) +VALUES + ('f41f5fd1-2a4e-4e52-adad-aee36d2da506', 'Startup Script', NOW() - INTERVAL '1 hour 55 minutes', NOW() - INTERVAL '1 hour 50 minutes', 0); From 669b837a34a224ff1edf171151cfc1b27c108d42 Mon Sep 17 00:00:00 2001 From: Danielle Maywood Date: Wed, 18 Sep 2024 10:52:44 +0000 Subject: [PATCH 10/56] fix: typo --- .../fixtures/000254_workspace_agent_script_timings.up.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coderd/database/migrations/testdata/fixtures/000254_workspace_agent_script_timings.up.sql b/coderd/database/migrations/testdata/fixtures/000254_workspace_agent_script_timings.up.sql index f5fb322639142..42ba373d48e4f 100644 --- a/coderd/database/migrations/testdata/fixtures/000254_workspace_agent_script_timings.up.sql +++ b/coderd/database/migrations/testdata/fixtures/000254_workspace_agent_script_timings.up.sql @@ -1,3 +1,3 @@ -INSERT INTO workspace_agent_sscript_timings (job_id, display_name, started_at, ended_at, exit_code) +INSERT INTO workspace_agent_script_timings (job_id, display_name, started_at, ended_at, exit_code) VALUES ('f41f5fd1-2a4e-4e52-adad-aee36d2da506', 'Startup Script', NOW() - INTERVAL '1 hour 55 minutes', NOW() - INTERVAL '1 hour 50 minutes', 0); From df5167313bc7073e0d16f1b9a0b170bf839843e9 Mon Sep 17 00:00:00 2001 From: Danielle Maywood Date: Wed, 18 Sep 2024 12:48:41 +0000 Subject: [PATCH 11/56] fix: use job id used in provisioner job timings --- .../fixtures/000254_workspace_agent_script_timings.up.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coderd/database/migrations/testdata/fixtures/000254_workspace_agent_script_timings.up.sql b/coderd/database/migrations/testdata/fixtures/000254_workspace_agent_script_timings.up.sql index 42ba373d48e4f..e8bafa2c8b88a 100644 --- a/coderd/database/migrations/testdata/fixtures/000254_workspace_agent_script_timings.up.sql +++ b/coderd/database/migrations/testdata/fixtures/000254_workspace_agent_script_timings.up.sql @@ -1,3 +1,3 @@ INSERT INTO workspace_agent_script_timings (job_id, display_name, started_at, ended_at, exit_code) VALUES - ('f41f5fd1-2a4e-4e52-adad-aee36d2da506', 'Startup Script', NOW() - INTERVAL '1 hour 55 minutes', NOW() - INTERVAL '1 hour 50 minutes', 0); + ('424a58cb-61d6-4627-9907-613c396c4a38', 'Startup Script', NOW() - INTERVAL '1 hour 55 minutes', NOW() - INTERVAL '1 hour 50 minutes', 0); From c6d71d1024958b75b53cdf2d964f66e7262e6270 Mon Sep 17 00:00:00 2001 From: Danielle Maywood Date: Wed, 18 Sep 2024 13:03:01 +0000 Subject: [PATCH 12/56] fix: increment migration number --- ...gs.down.sql => 000255_workspace_agent_script_timings.down.sql} | 0 ...imings.up.sql => 000255_workspace_agent_script_timings.up.sql} | 0 ...imings.up.sql => 000255_workspace_agent_script_timings.up.sql} | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename coderd/database/migrations/{000254_workspace_agent_script_timings.down.sql => 000255_workspace_agent_script_timings.down.sql} (100%) rename coderd/database/migrations/{000254_workspace_agent_script_timings.up.sql => 000255_workspace_agent_script_timings.up.sql} (100%) rename coderd/database/migrations/testdata/fixtures/{000254_workspace_agent_script_timings.up.sql => 000255_workspace_agent_script_timings.up.sql} (100%) diff --git a/coderd/database/migrations/000254_workspace_agent_script_timings.down.sql b/coderd/database/migrations/000255_workspace_agent_script_timings.down.sql similarity index 100% rename from coderd/database/migrations/000254_workspace_agent_script_timings.down.sql rename to coderd/database/migrations/000255_workspace_agent_script_timings.down.sql diff --git a/coderd/database/migrations/000254_workspace_agent_script_timings.up.sql b/coderd/database/migrations/000255_workspace_agent_script_timings.up.sql similarity index 100% rename from coderd/database/migrations/000254_workspace_agent_script_timings.up.sql rename to coderd/database/migrations/000255_workspace_agent_script_timings.up.sql diff --git a/coderd/database/migrations/testdata/fixtures/000254_workspace_agent_script_timings.up.sql b/coderd/database/migrations/testdata/fixtures/000255_workspace_agent_script_timings.up.sql similarity index 100% rename from coderd/database/migrations/testdata/fixtures/000254_workspace_agent_script_timings.up.sql rename to coderd/database/migrations/testdata/fixtures/000255_workspace_agent_script_timings.up.sql From a306e480ec794eda2286e7321e1482724d8a3060 Mon Sep 17 00:00:00 2001 From: Danielle Maywood Date: Wed, 18 Sep 2024 13:45:15 +0000 Subject: [PATCH 13/56] test: behaviour of script runner --- agent/agentscripts/agentscripts_test.go | 46 +++++++++++++++++++++++++ agent/agenttest/client.go | 11 +++++- 2 files changed, 56 insertions(+), 1 deletion(-) diff --git a/agent/agentscripts/agentscripts_test.go b/agent/agentscripts/agentscripts_test.go index 5e428de972efc..8200df6d0e85a 100644 --- a/agent/agentscripts/agentscripts_test.go +++ b/agent/agentscripts/agentscripts_test.go @@ -116,6 +116,52 @@ func TestTimeout(t *testing.T) { require.ErrorIs(t, runner.Execute(context.Background(), nil), agentscripts.ErrTimeout) } +func TestScriptReportsTiming(t *testing.T) { + t.Parallel() + + tests := []struct { + displayName string + script string + exitCode int32 + }{ + { + displayName: "exit-0", + script: "exit 0", + exitCode: 0, + }, + { + displayName: "exit-1", + script: "exit 1", + exitCode: 1, + }, + } + + for _, tt := range tests { + ctx := testutil.Context(t, testutil.WaitShort) + fLogger := newFakeScriptLogger() + runner := setup(t, func(uuid2 uuid.UUID) agentscripts.ScriptLogger { + return fLogger + }) + defer runner.Close() + aAPI := agenttest.NewFakeAgentAPI(t, slogtest.Make(t, nil), nil, nil) + err := runner.Init([]codersdk.WorkspaceAgentScript{{ + DisplayName: tt.displayName, + LogSourceID: uuid.New(), + Script: tt.script, + }}, aAPI.ScriptCompleted) + require.NoError(t, err) + require.NoError(t, runner.Execute(context.Background(), func(script codersdk.WorkspaceAgentScript) bool { + return true + })) + _ = testutil.RequireRecvCtx(ctx, t, fLogger.logs) + + require.Equal(t, len(aAPI.GetTiming()), 1) + timing := aAPI.GetTiming()[0] + require.Equal(t, timing.DisplayName, tt.displayName) + require.Equal(t, timing.ExitCode, tt.exitCode) + } +} + // TestCronClose exists because cron.Run() can happen after cron.Close(). // If this happens, there used to be a deadlock. func TestCronClose(t *testing.T) { diff --git a/agent/agenttest/client.go b/agent/agenttest/client.go index e75631c2316c6..4f1dbe1450c4e 100644 --- a/agent/agenttest/client.go +++ b/agent/agenttest/client.go @@ -170,6 +170,7 @@ type FakeAgentAPI struct { logsCh chan<- *agentproto.BatchCreateLogsRequest lifecycleStates []codersdk.WorkspaceAgentLifecycle metadata map[string]agentsdk.Metadata + timing []*agentproto.Timing getAnnouncementBannersFunc func() ([]codersdk.BannerConfig, error) } @@ -182,6 +183,10 @@ func (*FakeAgentAPI) GetServiceBanner(context.Context, *agentproto.GetServiceBan return &agentproto.ServiceBanner{}, nil } +func (f *FakeAgentAPI) GetTiming() []*agentproto.Timing { + return f.timing +} + func (f *FakeAgentAPI) SetAnnouncementBannersFunc(fn func() ([]codersdk.BannerConfig, error)) { f.Lock() defer f.Unlock() @@ -301,7 +306,11 @@ func (f *FakeAgentAPI) BatchCreateLogs(ctx context.Context, req *agentproto.Batc return &agentproto.BatchCreateLogsResponse{}, nil } -func (*FakeAgentAPI) ScriptCompleted(_ context.Context, _ *agentproto.WorkspaceAgentScriptCompletedRequest) (*agentproto.WorkspaceAgentScriptCompletedResponse, error) { +func (f *FakeAgentAPI) ScriptCompleted(_ context.Context, req *agentproto.WorkspaceAgentScriptCompletedRequest) (*agentproto.WorkspaceAgentScriptCompletedResponse, error) { + f.Lock() + f.timing = append(f.timing, req.Timing) + f.Unlock() + return &agentproto.WorkspaceAgentScriptCompletedResponse{}, nil } From 4b0056c37d9328ba81aa97c8f5cf6a14ec37bcb2 Mon Sep 17 00:00:00 2001 From: Danielle Maywood Date: Wed, 18 Sep 2024 13:58:20 +0000 Subject: [PATCH 14/56] test: rewrite test --- agent/agentscripts/agentscripts_test.go | 61 +++++++++++++++++-------- 1 file changed, 41 insertions(+), 20 deletions(-) diff --git a/agent/agentscripts/agentscripts_test.go b/agent/agentscripts/agentscripts_test.go index 8200df6d0e85a..e9b46e521baee 100644 --- a/agent/agentscripts/agentscripts_test.go +++ b/agent/agentscripts/agentscripts_test.go @@ -1,9 +1,11 @@ package agentscripts_test import ( + "cmp" "context" "path/filepath" "runtime" + "slices" "testing" "time" @@ -18,6 +20,7 @@ import ( "github.com/coder/coder/v2/agent/agentscripts" "github.com/coder/coder/v2/agent/agentssh" "github.com/coder/coder/v2/agent/agenttest" + "github.com/coder/coder/v2/agent/proto" "github.com/coder/coder/v2/codersdk" "github.com/coder/coder/v2/codersdk/agentsdk" "github.com/coder/coder/v2/testutil" @@ -119,11 +122,13 @@ func TestTimeout(t *testing.T) { func TestScriptReportsTiming(t *testing.T) { t.Parallel() - tests := []struct { + type test struct { displayName string script string exitCode int32 - }{ + } + + tests := []test{ { displayName: "exit-0", script: "exit 0", @@ -136,29 +141,45 @@ func TestScriptReportsTiming(t *testing.T) { }, } + ctx := testutil.Context(t, testutil.WaitShort) + fLogger := newFakeScriptLogger() + runner := setup(t, func(uuid2 uuid.UUID) agentscripts.ScriptLogger { + return fLogger + }) + defer runner.Close() + aAPI := agenttest.NewFakeAgentAPI(t, slogtest.Make(t, nil), nil, nil) + + scripts := []codersdk.WorkspaceAgentScript{} for _, tt := range tests { - ctx := testutil.Context(t, testutil.WaitShort) - fLogger := newFakeScriptLogger() - runner := setup(t, func(uuid2 uuid.UUID) agentscripts.ScriptLogger { - return fLogger - }) - defer runner.Close() - aAPI := agenttest.NewFakeAgentAPI(t, slogtest.Make(t, nil), nil, nil) - err := runner.Init([]codersdk.WorkspaceAgentScript{{ + scripts = append(scripts, codersdk.WorkspaceAgentScript{ DisplayName: tt.displayName, LogSourceID: uuid.New(), Script: tt.script, - }}, aAPI.ScriptCompleted) - require.NoError(t, err) - require.NoError(t, runner.Execute(context.Background(), func(script codersdk.WorkspaceAgentScript) bool { - return true - })) - _ = testutil.RequireRecvCtx(ctx, t, fLogger.logs) + }) + } + + err := runner.Init(scripts, aAPI.ScriptCompleted) + require.NoError(t, err) + require.NoError(t, runner.Execute(context.Background(), func(script codersdk.WorkspaceAgentScript) bool { + return true + })) + _ = testutil.RequireRecvCtx(ctx, t, fLogger.logs) + + timing := aAPI.GetTiming() + require.Equal(t, len(timing), len(tests)) + + // Sort the tests and timing by display name to ensure + // consistent order. + slices.SortFunc(timing, func(a, b *proto.Timing) int { + return cmp.Compare(a.DisplayName, b.DisplayName) + }) + slices.SortFunc(tests, func(a, b test) int { + return cmp.Compare(a.displayName, b.displayName) + }) - require.Equal(t, len(aAPI.GetTiming()), 1) - timing := aAPI.GetTiming()[0] - require.Equal(t, timing.DisplayName, tt.displayName) - require.Equal(t, timing.ExitCode, tt.exitCode) + for i, tt := range tests { + require.Equal(t, timing[i].DisplayName, tt.displayName) + require.Equal(t, timing[i].ExitCode, tt.exitCode) } } From 14b68a162cb91cc09bb9413bdbfeb53657bb567d Mon Sep 17 00:00:00 2001 From: Danielle Maywood Date: Wed, 18 Sep 2024 14:07:08 +0000 Subject: [PATCH 15/56] test: does exit 1 script break things? --- agent/agentscripts/agentscripts_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/agent/agentscripts/agentscripts_test.go b/agent/agentscripts/agentscripts_test.go index e9b46e521baee..74da6d1b29428 100644 --- a/agent/agentscripts/agentscripts_test.go +++ b/agent/agentscripts/agentscripts_test.go @@ -135,9 +135,9 @@ func TestScriptReportsTiming(t *testing.T) { exitCode: 0, }, { - displayName: "exit-1", - script: "exit 1", - exitCode: 1, + displayName: "say-hello", + script: "echo 'Hello, World!'", + exitCode: 0, }, } From b22cb575e2b1d1ca09349dd16bf612765bf6476e Mon Sep 17 00:00:00 2001 From: Danielle Maywood Date: Wed, 18 Sep 2024 14:24:41 +0000 Subject: [PATCH 16/56] test: rewrite test again --- agent/agentscripts/agentscripts_test.go | 65 +++++-------------------- agent/agenttest/client.go | 8 +-- 2 files changed, 17 insertions(+), 56 deletions(-) diff --git a/agent/agentscripts/agentscripts_test.go b/agent/agentscripts/agentscripts_test.go index 74da6d1b29428..0409e46696041 100644 --- a/agent/agentscripts/agentscripts_test.go +++ b/agent/agentscripts/agentscripts_test.go @@ -1,11 +1,9 @@ package agentscripts_test import ( - "cmp" "context" "path/filepath" "runtime" - "slices" "testing" "time" @@ -20,7 +18,6 @@ import ( "github.com/coder/coder/v2/agent/agentscripts" "github.com/coder/coder/v2/agent/agentssh" "github.com/coder/coder/v2/agent/agenttest" - "github.com/coder/coder/v2/agent/proto" "github.com/coder/coder/v2/codersdk" "github.com/coder/coder/v2/codersdk/agentsdk" "github.com/coder/coder/v2/testutil" @@ -121,26 +118,6 @@ func TestTimeout(t *testing.T) { func TestScriptReportsTiming(t *testing.T) { t.Parallel() - - type test struct { - displayName string - script string - exitCode int32 - } - - tests := []test{ - { - displayName: "exit-0", - script: "exit 0", - exitCode: 0, - }, - { - displayName: "say-hello", - script: "echo 'Hello, World!'", - exitCode: 0, - }, - } - ctx := testutil.Context(t, testutil.WaitShort) fLogger := newFakeScriptLogger() runner := setup(t, func(uuid2 uuid.UUID) agentscripts.ScriptLogger { @@ -148,39 +125,23 @@ func TestScriptReportsTiming(t *testing.T) { }) defer runner.Close() aAPI := agenttest.NewFakeAgentAPI(t, slogtest.Make(t, nil), nil, nil) - - scripts := []codersdk.WorkspaceAgentScript{} - for _, tt := range tests { - scripts = append(scripts, codersdk.WorkspaceAgentScript{ - DisplayName: tt.displayName, - LogSourceID: uuid.New(), - Script: tt.script, - }) - } - - err := runner.Init(scripts, aAPI.ScriptCompleted) + err := runner.Init([]codersdk.WorkspaceAgentScript{{ + DisplayName: "say-hello", + LogSourceID: uuid.New(), + Script: "echo hello", + }}, aAPI.ScriptCompleted) require.NoError(t, err) require.NoError(t, runner.Execute(context.Background(), func(script codersdk.WorkspaceAgentScript) bool { return true })) - _ = testutil.RequireRecvCtx(ctx, t, fLogger.logs) - - timing := aAPI.GetTiming() - require.Equal(t, len(timing), len(tests)) - - // Sort the tests and timing by display name to ensure - // consistent order. - slices.SortFunc(timing, func(a, b *proto.Timing) int { - return cmp.Compare(a.DisplayName, b.DisplayName) - }) - slices.SortFunc(tests, func(a, b test) int { - return cmp.Compare(a.displayName, b.displayName) - }) - - for i, tt := range tests { - require.Equal(t, timing[i].DisplayName, tt.displayName) - require.Equal(t, timing[i].ExitCode, tt.exitCode) - } + log := testutil.RequireRecvCtx(ctx, t, fLogger.logs) + require.Equal(t, "hello", log.Output) + timings := aAPI.GetTimings() + require.Equal(t, len(timings), 1) + timing := timings[0] + require.Equal(t, timing.DisplayName, "say-hello") + require.Equal(t, timing.ExitCode, int32(0)) + require.GreaterOrEqual(t, timing.End.AsTime(), timing.Start.AsTime()) } // TestCronClose exists because cron.Run() can happen after cron.Close(). diff --git a/agent/agenttest/client.go b/agent/agenttest/client.go index 4f1dbe1450c4e..567df8761475f 100644 --- a/agent/agenttest/client.go +++ b/agent/agenttest/client.go @@ -170,7 +170,7 @@ type FakeAgentAPI struct { logsCh chan<- *agentproto.BatchCreateLogsRequest lifecycleStates []codersdk.WorkspaceAgentLifecycle metadata map[string]agentsdk.Metadata - timing []*agentproto.Timing + timings []*agentproto.Timing getAnnouncementBannersFunc func() ([]codersdk.BannerConfig, error) } @@ -183,8 +183,8 @@ func (*FakeAgentAPI) GetServiceBanner(context.Context, *agentproto.GetServiceBan return &agentproto.ServiceBanner{}, nil } -func (f *FakeAgentAPI) GetTiming() []*agentproto.Timing { - return f.timing +func (f *FakeAgentAPI) GetTimings() []*agentproto.Timing { + return f.timings } func (f *FakeAgentAPI) SetAnnouncementBannersFunc(fn func() ([]codersdk.BannerConfig, error)) { @@ -308,7 +308,7 @@ func (f *FakeAgentAPI) BatchCreateLogs(ctx context.Context, req *agentproto.Batc func (f *FakeAgentAPI) ScriptCompleted(_ context.Context, req *agentproto.WorkspaceAgentScriptCompletedRequest) (*agentproto.WorkspaceAgentScriptCompletedResponse, error) { f.Lock() - f.timing = append(f.timing, req.Timing) + f.timings = append(f.timings, req.Timing) f.Unlock() return &agentproto.WorkspaceAgentScriptCompletedResponse{}, nil From ef5e2fef159c5a43d988efcbdacb3a3cc73fea5a Mon Sep 17 00:00:00 2001 From: Danielle Maywood Date: Thu, 19 Sep 2024 08:10:34 +0000 Subject: [PATCH 17/56] fix: revert change Not sure how this came to be, I do not recall manually changing these files. --- cli/organizationsettings.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cli/organizationsettings.go b/cli/organizationsettings.go index 2c6b901de10ca..c4422c8d372c6 100644 --- a/cli/organizationsettings.go +++ b/cli/organizationsettings.go @@ -125,13 +125,13 @@ func (r *RootCmd) setOrganizationSettings(orgContext *OrganizationContext, setti settingJSON, err := json.Marshal(output) if err != nil { - return xerrors.Errorf("failed to marshal organization setting %s: %w", inv.Args[0], err) + return fmt.Errorf("failed to marshal organization setting %s: %w", inv.Args[0], err) } var dst bytes.Buffer err = json.Indent(&dst, settingJSON, "", "\t") if err != nil { - return xerrors.Errorf("failed to indent organization setting as json %s: %w", inv.Args[0], err) + return fmt.Errorf("failed to indent organization setting as json %s: %w", inv.Args[0], err) } _, err = fmt.Fprintln(inv.Stdout, dst.String()) @@ -190,13 +190,13 @@ func (r *RootCmd) printOrganizationSetting(orgContext *OrganizationContext, sett settingJSON, err := json.Marshal(output) if err != nil { - return xerrors.Errorf("failed to marshal organization setting %s: %w", inv.Args[0], err) + return fmt.Errorf("failed to marshal organization setting %s: %w", inv.Args[0], err) } var dst bytes.Buffer err = json.Indent(&dst, settingJSON, "", "\t") if err != nil { - return xerrors.Errorf("failed to indent organization setting as json %s: %w", inv.Args[0], err) + return fmt.Errorf("failed to indent organization setting as json %s: %w", inv.Args[0], err) } _, err = fmt.Fprintln(inv.Stdout, dst.String()) From a5b412bef857c8541c596edcc1ddec01905a9f87 Mon Sep 17 00:00:00 2001 From: Danielle Maywood Date: Thu, 19 Sep 2024 08:25:33 +0000 Subject: [PATCH 18/56] fix: let code breathe --- agent/agentscripts/agentscripts_test.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/agent/agentscripts/agentscripts_test.go b/agent/agentscripts/agentscripts_test.go index 0409e46696041..218b73514af78 100644 --- a/agent/agentscripts/agentscripts_test.go +++ b/agent/agentscripts/agentscripts_test.go @@ -118,12 +118,14 @@ func TestTimeout(t *testing.T) { func TestScriptReportsTiming(t *testing.T) { t.Parallel() + ctx := testutil.Context(t, testutil.WaitShort) fLogger := newFakeScriptLogger() runner := setup(t, func(uuid2 uuid.UUID) agentscripts.ScriptLogger { return fLogger }) defer runner.Close() + aAPI := agenttest.NewFakeAgentAPI(t, slogtest.Make(t, nil), nil, nil) err := runner.Init([]codersdk.WorkspaceAgentScript{{ DisplayName: "say-hello", @@ -134,10 +136,13 @@ func TestScriptReportsTiming(t *testing.T) { require.NoError(t, runner.Execute(context.Background(), func(script codersdk.WorkspaceAgentScript) bool { return true })) + log := testutil.RequireRecvCtx(ctx, t, fLogger.logs) require.Equal(t, "hello", log.Output) + timings := aAPI.GetTimings() require.Equal(t, len(timings), 1) + timing := timings[0] require.Equal(t, timing.DisplayName, "say-hello") require.Equal(t, timing.ExitCode, int32(0)) From 57ebf306ede49981c6c1af9a120167f8f42c5ae3 Mon Sep 17 00:00:00 2001 From: Danielle Maywood Date: Thu, 19 Sep 2024 08:25:43 +0000 Subject: [PATCH 19/56] fix: wrap errors --- coderd/agentapi/scripts.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/coderd/agentapi/scripts.go b/coderd/agentapi/scripts.go index 5f87b58e404dc..566894b44c0f6 100644 --- a/coderd/agentapi/scripts.go +++ b/coderd/agentapi/scripts.go @@ -4,6 +4,7 @@ import ( "context" "github.com/google/uuid" + "golang.org/x/xerrors" agentproto "github.com/coder/coder/v2/agent/proto" "github.com/coder/coder/v2/coderd/database" @@ -19,12 +20,12 @@ func (s *ScriptsAPI) ScriptCompleted(ctx context.Context, req *agentproto.Worksp agent, err := s.Database.GetWorkspaceAgentByID(ctx, s.AgentID) if err != nil { - return nil, err + return nil, xerrors.Errorf("get workspace agent by id in database: %w", err) } resource, err := s.Database.GetWorkspaceResourceByID(ctx, agent.ResourceID) if err != nil { - return nil, err + return nil, xerrors.Errorf("get workspace resource by id in database: %w", err) } _, err = s.Database.InsertWorkspaceAgentScriptTimings(ctx, database.InsertWorkspaceAgentScriptTimingsParams{ @@ -35,7 +36,7 @@ func (s *ScriptsAPI) ScriptCompleted(ctx context.Context, req *agentproto.Worksp ExitCode: req.Timing.ExitCode, }) if err != nil { - return nil, err + return nil, xerrors.Errorf("insert workspace agent script timings into database: %w", err) } return res, nil From 2a49f67460b382d4041e3ef4d97b1dddf86be93e Mon Sep 17 00:00:00 2001 From: Danielle Maywood Date: Thu, 19 Sep 2024 08:27:08 +0000 Subject: [PATCH 20/56] fix: justify nolint --- coderd/database/dbmem/dbmem.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coderd/database/dbmem/dbmem.go b/coderd/database/dbmem/dbmem.go index c1d1be1f6f4d0..1826d3db1676c 100644 --- a/coderd/database/dbmem/dbmem.go +++ b/coderd/database/dbmem/dbmem.go @@ -7836,7 +7836,7 @@ func (q *FakeQuerier) InsertWorkspaceAgentScriptTimings(_ context.Context, arg d q.mutex.Lock() defer q.mutex.Unlock() - //nolint:gosimple + //nolint:gosimple // Stop linter suggesting 'arg' should be of type database.WorkspaceAgentScriptTiming scriptTiming := database.WorkspaceAgentScriptTiming{ StartedAt: arg.StartedAt, EndedAt: arg.EndedAt, From 0698584e2d1c87b1c6e393d55188685e2ea482cf Mon Sep 17 00:00:00 2001 From: Danielle Maywood Date: Thu, 19 Sep 2024 08:29:18 +0000 Subject: [PATCH 21/56] fix: swap require.Equal argument order --- agent/agentscripts/agentscripts_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/agent/agentscripts/agentscripts_test.go b/agent/agentscripts/agentscripts_test.go index 218b73514af78..8aa8d70279629 100644 --- a/agent/agentscripts/agentscripts_test.go +++ b/agent/agentscripts/agentscripts_test.go @@ -141,11 +141,11 @@ func TestScriptReportsTiming(t *testing.T) { require.Equal(t, "hello", log.Output) timings := aAPI.GetTimings() - require.Equal(t, len(timings), 1) + require.Equal(t, 1, len(timings)) timing := timings[0] - require.Equal(t, timing.DisplayName, "say-hello") - require.Equal(t, timing.ExitCode, int32(0)) + require.Equal(t, "say-hello", timing.DisplayName) + require.Equal(t, int32(0), timing.ExitCode) require.GreaterOrEqual(t, timing.End.AsTime(), timing.Start.AsTime()) } From 3580069bbb6ed8da8dca921274a9a683e18f84cc Mon Sep 17 00:00:00 2001 From: Danielle Maywood Date: Thu, 19 Sep 2024 08:39:36 +0000 Subject: [PATCH 22/56] fix: add mutex operations --- agent/agenttest/client.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/agent/agenttest/client.go b/agent/agenttest/client.go index 567df8761475f..a17f9200a9b87 100644 --- a/agent/agenttest/client.go +++ b/agent/agenttest/client.go @@ -184,7 +184,9 @@ func (*FakeAgentAPI) GetServiceBanner(context.Context, *agentproto.GetServiceBan } func (f *FakeAgentAPI) GetTimings() []*agentproto.Timing { - return f.timings + f.Lock() + defer f.Unlock() + return slices.Clone(f.timings) } func (f *FakeAgentAPI) SetAnnouncementBannersFunc(fn func() ([]codersdk.BannerConfig, error)) { From 9cb1252d029b09bd30214708abda75a92a17ed1c Mon Sep 17 00:00:00 2001 From: Danielle Maywood Date: Thu, 19 Sep 2024 09:24:59 +0000 Subject: [PATCH 23/56] feat: add 'ran_on_start' and 'blocked_login' fields --- agent/agentscripts/agentscripts.go | 10 +- agent/proto/agent.pb.go | 172 ++++++++++-------- agent/proto/agent.proto | 2 + coderd/agentapi/scripts.go | 12 +- coderd/database/dbmem/dbmem.go | 12 +- coderd/database/dump.sql | 4 +- ...0255_workspace_agent_script_timings.up.sql | 12 +- coderd/database/models.go | 12 +- coderd/database/queries.sql.go | 22 ++- coderd/database/queries/workspaceagents.sql | 6 +- 10 files changed, 154 insertions(+), 110 deletions(-) diff --git a/agent/agentscripts/agentscripts.go b/agent/agentscripts/agentscripts.go index a60ab9e0ab77f..8bd1b11bd275d 100644 --- a/agent/agentscripts/agentscripts.go +++ b/agent/agentscripts/agentscripts.go @@ -323,10 +323,12 @@ func (r *Runner) run(ctx context.Context, script codersdk.WorkspaceAgentScript) _, err = r.scriptCompleted(ctx, &proto.WorkspaceAgentScriptCompletedRequest{ Timing: &proto.Timing{ - DisplayName: script.DisplayName, - Start: timestamppb.New(start), - End: timestamppb.New(end), - ExitCode: int32(exitCode), + DisplayName: script.DisplayName, + Start: timestamppb.New(start), + End: timestamppb.New(end), + ExitCode: int32(exitCode), + RanOnStart: script.RunOnStart, + BlockedLogin: script.StartBlocksLogin, }, }) }() diff --git a/agent/proto/agent.pb.go b/agent/proto/agent.pb.go index fd98440161783..97c03588288a9 100644 --- a/agent/proto/agent.pb.go +++ b/agent/proto/agent.pb.go @@ -2113,10 +2113,12 @@ type Timing struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - DisplayName string `protobuf:"bytes,1,opt,name=display_name,json=displayName,proto3" json:"display_name,omitempty"` - Start *timestamppb.Timestamp `protobuf:"bytes,2,opt,name=start,proto3" json:"start,omitempty"` - End *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=end,proto3" json:"end,omitempty"` - ExitCode int32 `protobuf:"varint,4,opt,name=exit_code,json=exitCode,proto3" json:"exit_code,omitempty"` + DisplayName string `protobuf:"bytes,1,opt,name=display_name,json=displayName,proto3" json:"display_name,omitempty"` + Start *timestamppb.Timestamp `protobuf:"bytes,2,opt,name=start,proto3" json:"start,omitempty"` + End *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=end,proto3" json:"end,omitempty"` + ExitCode int32 `protobuf:"varint,4,opt,name=exit_code,json=exitCode,proto3" json:"exit_code,omitempty"` + RanOnStart bool `protobuf:"varint,5,opt,name=ran_on_start,json=ranOnStart,proto3" json:"ran_on_start,omitempty"` + BlockedLogin bool `protobuf:"varint,6,opt,name=blocked_login,json=blockedLogin,proto3" json:"blocked_login,omitempty"` } func (x *Timing) Reset() { @@ -2179,6 +2181,20 @@ func (x *Timing) GetExitCode() int32 { return 0 } +func (x *Timing) GetRanOnStart() bool { + if x != nil { + return x.RanOnStart + } + return false +} + +func (x *Timing) GetBlockedLogin() bool { + if x != nil { + return x.BlockedLogin + } + return false +} + type WorkspaceApp_Healthcheck struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -2942,7 +2958,7 @@ var file_agent_proto_agent_proto_rawDesc = []byte{ 0x6e, 0x67, 0x52, 0x06, 0x74, 0x69, 0x6d, 0x69, 0x6e, 0x67, 0x22, 0x27, 0x0a, 0x25, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0xa8, 0x01, 0x0a, 0x06, 0x54, 0x69, 0x6d, 0x69, 0x6e, 0x67, 0x12, 0x21, + 0x6e, 0x73, 0x65, 0x22, 0xef, 0x01, 0x0a, 0x06, 0x54, 0x69, 0x6d, 0x69, 0x6e, 0x67, 0x12, 0x21, 0x0a, 0x0c, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x30, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, @@ -2952,80 +2968,84 @@ var file_agent_proto_agent_proto_rawDesc = []byte{ 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x03, 0x65, 0x6e, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x65, 0x78, 0x69, 0x74, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x65, 0x78, 0x69, 0x74, 0x43, 0x6f, 0x64, 0x65, 0x2a, 0x63, - 0x0a, 0x09, 0x41, 0x70, 0x70, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x12, 0x1a, 0x0a, 0x16, 0x41, - 0x50, 0x50, 0x5f, 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, - 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x44, 0x49, 0x53, 0x41, 0x42, - 0x4c, 0x45, 0x44, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x49, 0x4e, 0x49, 0x54, 0x49, 0x41, 0x4c, - 0x49, 0x5a, 0x49, 0x4e, 0x47, 0x10, 0x02, 0x12, 0x0b, 0x0a, 0x07, 0x48, 0x45, 0x41, 0x4c, 0x54, - 0x48, 0x59, 0x10, 0x03, 0x12, 0x0d, 0x0a, 0x09, 0x55, 0x4e, 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, - 0x59, 0x10, 0x04, 0x32, 0xef, 0x07, 0x0a, 0x05, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x12, 0x4b, 0x0a, - 0x0b, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x12, 0x22, 0x2e, 0x63, - 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, - 0x74, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x18, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, - 0x32, 0x2e, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x12, 0x5a, 0x0a, 0x10, 0x47, 0x65, - 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x12, 0x27, + 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x65, 0x78, 0x69, 0x74, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x20, + 0x0a, 0x0c, 0x72, 0x61, 0x6e, 0x5f, 0x6f, 0x6e, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x72, 0x61, 0x6e, 0x4f, 0x6e, 0x53, 0x74, 0x61, 0x72, 0x74, + 0x12, 0x23, 0x0a, 0x0d, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x65, 0x64, 0x5f, 0x6c, 0x6f, 0x67, 0x69, + 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x65, 0x64, + 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x2a, 0x63, 0x0a, 0x09, 0x41, 0x70, 0x70, 0x48, 0x65, 0x61, 0x6c, + 0x74, 0x68, 0x12, 0x1a, 0x0a, 0x16, 0x41, 0x50, 0x50, 0x5f, 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, + 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0c, + 0x0a, 0x08, 0x44, 0x49, 0x53, 0x41, 0x42, 0x4c, 0x45, 0x44, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, + 0x49, 0x4e, 0x49, 0x54, 0x49, 0x41, 0x4c, 0x49, 0x5a, 0x49, 0x4e, 0x47, 0x10, 0x02, 0x12, 0x0b, + 0x0a, 0x07, 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, 0x59, 0x10, 0x03, 0x12, 0x0d, 0x0a, 0x09, 0x55, + 0x4e, 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, 0x59, 0x10, 0x04, 0x32, 0xef, 0x07, 0x0a, 0x05, 0x41, + 0x67, 0x65, 0x6e, 0x74, 0x12, 0x4b, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x6e, 0x69, 0x66, + 0x65, 0x73, 0x74, 0x12, 0x22, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, + 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, + 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, + 0x74, 0x12, 0x5a, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x42, + 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x12, 0x27, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, + 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, - 0x47, 0x65, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, - 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x12, 0x56, 0x0a, 0x0b, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x22, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, - 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, - 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x63, 0x6f, 0x64, 0x65, - 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x54, - 0x0a, 0x0f, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4c, 0x69, 0x66, 0x65, 0x63, 0x79, 0x63, 0x6c, - 0x65, 0x12, 0x26, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, - 0x76, 0x32, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4c, 0x69, 0x66, 0x65, 0x63, 0x79, 0x63, - 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x63, 0x6f, 0x64, 0x65, - 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x4c, 0x69, 0x66, 0x65, 0x63, - 0x79, 0x63, 0x6c, 0x65, 0x12, 0x72, 0x0a, 0x15, 0x42, 0x61, 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, - 0x61, 0x74, 0x65, 0x41, 0x70, 0x70, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x73, 0x12, 0x2b, 0x2e, - 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x42, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x12, 0x56, 0x0a, + 0x0b, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x22, 0x2e, 0x63, + 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x23, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, + 0x32, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x54, 0x0a, 0x0f, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4c, + 0x69, 0x66, 0x65, 0x63, 0x79, 0x63, 0x6c, 0x65, 0x12, 0x26, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, + 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x4c, 0x69, 0x66, 0x65, 0x63, 0x79, 0x63, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x19, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, + 0x32, 0x2e, 0x4c, 0x69, 0x66, 0x65, 0x63, 0x79, 0x63, 0x6c, 0x65, 0x12, 0x72, 0x0a, 0x15, 0x42, 0x61, 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x70, 0x70, 0x48, 0x65, 0x61, - 0x6c, 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x63, 0x6f, 0x64, + 0x6c, 0x74, 0x68, 0x73, 0x12, 0x2b, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, + 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x41, 0x70, 0x70, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x2c, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, + 0x76, 0x32, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x70, + 0x70, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x4e, 0x0a, 0x0d, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, + 0x12, 0x24, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, + 0x32, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, + 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x12, + 0x6e, 0x0a, 0x13, 0x42, 0x61, 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x2a, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, + 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, + 0x2e, 0x76, 0x32, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x62, 0x0a, 0x0f, 0x42, 0x61, 0x74, 0x63, 0x68, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4c, 0x6f, + 0x67, 0x73, 0x12, 0x26, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, + 0x2e, 0x76, 0x32, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4c, + 0x6f, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x42, 0x61, 0x74, 0x63, - 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x70, 0x70, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4e, 0x0a, 0x0d, 0x55, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x12, 0x24, 0x2e, 0x63, 0x6f, 0x64, 0x65, - 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x17, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, - 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x12, 0x6e, 0x0a, 0x13, 0x42, 0x61, 0x74, 0x63, - 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, - 0x2a, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, - 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x74, 0x61, - 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x63, 0x6f, - 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x42, 0x61, 0x74, - 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x62, 0x0a, 0x0f, 0x42, 0x61, 0x74, 0x63, - 0x68, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4c, 0x6f, 0x67, 0x73, 0x12, 0x26, 0x2e, 0x63, 0x6f, - 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x42, 0x61, 0x74, - 0x63, 0x68, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, - 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, - 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x77, 0x0a, 0x16, - 0x47, 0x65, 0x74, 0x41, 0x6e, 0x6e, 0x6f, 0x75, 0x6e, 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, - 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x73, 0x12, 0x2d, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, - 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x6e, 0x6e, 0x6f, 0x75, - 0x6e, 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x73, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, - 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x6e, 0x6e, 0x6f, 0x75, 0x6e, - 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7e, 0x0a, 0x0f, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x43, - 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x12, 0x34, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, - 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, - 0x61, 0x63, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x43, 0x6f, - 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x35, - 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, - 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x53, 0x63, - 0x72, 0x69, 0x70, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x27, 0x5a, 0x25, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, - 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2f, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2f, - 0x76, 0x32, 0x2f, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x68, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x77, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x41, 0x6e, 0x6e, 0x6f, 0x75, 0x6e, + 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x73, 0x12, 0x2d, 0x2e, + 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x47, + 0x65, 0x74, 0x41, 0x6e, 0x6e, 0x6f, 0x75, 0x6e, 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x61, + 0x6e, 0x6e, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x63, + 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, + 0x74, 0x41, 0x6e, 0x6e, 0x6f, 0x75, 0x6e, 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x61, 0x6e, + 0x6e, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7e, 0x0a, 0x0f, + 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x12, + 0x34, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, + 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x53, + 0x63, 0x72, 0x69, 0x70, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x35, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, + 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, + 0x41, 0x67, 0x65, 0x6e, 0x74, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x6c, + 0x65, 0x74, 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x27, 0x5a, 0x25, + 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x64, 0x65, 0x72, + 0x2f, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2f, 0x76, 0x32, 0x2f, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2f, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/agent/proto/agent.proto b/agent/proto/agent.proto index 21e6dd6b2b91a..0ee8f10dc05d4 100644 --- a/agent/proto/agent.proto +++ b/agent/proto/agent.proto @@ -277,6 +277,8 @@ message Timing { google.protobuf.Timestamp start = 2; google.protobuf.Timestamp end = 3; int32 exit_code = 4; + bool ran_on_start = 5; + bool blocked_login = 6; } service Agent { diff --git a/coderd/agentapi/scripts.go b/coderd/agentapi/scripts.go index 566894b44c0f6..885393b594b91 100644 --- a/coderd/agentapi/scripts.go +++ b/coderd/agentapi/scripts.go @@ -29,11 +29,13 @@ func (s *ScriptsAPI) ScriptCompleted(ctx context.Context, req *agentproto.Worksp } _, err = s.Database.InsertWorkspaceAgentScriptTimings(ctx, database.InsertWorkspaceAgentScriptTimingsParams{ - JobID: resource.JobID, - DisplayName: req.Timing.DisplayName, - StartedAt: req.Timing.Start.AsTime(), - EndedAt: req.Timing.End.AsTime(), - ExitCode: req.Timing.ExitCode, + JobID: resource.JobID, + DisplayName: req.Timing.DisplayName, + StartedAt: req.Timing.Start.AsTime(), + EndedAt: req.Timing.End.AsTime(), + ExitCode: req.Timing.ExitCode, + RanOnStart: req.Timing.RanOnStart, + BlockedLogin: req.Timing.BlockedLogin, }) if err != nil { return nil, xerrors.Errorf("insert workspace agent script timings into database: %w", err) diff --git a/coderd/database/dbmem/dbmem.go b/coderd/database/dbmem/dbmem.go index 1826d3db1676c..c5d78a12f6451 100644 --- a/coderd/database/dbmem/dbmem.go +++ b/coderd/database/dbmem/dbmem.go @@ -7838,11 +7838,13 @@ func (q *FakeQuerier) InsertWorkspaceAgentScriptTimings(_ context.Context, arg d //nolint:gosimple // Stop linter suggesting 'arg' should be of type database.WorkspaceAgentScriptTiming scriptTiming := database.WorkspaceAgentScriptTiming{ - StartedAt: arg.StartedAt, - EndedAt: arg.EndedAt, - ExitCode: arg.ExitCode, - DisplayName: arg.DisplayName, - JobID: arg.JobID, + StartedAt: arg.StartedAt, + EndedAt: arg.EndedAt, + ExitCode: arg.ExitCode, + DisplayName: arg.DisplayName, + JobID: arg.JobID, + RanOnStart: arg.RanOnStart, + BlockedLogin: arg.BlockedLogin, } q.workspaceAgentScriptTimings = append(q.workspaceAgentScriptTimings, scriptTiming) diff --git a/coderd/database/dump.sql b/coderd/database/dump.sql index f41635e6541ff..4eae33fd4d838 100644 --- a/coderd/database/dump.sql +++ b/coderd/database/dump.sql @@ -1360,7 +1360,9 @@ CREATE TABLE workspace_agent_script_timings ( display_name text NOT NULL, started_at timestamp with time zone NOT NULL, ended_at timestamp with time zone NOT NULL, - exit_code integer NOT NULL + exit_code integer NOT NULL, + ran_on_start boolean NOT NULL, + blocked_login boolean NOT NULL ); CREATE TABLE workspace_agent_scripts ( diff --git a/coderd/database/migrations/000255_workspace_agent_script_timings.up.sql b/coderd/database/migrations/000255_workspace_agent_script_timings.up.sql index 9eaa00c62d21f..31e83cdc1fe62 100644 --- a/coderd/database/migrations/000255_workspace_agent_script_timings.up.sql +++ b/coderd/database/migrations/000255_workspace_agent_script_timings.up.sql @@ -1,10 +1,12 @@ CREATE TABLE workspace_agent_script_timings ( - job_id uuid not null references provisioner_jobs (id) on delete cascade, - display_name text not null, - started_at timestamp with time zone not null, - ended_at timestamp with time zone not null, - exit_code int not null + job_id uuid not null references provisioner_jobs (id) on delete cascade, + display_name text not null, + started_at timestamp with time zone not null, + ended_at timestamp with time zone not null, + exit_code int not null, + ran_on_start bool not null, + blocked_login bool not null ); ALTER TABLE workspace_agent_scripts ADD COLUMN display_name text not null default ''; diff --git a/coderd/database/models.go b/coderd/database/models.go index 8ab682d102e65..10c39d6cc5817 100644 --- a/coderd/database/models.go +++ b/coderd/database/models.go @@ -2884,11 +2884,13 @@ type WorkspaceAgentScript struct { } type WorkspaceAgentScriptTiming struct { - JobID uuid.UUID `db:"job_id" json:"job_id"` - DisplayName string `db:"display_name" json:"display_name"` - StartedAt time.Time `db:"started_at" json:"started_at"` - EndedAt time.Time `db:"ended_at" json:"ended_at"` - ExitCode int32 `db:"exit_code" json:"exit_code"` + JobID uuid.UUID `db:"job_id" json:"job_id"` + DisplayName string `db:"display_name" json:"display_name"` + StartedAt time.Time `db:"started_at" json:"started_at"` + EndedAt time.Time `db:"ended_at" json:"ended_at"` + ExitCode int32 `db:"exit_code" json:"exit_code"` + RanOnStart bool `db:"ran_on_start" json:"ran_on_start"` + BlockedLogin bool `db:"blocked_login" json:"blocked_login"` } type WorkspaceAgentStat struct { diff --git a/coderd/database/queries.sql.go b/coderd/database/queries.sql.go index cc6337796f57c..7a91760f126b7 100644 --- a/coderd/database/queries.sql.go +++ b/coderd/database/queries.sql.go @@ -11809,18 +11809,22 @@ INSERT INTO display_name, started_at, ended_at, - exit_code + exit_code, + ran_on_start, + blocked_login ) VALUES - ($1, $2, $3, $4, $5) RETURNING job_id, display_name, started_at, ended_at, exit_code + ($1, $2, $3, $4, $5, $6, $7) RETURNING job_id, display_name, started_at, ended_at, exit_code, ran_on_start, blocked_login ` type InsertWorkspaceAgentScriptTimingsParams struct { - JobID uuid.UUID `db:"job_id" json:"job_id"` - DisplayName string `db:"display_name" json:"display_name"` - StartedAt time.Time `db:"started_at" json:"started_at"` - EndedAt time.Time `db:"ended_at" json:"ended_at"` - ExitCode int32 `db:"exit_code" json:"exit_code"` + JobID uuid.UUID `db:"job_id" json:"job_id"` + DisplayName string `db:"display_name" json:"display_name"` + StartedAt time.Time `db:"started_at" json:"started_at"` + EndedAt time.Time `db:"ended_at" json:"ended_at"` + ExitCode int32 `db:"exit_code" json:"exit_code"` + RanOnStart bool `db:"ran_on_start" json:"ran_on_start"` + BlockedLogin bool `db:"blocked_login" json:"blocked_login"` } func (q *sqlQuerier) InsertWorkspaceAgentScriptTimings(ctx context.Context, arg InsertWorkspaceAgentScriptTimingsParams) (WorkspaceAgentScriptTiming, error) { @@ -11830,6 +11834,8 @@ func (q *sqlQuerier) InsertWorkspaceAgentScriptTimings(ctx context.Context, arg arg.StartedAt, arg.EndedAt, arg.ExitCode, + arg.RanOnStart, + arg.BlockedLogin, ) var i WorkspaceAgentScriptTiming err := row.Scan( @@ -11838,6 +11844,8 @@ func (q *sqlQuerier) InsertWorkspaceAgentScriptTimings(ctx context.Context, arg &i.StartedAt, &i.EndedAt, &i.ExitCode, + &i.RanOnStart, + &i.BlockedLogin, ) return i, err } diff --git a/coderd/database/queries/workspaceagents.sql b/coderd/database/queries/workspaceagents.sql index 3466acb20b8db..d207ccb3c5aae 100644 --- a/coderd/database/queries/workspaceagents.sql +++ b/coderd/database/queries/workspaceagents.sql @@ -295,7 +295,9 @@ INSERT INTO display_name, started_at, ended_at, - exit_code + exit_code, + ran_on_start, + blocked_login ) VALUES - ($1, $2, $3, $4, $5) RETURNING *; + ($1, $2, $3, $4, $5, $6, $7) RETURNING *; From 0b0d1ef125d5130a0cb9166d598dcfe6637127c8 Mon Sep 17 00:00:00 2001 From: Danielle Maywood Date: Thu, 19 Sep 2024 09:39:56 +0000 Subject: [PATCH 24/56] fix: update testdata fixture --- .../fixtures/000255_workspace_agent_script_timings.up.sql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/coderd/database/migrations/testdata/fixtures/000255_workspace_agent_script_timings.up.sql b/coderd/database/migrations/testdata/fixtures/000255_workspace_agent_script_timings.up.sql index e8bafa2c8b88a..7cee75d7f4c0e 100644 --- a/coderd/database/migrations/testdata/fixtures/000255_workspace_agent_script_timings.up.sql +++ b/coderd/database/migrations/testdata/fixtures/000255_workspace_agent_script_timings.up.sql @@ -1,3 +1,3 @@ -INSERT INTO workspace_agent_script_timings (job_id, display_name, started_at, ended_at, exit_code) +INSERT INTO workspace_agent_script_timings (job_id, display_name, started_at, ended_at, exit_code, ran_on_start, blocked_login) VALUES - ('424a58cb-61d6-4627-9907-613c396c4a38', 'Startup Script', NOW() - INTERVAL '1 hour 55 minutes', NOW() - INTERVAL '1 hour 50 minutes', 0); + ('424a58cb-61d6-4627-9907-613c396c4a38', 'Startup Script', NOW() - INTERVAL '1 hour 55 minutes', NOW() - INTERVAL '1 hour 50 minutes', 0, true, false); From eb857c19646091ecfe4870284b70c799643982e1 Mon Sep 17 00:00:00 2001 From: Danielle Maywood Date: Thu, 19 Sep 2024 10:33:57 +0000 Subject: [PATCH 25/56] fix: refer to agent_id instead of job_id in timings --- coderd/agentapi/scripts.go | 14 ++------------ coderd/database/dbmem/dbmem.go | 2 +- coderd/database/dump.sql | 4 ++-- coderd/database/foreign_key_constraint.go | 2 +- .../000255_workspace_agent_script_timings.up.sql | 2 +- .../000255_workspace_agent_script_timings.up.sql | 4 ++-- coderd/database/models.go | 2 +- coderd/database/queries.sql.go | 10 +++++----- coderd/database/queries/workspaceagents.sql | 2 +- 9 files changed, 16 insertions(+), 26 deletions(-) diff --git a/coderd/agentapi/scripts.go b/coderd/agentapi/scripts.go index 885393b594b91..066b4b1538b68 100644 --- a/coderd/agentapi/scripts.go +++ b/coderd/agentapi/scripts.go @@ -18,18 +18,8 @@ type ScriptsAPI struct { func (s *ScriptsAPI) ScriptCompleted(ctx context.Context, req *agentproto.WorkspaceAgentScriptCompletedRequest) (*agentproto.WorkspaceAgentScriptCompletedResponse, error) { res := &agentproto.WorkspaceAgentScriptCompletedResponse{} - agent, err := s.Database.GetWorkspaceAgentByID(ctx, s.AgentID) - if err != nil { - return nil, xerrors.Errorf("get workspace agent by id in database: %w", err) - } - - resource, err := s.Database.GetWorkspaceResourceByID(ctx, agent.ResourceID) - if err != nil { - return nil, xerrors.Errorf("get workspace resource by id in database: %w", err) - } - - _, err = s.Database.InsertWorkspaceAgentScriptTimings(ctx, database.InsertWorkspaceAgentScriptTimingsParams{ - JobID: resource.JobID, + _, err := s.Database.InsertWorkspaceAgentScriptTimings(ctx, database.InsertWorkspaceAgentScriptTimingsParams{ + AgentID: s.AgentID, DisplayName: req.Timing.DisplayName, StartedAt: req.Timing.Start.AsTime(), EndedAt: req.Timing.End.AsTime(), diff --git a/coderd/database/dbmem/dbmem.go b/coderd/database/dbmem/dbmem.go index c5d78a12f6451..79cc5f7068f01 100644 --- a/coderd/database/dbmem/dbmem.go +++ b/coderd/database/dbmem/dbmem.go @@ -7838,11 +7838,11 @@ func (q *FakeQuerier) InsertWorkspaceAgentScriptTimings(_ context.Context, arg d //nolint:gosimple // Stop linter suggesting 'arg' should be of type database.WorkspaceAgentScriptTiming scriptTiming := database.WorkspaceAgentScriptTiming{ + AgentID: arg.AgentID, StartedAt: arg.StartedAt, EndedAt: arg.EndedAt, ExitCode: arg.ExitCode, DisplayName: arg.DisplayName, - JobID: arg.JobID, RanOnStart: arg.RanOnStart, BlockedLogin: arg.BlockedLogin, } diff --git a/coderd/database/dump.sql b/coderd/database/dump.sql index 4eae33fd4d838..2aebbbc0a2eb1 100644 --- a/coderd/database/dump.sql +++ b/coderd/database/dump.sql @@ -1356,7 +1356,7 @@ CREATE TABLE workspace_agent_port_share ( ); CREATE TABLE workspace_agent_script_timings ( - job_id uuid NOT NULL, + agent_id uuid NOT NULL, display_name text NOT NULL, started_at timestamp with time zone NOT NULL, ended_at timestamp with time zone NOT NULL, @@ -2236,7 +2236,7 @@ ALTER TABLE ONLY workspace_agent_port_share ADD CONSTRAINT workspace_agent_port_share_workspace_id_fkey FOREIGN KEY (workspace_id) REFERENCES workspaces(id) ON DELETE CASCADE; ALTER TABLE ONLY workspace_agent_script_timings - ADD CONSTRAINT workspace_agent_script_timings_job_id_fkey FOREIGN KEY (job_id) REFERENCES provisioner_jobs(id) ON DELETE CASCADE; + ADD CONSTRAINT workspace_agent_script_timings_agent_id_fkey FOREIGN KEY (agent_id) REFERENCES workspace_agents(id) ON DELETE CASCADE; ALTER TABLE ONLY workspace_agent_scripts ADD CONSTRAINT workspace_agent_scripts_workspace_agent_id_fkey FOREIGN KEY (workspace_agent_id) REFERENCES workspace_agents(id) ON DELETE CASCADE; diff --git a/coderd/database/foreign_key_constraint.go b/coderd/database/foreign_key_constraint.go index ad731575a1385..b92ba65b58b97 100644 --- a/coderd/database/foreign_key_constraint.go +++ b/coderd/database/foreign_key_constraint.go @@ -53,7 +53,7 @@ const ( ForeignKeyWorkspaceAgentLogSourcesWorkspaceAgentID ForeignKeyConstraint = "workspace_agent_log_sources_workspace_agent_id_fkey" // ALTER TABLE ONLY workspace_agent_log_sources ADD CONSTRAINT workspace_agent_log_sources_workspace_agent_id_fkey FOREIGN KEY (workspace_agent_id) REFERENCES workspace_agents(id) ON DELETE CASCADE; ForeignKeyWorkspaceAgentMetadataWorkspaceAgentID ForeignKeyConstraint = "workspace_agent_metadata_workspace_agent_id_fkey" // ALTER TABLE ONLY workspace_agent_metadata ADD CONSTRAINT workspace_agent_metadata_workspace_agent_id_fkey FOREIGN KEY (workspace_agent_id) REFERENCES workspace_agents(id) ON DELETE CASCADE; ForeignKeyWorkspaceAgentPortShareWorkspaceID ForeignKeyConstraint = "workspace_agent_port_share_workspace_id_fkey" // ALTER TABLE ONLY workspace_agent_port_share ADD CONSTRAINT workspace_agent_port_share_workspace_id_fkey FOREIGN KEY (workspace_id) REFERENCES workspaces(id) ON DELETE CASCADE; - ForeignKeyWorkspaceAgentScriptTimingsJobID ForeignKeyConstraint = "workspace_agent_script_timings_job_id_fkey" // ALTER TABLE ONLY workspace_agent_script_timings ADD CONSTRAINT workspace_agent_script_timings_job_id_fkey FOREIGN KEY (job_id) REFERENCES provisioner_jobs(id) ON DELETE CASCADE; + ForeignKeyWorkspaceAgentScriptTimingsAgentID ForeignKeyConstraint = "workspace_agent_script_timings_agent_id_fkey" // ALTER TABLE ONLY workspace_agent_script_timings ADD CONSTRAINT workspace_agent_script_timings_agent_id_fkey FOREIGN KEY (agent_id) REFERENCES workspace_agents(id) ON DELETE CASCADE; ForeignKeyWorkspaceAgentScriptsWorkspaceAgentID ForeignKeyConstraint = "workspace_agent_scripts_workspace_agent_id_fkey" // ALTER TABLE ONLY workspace_agent_scripts ADD CONSTRAINT workspace_agent_scripts_workspace_agent_id_fkey FOREIGN KEY (workspace_agent_id) REFERENCES workspace_agents(id) ON DELETE CASCADE; ForeignKeyWorkspaceAgentStartupLogsAgentID ForeignKeyConstraint = "workspace_agent_startup_logs_agent_id_fkey" // ALTER TABLE ONLY workspace_agent_logs ADD CONSTRAINT workspace_agent_startup_logs_agent_id_fkey FOREIGN KEY (agent_id) REFERENCES workspace_agents(id) ON DELETE CASCADE; ForeignKeyWorkspaceAgentsResourceID ForeignKeyConstraint = "workspace_agents_resource_id_fkey" // ALTER TABLE ONLY workspace_agents ADD CONSTRAINT workspace_agents_resource_id_fkey FOREIGN KEY (resource_id) REFERENCES workspace_resources(id) ON DELETE CASCADE; diff --git a/coderd/database/migrations/000255_workspace_agent_script_timings.up.sql b/coderd/database/migrations/000255_workspace_agent_script_timings.up.sql index 31e83cdc1fe62..669c08d83e586 100644 --- a/coderd/database/migrations/000255_workspace_agent_script_timings.up.sql +++ b/coderd/database/migrations/000255_workspace_agent_script_timings.up.sql @@ -1,6 +1,6 @@ CREATE TABLE workspace_agent_script_timings ( - job_id uuid not null references provisioner_jobs (id) on delete cascade, + agent_id uuid not null references workspace_agents (id) on delete cascade, display_name text not null, started_at timestamp with time zone not null, ended_at timestamp with time zone not null, diff --git a/coderd/database/migrations/testdata/fixtures/000255_workspace_agent_script_timings.up.sql b/coderd/database/migrations/testdata/fixtures/000255_workspace_agent_script_timings.up.sql index 7cee75d7f4c0e..f37513dcce84a 100644 --- a/coderd/database/migrations/testdata/fixtures/000255_workspace_agent_script_timings.up.sql +++ b/coderd/database/migrations/testdata/fixtures/000255_workspace_agent_script_timings.up.sql @@ -1,3 +1,3 @@ -INSERT INTO workspace_agent_script_timings (job_id, display_name, started_at, ended_at, exit_code, ran_on_start, blocked_login) +INSERT INTO workspace_agent_script_timings (agent_id, display_name, started_at, ended_at, exit_code, ran_on_start, blocked_login) VALUES - ('424a58cb-61d6-4627-9907-613c396c4a38', 'Startup Script', NOW() - INTERVAL '1 hour 55 minutes', NOW() - INTERVAL '1 hour 50 minutes', 0, true, false); + ('45e89705-e09d-4850-bcec-f9a937f5d78d', 'Startup Script', NOW() - INTERVAL '1 hour 55 minutes', NOW() - INTERVAL '1 hour 50 minutes', 0, true, false); diff --git a/coderd/database/models.go b/coderd/database/models.go index 10c39d6cc5817..abbce4807e21a 100644 --- a/coderd/database/models.go +++ b/coderd/database/models.go @@ -2884,7 +2884,7 @@ type WorkspaceAgentScript struct { } type WorkspaceAgentScriptTiming struct { - JobID uuid.UUID `db:"job_id" json:"job_id"` + AgentID uuid.UUID `db:"agent_id" json:"agent_id"` DisplayName string `db:"display_name" json:"display_name"` StartedAt time.Time `db:"started_at" json:"started_at"` EndedAt time.Time `db:"ended_at" json:"ended_at"` diff --git a/coderd/database/queries.sql.go b/coderd/database/queries.sql.go index 7a91760f126b7..908bb31fb6d97 100644 --- a/coderd/database/queries.sql.go +++ b/coderd/database/queries.sql.go @@ -11805,7 +11805,7 @@ func (q *sqlQuerier) InsertWorkspaceAgentMetadata(ctx context.Context, arg Inser const insertWorkspaceAgentScriptTimings = `-- name: InsertWorkspaceAgentScriptTimings :one INSERT INTO workspace_agent_script_timings ( - job_id, + agent_id, display_name, started_at, ended_at, @@ -11814,11 +11814,11 @@ INSERT INTO blocked_login ) VALUES - ($1, $2, $3, $4, $5, $6, $7) RETURNING job_id, display_name, started_at, ended_at, exit_code, ran_on_start, blocked_login + ($1, $2, $3, $4, $5, $6, $7) RETURNING agent_id, display_name, started_at, ended_at, exit_code, ran_on_start, blocked_login ` type InsertWorkspaceAgentScriptTimingsParams struct { - JobID uuid.UUID `db:"job_id" json:"job_id"` + AgentID uuid.UUID `db:"agent_id" json:"agent_id"` DisplayName string `db:"display_name" json:"display_name"` StartedAt time.Time `db:"started_at" json:"started_at"` EndedAt time.Time `db:"ended_at" json:"ended_at"` @@ -11829,7 +11829,7 @@ type InsertWorkspaceAgentScriptTimingsParams struct { func (q *sqlQuerier) InsertWorkspaceAgentScriptTimings(ctx context.Context, arg InsertWorkspaceAgentScriptTimingsParams) (WorkspaceAgentScriptTiming, error) { row := q.db.QueryRowContext(ctx, insertWorkspaceAgentScriptTimings, - arg.JobID, + arg.AgentID, arg.DisplayName, arg.StartedAt, arg.EndedAt, @@ -11839,7 +11839,7 @@ func (q *sqlQuerier) InsertWorkspaceAgentScriptTimings(ctx context.Context, arg ) var i WorkspaceAgentScriptTiming err := row.Scan( - &i.JobID, + &i.AgentID, &i.DisplayName, &i.StartedAt, &i.EndedAt, diff --git a/coderd/database/queries/workspaceagents.sql b/coderd/database/queries/workspaceagents.sql index d207ccb3c5aae..e703239668c7e 100644 --- a/coderd/database/queries/workspaceagents.sql +++ b/coderd/database/queries/workspaceagents.sql @@ -291,7 +291,7 @@ WHERE -- name: InsertWorkspaceAgentScriptTimings :one INSERT INTO workspace_agent_script_timings ( - job_id, + agent_id, display_name, started_at, ended_at, From 586d88f0b6a573e4a53c5b8ec0d6c846011f1612 Mon Sep 17 00:00:00 2001 From: Danielle Maywood Date: Thu, 19 Sep 2024 10:39:05 +0000 Subject: [PATCH 26/56] fix: JobID -> AgentID in dbauthz_test --- coderd/database/dbauthz/dbauthz_test.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/coderd/database/dbauthz/dbauthz_test.go b/coderd/database/dbauthz/dbauthz_test.go index 87b592dacebd8..aed1ab5e8d0b2 100644 --- a/coderd/database/dbauthz/dbauthz_test.go +++ b/coderd/database/dbauthz/dbauthz_test.go @@ -2633,9 +2633,8 @@ func (s *MethodTestSuite) TestSystemFunctions() { check.Args(database.InsertWorkspaceAppStatsParams{}).Asserts(rbac.ResourceSystem, policy.ActionCreate) })) s.Run("InsertWorkspaceAgentScriptTimings", s.Subtest(func(db database.Store, check *expects) { - j := dbgen.ProvisionerJob(s.T(), db, nil, database.ProvisionerJob{}) check.Args(database.InsertWorkspaceAgentScriptTimingsParams{ - JobID: j.ID, + AgentID: uuid.New(), }).Asserts( /* rbac.ResourceSystem, policy.ActionCreate */ ) })) s.Run("InsertWorkspaceAgentScripts", s.Subtest(func(db database.Store, check *expects) { From b6289bbc7e89d728420cadae4d5d5d8cc07daf3d Mon Sep 17 00:00:00 2001 From: Danielle Maywood Date: Thu, 19 Sep 2024 13:01:19 +0000 Subject: [PATCH 27/56] fix: add 'id' to scripts, make timing refer to script id --- agent/agentscripts/agentscripts.go | 5 + agent/proto/agent.pb.go | 169 ++++++++++-------- agent/proto/agent.proto | 2 + coderd/agentapi/manifest.go | 1 + coderd/agentapi/scripts.go | 9 +- coderd/apidoc/docs.go | 4 + coderd/apidoc/swagger.json | 4 + coderd/database/dbauthz/dbauthz_test.go | 2 +- coderd/database/dbmem/dbmem.go | 2 +- coderd/database/dump.sql | 8 +- coderd/database/foreign_key_constraint.go | 2 +- ...55_workspace_agent_script_timings.down.sql | 1 + ...0255_workspace_agent_script_timings.up.sql | 4 +- coderd/database/models.go | 3 +- coderd/database/queries.sql.go | 23 ++- coderd/database/queries/workspaceagents.sql | 2 +- coderd/database/queries/workspacescripts.sql | 5 +- coderd/database/unique_constraint.go | 1 + .../provisionerdserver/provisionerdserver.go | 3 + coderd/workspaceagents.go | 1 + codersdk/agentsdk/convert.go | 10 +- codersdk/workspaceagents.go | 1 + docs/reference/api/agents.md | 1 + docs/reference/api/builds.md | 8 + docs/reference/api/schemas.md | 7 + docs/reference/api/templates.md | 4 + docs/reference/api/workspaces.md | 6 + site/src/api/typesGenerated.ts | 1 + site/src/testHelpers/entities.ts | 1 + 29 files changed, 192 insertions(+), 98 deletions(-) diff --git a/agent/agentscripts/agentscripts.go b/agent/agentscripts/agentscripts.go index 8bd1b11bd275d..6cd4ef1110b5b 100644 --- a/agent/agentscripts/agentscripts.go +++ b/agent/agentscripts/agentscripts.go @@ -323,6 +323,7 @@ func (r *Runner) run(ctx context.Context, script codersdk.WorkspaceAgentScript) _, err = r.scriptCompleted(ctx, &proto.WorkspaceAgentScriptCompletedRequest{ Timing: &proto.Timing{ + ScriptId: script.ID[:], DisplayName: script.DisplayName, Start: timestamppb.New(start), End: timestamppb.New(end), @@ -331,6 +332,10 @@ func (r *Runner) run(ctx context.Context, script codersdk.WorkspaceAgentScript) BlockedLogin: script.StartBlocksLogin, }, }) + + if err != nil { + logger.Error(ctx, fmt.Sprintf("reporting script completed: %s", err.Error())) + } }() err = cmd.Start() diff --git a/agent/proto/agent.pb.go b/agent/proto/agent.pb.go index 97c03588288a9..898c2b2687782 100644 --- a/agent/proto/agent.pb.go +++ b/agent/proto/agent.pb.go @@ -571,6 +571,7 @@ type WorkspaceAgentScript struct { StartBlocksLogin bool `protobuf:"varint,7,opt,name=start_blocks_login,json=startBlocksLogin,proto3" json:"start_blocks_login,omitempty"` Timeout *durationpb.Duration `protobuf:"bytes,8,opt,name=timeout,proto3" json:"timeout,omitempty"` DisplayName string `protobuf:"bytes,9,opt,name=display_name,json=displayName,proto3" json:"display_name,omitempty"` + Id []byte `protobuf:"bytes,10,opt,name=id,proto3" json:"id,omitempty"` } func (x *WorkspaceAgentScript) Reset() { @@ -668,6 +669,13 @@ func (x *WorkspaceAgentScript) GetDisplayName() string { return "" } +func (x *WorkspaceAgentScript) GetId() []byte { + if x != nil { + return x.Id + } + return nil +} + type WorkspaceAgentMetadata struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -2119,6 +2127,7 @@ type Timing struct { ExitCode int32 `protobuf:"varint,4,opt,name=exit_code,json=exitCode,proto3" json:"exit_code,omitempty"` RanOnStart bool `protobuf:"varint,5,opt,name=ran_on_start,json=ranOnStart,proto3" json:"ran_on_start,omitempty"` BlockedLogin bool `protobuf:"varint,6,opt,name=blocked_login,json=blockedLogin,proto3" json:"blocked_login,omitempty"` + ScriptId []byte `protobuf:"bytes,7,opt,name=script_id,json=scriptId,proto3" json:"script_id,omitempty"` } func (x *Timing) Reset() { @@ -2195,6 +2204,13 @@ func (x *Timing) GetBlockedLogin() bool { return false } +func (x *Timing) GetScriptId() []byte { + if x != nil { + return x.ScriptId + } + return nil +} + type WorkspaceApp_Healthcheck struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -2649,7 +2665,7 @@ var file_agent_proto_agent_proto_rawDesc = []byte{ 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x44, 0x49, 0x53, 0x41, 0x42, 0x4c, 0x45, 0x44, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x49, 0x4e, 0x49, 0x54, 0x49, 0x41, 0x4c, 0x49, 0x5a, 0x49, 0x4e, 0x47, 0x10, 0x02, 0x12, 0x0b, 0x0a, 0x07, 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, 0x59, 0x10, 0x03, 0x12, - 0x0d, 0x0a, 0x09, 0x55, 0x4e, 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, 0x59, 0x10, 0x04, 0x22, 0xc9, + 0x0d, 0x0a, 0x09, 0x55, 0x4e, 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, 0x59, 0x10, 0x04, 0x22, 0xd9, 0x02, 0x0a, 0x14, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x12, 0x22, 0x0a, 0x0d, 0x6c, 0x6f, 0x67, 0x5f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, @@ -2670,7 +2686,8 @@ var file_agent_proto_agent_proto_rawDesc = []byte{ 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, - 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x86, 0x04, 0x0a, 0x16, 0x57, + 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, + 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, 0x69, 0x64, 0x22, 0x86, 0x04, 0x0a, 0x16, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x45, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, @@ -2958,7 +2975,7 @@ var file_agent_proto_agent_proto_rawDesc = []byte{ 0x6e, 0x67, 0x52, 0x06, 0x74, 0x69, 0x6d, 0x69, 0x6e, 0x67, 0x22, 0x27, 0x0a, 0x25, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0xef, 0x01, 0x0a, 0x06, 0x54, 0x69, 0x6d, 0x69, 0x6e, 0x67, 0x12, 0x21, + 0x6e, 0x73, 0x65, 0x22, 0x8c, 0x02, 0x0a, 0x06, 0x54, 0x69, 0x6d, 0x69, 0x6e, 0x67, 0x12, 0x21, 0x0a, 0x0c, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x30, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, @@ -2973,79 +2990,81 @@ var file_agent_proto_agent_proto_rawDesc = []byte{ 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x72, 0x61, 0x6e, 0x4f, 0x6e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x12, 0x23, 0x0a, 0x0d, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x65, 0x64, 0x5f, 0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x65, 0x64, - 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x2a, 0x63, 0x0a, 0x09, 0x41, 0x70, 0x70, 0x48, 0x65, 0x61, 0x6c, - 0x74, 0x68, 0x12, 0x1a, 0x0a, 0x16, 0x41, 0x50, 0x50, 0x5f, 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, - 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0c, - 0x0a, 0x08, 0x44, 0x49, 0x53, 0x41, 0x42, 0x4c, 0x45, 0x44, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, - 0x49, 0x4e, 0x49, 0x54, 0x49, 0x41, 0x4c, 0x49, 0x5a, 0x49, 0x4e, 0x47, 0x10, 0x02, 0x12, 0x0b, - 0x0a, 0x07, 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, 0x59, 0x10, 0x03, 0x12, 0x0d, 0x0a, 0x09, 0x55, - 0x4e, 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, 0x59, 0x10, 0x04, 0x32, 0xef, 0x07, 0x0a, 0x05, 0x41, - 0x67, 0x65, 0x6e, 0x74, 0x12, 0x4b, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x6e, 0x69, 0x66, - 0x65, 0x73, 0x74, 0x12, 0x22, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, - 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, - 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, - 0x74, 0x12, 0x5a, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x42, - 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x12, 0x27, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, - 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, - 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, - 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x12, 0x56, 0x0a, - 0x0b, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x22, 0x2e, 0x63, - 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x23, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, - 0x32, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x54, 0x0a, 0x0f, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4c, - 0x69, 0x66, 0x65, 0x63, 0x79, 0x63, 0x6c, 0x65, 0x12, 0x26, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, - 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x4c, 0x69, 0x66, 0x65, 0x63, 0x79, 0x63, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x19, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, - 0x32, 0x2e, 0x4c, 0x69, 0x66, 0x65, 0x63, 0x79, 0x63, 0x6c, 0x65, 0x12, 0x72, 0x0a, 0x15, 0x42, - 0x61, 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x70, 0x70, 0x48, 0x65, 0x61, - 0x6c, 0x74, 0x68, 0x73, 0x12, 0x2b, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, - 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x41, 0x70, 0x70, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x2c, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, + 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x5f, + 0x69, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x49, 0x64, 0x2a, 0x63, 0x0a, 0x09, 0x41, 0x70, 0x70, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x12, + 0x1a, 0x0a, 0x16, 0x41, 0x50, 0x50, 0x5f, 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, 0x5f, 0x55, 0x4e, + 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x44, + 0x49, 0x53, 0x41, 0x42, 0x4c, 0x45, 0x44, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x49, 0x4e, 0x49, + 0x54, 0x49, 0x41, 0x4c, 0x49, 0x5a, 0x49, 0x4e, 0x47, 0x10, 0x02, 0x12, 0x0b, 0x0a, 0x07, 0x48, + 0x45, 0x41, 0x4c, 0x54, 0x48, 0x59, 0x10, 0x03, 0x12, 0x0d, 0x0a, 0x09, 0x55, 0x4e, 0x48, 0x45, + 0x41, 0x4c, 0x54, 0x48, 0x59, 0x10, 0x04, 0x32, 0xef, 0x07, 0x0a, 0x05, 0x41, 0x67, 0x65, 0x6e, + 0x74, 0x12, 0x4b, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, + 0x12, 0x22, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, + 0x32, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, + 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x12, 0x5a, + 0x0a, 0x10, 0x47, 0x65, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x42, 0x61, 0x6e, 0x6e, + 0x65, 0x72, 0x12, 0x27, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, + 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x42, 0x61, + 0x6e, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x63, 0x6f, + 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x12, 0x56, 0x0a, 0x0b, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x22, 0x2e, 0x63, 0x6f, 0x64, 0x65, + 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, + 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x54, 0x0a, 0x0f, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4c, 0x69, 0x66, 0x65, + 0x63, 0x79, 0x63, 0x6c, 0x65, 0x12, 0x26, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, + 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4c, 0x69, 0x66, + 0x65, 0x63, 0x79, 0x63, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, + 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x4c, + 0x69, 0x66, 0x65, 0x63, 0x79, 0x63, 0x6c, 0x65, 0x12, 0x72, 0x0a, 0x15, 0x42, 0x61, 0x74, 0x63, + 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x70, 0x70, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, + 0x73, 0x12, 0x2b, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x70, - 0x70, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x4e, 0x0a, 0x0d, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, - 0x12, 0x24, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, - 0x32, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, - 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x12, - 0x6e, 0x0a, 0x13, 0x42, 0x61, 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x65, - 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x2a, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, - 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, - 0x61, 0x74, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, - 0x2e, 0x76, 0x32, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, - 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x62, 0x0a, 0x0f, 0x42, 0x61, 0x74, 0x63, 0x68, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4c, 0x6f, - 0x67, 0x73, 0x12, 0x26, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, - 0x2e, 0x76, 0x32, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4c, - 0x6f, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x63, 0x6f, 0x64, - 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x42, 0x61, 0x74, 0x63, - 0x68, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x77, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x41, 0x6e, 0x6e, 0x6f, 0x75, 0x6e, - 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x73, 0x12, 0x2d, 0x2e, - 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x47, - 0x65, 0x74, 0x41, 0x6e, 0x6e, 0x6f, 0x75, 0x6e, 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x61, - 0x6e, 0x6e, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x63, - 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, - 0x74, 0x41, 0x6e, 0x6e, 0x6f, 0x75, 0x6e, 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x61, 0x6e, - 0x6e, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7e, 0x0a, 0x0f, - 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x12, - 0x34, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, - 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x53, - 0x63, 0x72, 0x69, 0x70, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x35, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, - 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, - 0x41, 0x67, 0x65, 0x6e, 0x74, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x6c, - 0x65, 0x74, 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x27, 0x5a, 0x25, - 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x64, 0x65, 0x72, - 0x2f, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2f, 0x76, 0x32, 0x2f, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2f, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x70, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, + 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, + 0x42, 0x61, 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x70, 0x70, 0x48, 0x65, + 0x61, 0x6c, 0x74, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4e, 0x0a, 0x0d, + 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x12, 0x24, 0x2e, + 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, + 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x12, 0x6e, 0x0a, 0x13, + 0x42, 0x61, 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x12, 0x2a, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, + 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x2b, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, + 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x62, 0x0a, 0x0f, + 0x42, 0x61, 0x74, 0x63, 0x68, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4c, 0x6f, 0x67, 0x73, 0x12, + 0x26, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, + 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4c, 0x6f, 0x67, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, + 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x77, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x41, 0x6e, 0x6e, 0x6f, 0x75, 0x6e, 0x63, 0x65, 0x6d, + 0x65, 0x6e, 0x74, 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x73, 0x12, 0x2d, 0x2e, 0x63, 0x6f, 0x64, + 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x41, + 0x6e, 0x6e, 0x6f, 0x75, 0x6e, 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x61, 0x6e, 0x6e, 0x65, + 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x63, 0x6f, 0x64, 0x65, + 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x6e, + 0x6e, 0x6f, 0x75, 0x6e, 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7e, 0x0a, 0x0f, 0x53, 0x63, 0x72, + 0x69, 0x70, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x12, 0x34, 0x2e, 0x63, + 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x57, 0x6f, + 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x53, 0x63, 0x72, 0x69, + 0x70, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x35, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, + 0x2e, 0x76, 0x32, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x41, 0x67, 0x65, + 0x6e, 0x74, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, + 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x27, 0x5a, 0x25, 0x67, 0x69, 0x74, + 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2f, 0x63, 0x6f, + 0x64, 0x65, 0x72, 0x2f, 0x76, 0x32, 0x2f, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2f, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/agent/proto/agent.proto b/agent/proto/agent.proto index 0ee8f10dc05d4..c26df0eaa6f4e 100644 --- a/agent/proto/agent.proto +++ b/agent/proto/agent.proto @@ -54,6 +54,7 @@ message WorkspaceAgentScript { bool start_blocks_login = 7; google.protobuf.Duration timeout = 8; string display_name = 9; + bytes id = 10; } message WorkspaceAgentMetadata { @@ -279,6 +280,7 @@ message Timing { int32 exit_code = 4; bool ran_on_start = 5; bool blocked_login = 6; + bytes script_id = 7; } service Agent { diff --git a/coderd/agentapi/manifest.go b/coderd/agentapi/manifest.go index a78a07ccac8ed..b3ad5edc484f8 100644 --- a/coderd/agentapi/manifest.go +++ b/coderd/agentapi/manifest.go @@ -178,6 +178,7 @@ func dbAgentScriptsToProto(scripts []database.WorkspaceAgentScript) []*agentprot func dbAgentScriptToProto(script database.WorkspaceAgentScript) *agentproto.WorkspaceAgentScript { return &agentproto.WorkspaceAgentScript{ + Id: script.ID[:], DisplayName: script.DisplayName, LogSourceId: script.LogSourceID[:], LogPath: script.LogPath, diff --git a/coderd/agentapi/scripts.go b/coderd/agentapi/scripts.go index 066b4b1538b68..6f866dbb7a32b 100644 --- a/coderd/agentapi/scripts.go +++ b/coderd/agentapi/scripts.go @@ -18,8 +18,13 @@ type ScriptsAPI struct { func (s *ScriptsAPI) ScriptCompleted(ctx context.Context, req *agentproto.WorkspaceAgentScriptCompletedRequest) (*agentproto.WorkspaceAgentScriptCompletedResponse, error) { res := &agentproto.WorkspaceAgentScriptCompletedResponse{} - _, err := s.Database.InsertWorkspaceAgentScriptTimings(ctx, database.InsertWorkspaceAgentScriptTimingsParams{ - AgentID: s.AgentID, + scriptID, err := uuid.FromBytes(req.Timing.ScriptId) + if err != nil { + return nil, xerrors.Errorf("script id from bytes: %w", err) + } + + _, err = s.Database.InsertWorkspaceAgentScriptTimings(ctx, database.InsertWorkspaceAgentScriptTimingsParams{ + ScriptID: scriptID, DisplayName: req.Timing.DisplayName, StartedAt: req.Timing.Start.AsTime(), EndedAt: req.Timing.End.AsTime(), diff --git a/coderd/apidoc/docs.go b/coderd/apidoc/docs.go index 37afc0ec80653..ebf9bf8ae075d 100644 --- a/coderd/apidoc/docs.go +++ b/coderd/apidoc/docs.go @@ -14263,6 +14263,10 @@ const docTemplate = `{ "display_name": { "type": "string" }, + "id": { + "type": "string", + "format": "uuid" + }, "log_path": { "type": "string" }, diff --git a/coderd/apidoc/swagger.json b/coderd/apidoc/swagger.json index 9c511d9f07068..3a162713ed489 100644 --- a/coderd/apidoc/swagger.json +++ b/coderd/apidoc/swagger.json @@ -12989,6 +12989,10 @@ "display_name": { "type": "string" }, + "id": { + "type": "string", + "format": "uuid" + }, "log_path": { "type": "string" }, diff --git a/coderd/database/dbauthz/dbauthz_test.go b/coderd/database/dbauthz/dbauthz_test.go index aed1ab5e8d0b2..023298b4c5482 100644 --- a/coderd/database/dbauthz/dbauthz_test.go +++ b/coderd/database/dbauthz/dbauthz_test.go @@ -2634,7 +2634,7 @@ func (s *MethodTestSuite) TestSystemFunctions() { })) s.Run("InsertWorkspaceAgentScriptTimings", s.Subtest(func(db database.Store, check *expects) { check.Args(database.InsertWorkspaceAgentScriptTimingsParams{ - AgentID: uuid.New(), + ScriptID: uuid.New(), }).Asserts( /* rbac.ResourceSystem, policy.ActionCreate */ ) })) s.Run("InsertWorkspaceAgentScripts", s.Subtest(func(db database.Store, check *expects) { diff --git a/coderd/database/dbmem/dbmem.go b/coderd/database/dbmem/dbmem.go index 79cc5f7068f01..8a8bfeb9946e0 100644 --- a/coderd/database/dbmem/dbmem.go +++ b/coderd/database/dbmem/dbmem.go @@ -7838,7 +7838,7 @@ func (q *FakeQuerier) InsertWorkspaceAgentScriptTimings(_ context.Context, arg d //nolint:gosimple // Stop linter suggesting 'arg' should be of type database.WorkspaceAgentScriptTiming scriptTiming := database.WorkspaceAgentScriptTiming{ - AgentID: arg.AgentID, + ScriptID: arg.ScriptID, StartedAt: arg.StartedAt, EndedAt: arg.EndedAt, ExitCode: arg.ExitCode, diff --git a/coderd/database/dump.sql b/coderd/database/dump.sql index 2aebbbc0a2eb1..00664becf20d4 100644 --- a/coderd/database/dump.sql +++ b/coderd/database/dump.sql @@ -1356,7 +1356,7 @@ CREATE TABLE workspace_agent_port_share ( ); CREATE TABLE workspace_agent_script_timings ( - agent_id uuid NOT NULL, + script_id uuid NOT NULL, display_name text NOT NULL, started_at timestamp with time zone NOT NULL, ended_at timestamp with time zone NOT NULL, @@ -1376,6 +1376,7 @@ CREATE TABLE workspace_agent_scripts ( run_on_start boolean NOT NULL, run_on_stop boolean NOT NULL, timeout_seconds integer NOT NULL, + id uuid DEFAULT gen_random_uuid() NOT NULL, display_name text DEFAULT ''::text NOT NULL ); @@ -1868,6 +1869,9 @@ ALTER TABLE ONLY workspace_agent_metadata ALTER TABLE ONLY workspace_agent_port_share ADD CONSTRAINT workspace_agent_port_share_pkey PRIMARY KEY (workspace_id, agent_name, port); +ALTER TABLE ONLY workspace_agent_scripts + ADD CONSTRAINT workspace_agent_scripts_id_key UNIQUE (id); + ALTER TABLE ONLY workspace_agent_logs ADD CONSTRAINT workspace_agent_startup_logs_pkey PRIMARY KEY (id); @@ -2236,7 +2240,7 @@ ALTER TABLE ONLY workspace_agent_port_share ADD CONSTRAINT workspace_agent_port_share_workspace_id_fkey FOREIGN KEY (workspace_id) REFERENCES workspaces(id) ON DELETE CASCADE; ALTER TABLE ONLY workspace_agent_script_timings - ADD CONSTRAINT workspace_agent_script_timings_agent_id_fkey FOREIGN KEY (agent_id) REFERENCES workspace_agents(id) ON DELETE CASCADE; + ADD CONSTRAINT workspace_agent_script_timings_script_id_fkey FOREIGN KEY (script_id) REFERENCES workspace_agent_scripts(id) ON DELETE CASCADE; ALTER TABLE ONLY workspace_agent_scripts ADD CONSTRAINT workspace_agent_scripts_workspace_agent_id_fkey FOREIGN KEY (workspace_agent_id) REFERENCES workspace_agents(id) ON DELETE CASCADE; diff --git a/coderd/database/foreign_key_constraint.go b/coderd/database/foreign_key_constraint.go index b92ba65b58b97..f142e729b2f38 100644 --- a/coderd/database/foreign_key_constraint.go +++ b/coderd/database/foreign_key_constraint.go @@ -53,7 +53,7 @@ const ( ForeignKeyWorkspaceAgentLogSourcesWorkspaceAgentID ForeignKeyConstraint = "workspace_agent_log_sources_workspace_agent_id_fkey" // ALTER TABLE ONLY workspace_agent_log_sources ADD CONSTRAINT workspace_agent_log_sources_workspace_agent_id_fkey FOREIGN KEY (workspace_agent_id) REFERENCES workspace_agents(id) ON DELETE CASCADE; ForeignKeyWorkspaceAgentMetadataWorkspaceAgentID ForeignKeyConstraint = "workspace_agent_metadata_workspace_agent_id_fkey" // ALTER TABLE ONLY workspace_agent_metadata ADD CONSTRAINT workspace_agent_metadata_workspace_agent_id_fkey FOREIGN KEY (workspace_agent_id) REFERENCES workspace_agents(id) ON DELETE CASCADE; ForeignKeyWorkspaceAgentPortShareWorkspaceID ForeignKeyConstraint = "workspace_agent_port_share_workspace_id_fkey" // ALTER TABLE ONLY workspace_agent_port_share ADD CONSTRAINT workspace_agent_port_share_workspace_id_fkey FOREIGN KEY (workspace_id) REFERENCES workspaces(id) ON DELETE CASCADE; - ForeignKeyWorkspaceAgentScriptTimingsAgentID ForeignKeyConstraint = "workspace_agent_script_timings_agent_id_fkey" // ALTER TABLE ONLY workspace_agent_script_timings ADD CONSTRAINT workspace_agent_script_timings_agent_id_fkey FOREIGN KEY (agent_id) REFERENCES workspace_agents(id) ON DELETE CASCADE; + ForeignKeyWorkspaceAgentScriptTimingsScriptID ForeignKeyConstraint = "workspace_agent_script_timings_script_id_fkey" // ALTER TABLE ONLY workspace_agent_script_timings ADD CONSTRAINT workspace_agent_script_timings_script_id_fkey FOREIGN KEY (script_id) REFERENCES workspace_agent_scripts(id) ON DELETE CASCADE; ForeignKeyWorkspaceAgentScriptsWorkspaceAgentID ForeignKeyConstraint = "workspace_agent_scripts_workspace_agent_id_fkey" // ALTER TABLE ONLY workspace_agent_scripts ADD CONSTRAINT workspace_agent_scripts_workspace_agent_id_fkey FOREIGN KEY (workspace_agent_id) REFERENCES workspace_agents(id) ON DELETE CASCADE; ForeignKeyWorkspaceAgentStartupLogsAgentID ForeignKeyConstraint = "workspace_agent_startup_logs_agent_id_fkey" // ALTER TABLE ONLY workspace_agent_logs ADD CONSTRAINT workspace_agent_startup_logs_agent_id_fkey FOREIGN KEY (agent_id) REFERENCES workspace_agents(id) ON DELETE CASCADE; ForeignKeyWorkspaceAgentsResourceID ForeignKeyConstraint = "workspace_agents_resource_id_fkey" // ALTER TABLE ONLY workspace_agents ADD CONSTRAINT workspace_agents_resource_id_fkey FOREIGN KEY (resource_id) REFERENCES workspace_resources(id) ON DELETE CASCADE; diff --git a/coderd/database/migrations/000255_workspace_agent_script_timings.down.sql b/coderd/database/migrations/000255_workspace_agent_script_timings.down.sql index 219871e3e1e1d..97f0f400a2616 100644 --- a/coderd/database/migrations/000255_workspace_agent_script_timings.down.sql +++ b/coderd/database/migrations/000255_workspace_agent_script_timings.down.sql @@ -1,3 +1,4 @@ DROP TABLE IF EXISTS workspace_agent_script_timings; ALTER TABLE workspace_agent_scripts DROP COLUMN display_name; +ALTER TABLE workspace_agent_scripts DROP COLUMN id; diff --git a/coderd/database/migrations/000255_workspace_agent_script_timings.up.sql b/coderd/database/migrations/000255_workspace_agent_script_timings.up.sql index 669c08d83e586..0938f2a8b8e70 100644 --- a/coderd/database/migrations/000255_workspace_agent_script_timings.up.sql +++ b/coderd/database/migrations/000255_workspace_agent_script_timings.up.sql @@ -1,6 +1,8 @@ +ALTER TABLE workspace_agent_scripts ADD COLUMN id uuid unique not null default gen_random_uuid(); + CREATE TABLE workspace_agent_script_timings ( - agent_id uuid not null references workspace_agents (id) on delete cascade, + script_id uuid not null references workspace_agent_scripts (id) on delete cascade, display_name text not null, started_at timestamp with time zone not null, ended_at timestamp with time zone not null, diff --git a/coderd/database/models.go b/coderd/database/models.go index abbce4807e21a..7744fc73ae2c9 100644 --- a/coderd/database/models.go +++ b/coderd/database/models.go @@ -2880,11 +2880,12 @@ type WorkspaceAgentScript struct { RunOnStart bool `db:"run_on_start" json:"run_on_start"` RunOnStop bool `db:"run_on_stop" json:"run_on_stop"` TimeoutSeconds int32 `db:"timeout_seconds" json:"timeout_seconds"` + ID uuid.UUID `db:"id" json:"id"` DisplayName string `db:"display_name" json:"display_name"` } type WorkspaceAgentScriptTiming struct { - AgentID uuid.UUID `db:"agent_id" json:"agent_id"` + ScriptID uuid.UUID `db:"script_id" json:"script_id"` DisplayName string `db:"display_name" json:"display_name"` StartedAt time.Time `db:"started_at" json:"started_at"` EndedAt time.Time `db:"ended_at" json:"ended_at"` diff --git a/coderd/database/queries.sql.go b/coderd/database/queries.sql.go index 908bb31fb6d97..4a7309bf0f24f 100644 --- a/coderd/database/queries.sql.go +++ b/coderd/database/queries.sql.go @@ -11805,7 +11805,7 @@ func (q *sqlQuerier) InsertWorkspaceAgentMetadata(ctx context.Context, arg Inser const insertWorkspaceAgentScriptTimings = `-- name: InsertWorkspaceAgentScriptTimings :one INSERT INTO workspace_agent_script_timings ( - agent_id, + script_id, display_name, started_at, ended_at, @@ -11814,11 +11814,11 @@ INSERT INTO blocked_login ) VALUES - ($1, $2, $3, $4, $5, $6, $7) RETURNING agent_id, display_name, started_at, ended_at, exit_code, ran_on_start, blocked_login + ($1, $2, $3, $4, $5, $6, $7) RETURNING script_id, display_name, started_at, ended_at, exit_code, ran_on_start, blocked_login ` type InsertWorkspaceAgentScriptTimingsParams struct { - AgentID uuid.UUID `db:"agent_id" json:"agent_id"` + ScriptID uuid.UUID `db:"script_id" json:"script_id"` DisplayName string `db:"display_name" json:"display_name"` StartedAt time.Time `db:"started_at" json:"started_at"` EndedAt time.Time `db:"ended_at" json:"ended_at"` @@ -11829,7 +11829,7 @@ type InsertWorkspaceAgentScriptTimingsParams struct { func (q *sqlQuerier) InsertWorkspaceAgentScriptTimings(ctx context.Context, arg InsertWorkspaceAgentScriptTimingsParams) (WorkspaceAgentScriptTiming, error) { row := q.db.QueryRowContext(ctx, insertWorkspaceAgentScriptTimings, - arg.AgentID, + arg.ScriptID, arg.DisplayName, arg.StartedAt, arg.EndedAt, @@ -11839,7 +11839,7 @@ func (q *sqlQuerier) InsertWorkspaceAgentScriptTimings(ctx context.Context, arg ) var i WorkspaceAgentScriptTiming err := row.Scan( - &i.AgentID, + &i.ScriptID, &i.DisplayName, &i.StartedAt, &i.EndedAt, @@ -15540,7 +15540,7 @@ func (q *sqlQuerier) UpdateWorkspacesDormantDeletingAtByTemplateID(ctx context.C } const getWorkspaceAgentScriptsByAgentIDs = `-- name: GetWorkspaceAgentScriptsByAgentIDs :many -SELECT workspace_agent_id, log_source_id, log_path, created_at, script, cron, start_blocks_login, run_on_start, run_on_stop, timeout_seconds, display_name FROM workspace_agent_scripts WHERE workspace_agent_id = ANY($1 :: uuid [ ]) +SELECT workspace_agent_id, log_source_id, log_path, created_at, script, cron, start_blocks_login, run_on_start, run_on_stop, timeout_seconds, id, display_name FROM workspace_agent_scripts WHERE workspace_agent_id = ANY($1 :: uuid [ ]) ` func (q *sqlQuerier) GetWorkspaceAgentScriptsByAgentIDs(ctx context.Context, ids []uuid.UUID) ([]WorkspaceAgentScript, error) { @@ -15563,6 +15563,7 @@ func (q *sqlQuerier) GetWorkspaceAgentScriptsByAgentIDs(ctx context.Context, ids &i.RunOnStart, &i.RunOnStop, &i.TimeoutSeconds, + &i.ID, &i.DisplayName, ); err != nil { return nil, err @@ -15580,7 +15581,7 @@ func (q *sqlQuerier) GetWorkspaceAgentScriptsByAgentIDs(ctx context.Context, ids const insertWorkspaceAgentScripts = `-- name: InsertWorkspaceAgentScripts :many INSERT INTO - workspace_agent_scripts ( workspace_agent_id, created_at, log_source_id, log_path, script, cron, start_blocks_login, run_on_start, run_on_stop, timeout_seconds, display_name ) + workspace_agent_scripts ( workspace_agent_id, created_at, log_source_id, log_path, script, cron, start_blocks_login, run_on_start, run_on_stop, timeout_seconds, display_name, id ) SELECT $1 :: uuid AS workspace_agent_id, $2 :: timestamptz AS created_at, @@ -15592,8 +15593,9 @@ SELECT unnest($8 :: boolean [ ]) AS run_on_start, unnest($9 :: boolean [ ]) AS run_on_stop, unnest($10 :: integer [ ]) AS timeout_seconds, - unnest($11 :: text [ ]) AS display_name -RETURNING workspace_agent_scripts.workspace_agent_id, workspace_agent_scripts.log_source_id, workspace_agent_scripts.log_path, workspace_agent_scripts.created_at, workspace_agent_scripts.script, workspace_agent_scripts.cron, workspace_agent_scripts.start_blocks_login, workspace_agent_scripts.run_on_start, workspace_agent_scripts.run_on_stop, workspace_agent_scripts.timeout_seconds, workspace_agent_scripts.display_name + unnest($11 :: text [ ]) AS display_name, + unnest($12 :: uuid [ ]) AS id +RETURNING workspace_agent_scripts.workspace_agent_id, workspace_agent_scripts.log_source_id, workspace_agent_scripts.log_path, workspace_agent_scripts.created_at, workspace_agent_scripts.script, workspace_agent_scripts.cron, workspace_agent_scripts.start_blocks_login, workspace_agent_scripts.run_on_start, workspace_agent_scripts.run_on_stop, workspace_agent_scripts.timeout_seconds, workspace_agent_scripts.id, workspace_agent_scripts.display_name ` type InsertWorkspaceAgentScriptsParams struct { @@ -15608,6 +15610,7 @@ type InsertWorkspaceAgentScriptsParams struct { RunOnStop []bool `db:"run_on_stop" json:"run_on_stop"` TimeoutSeconds []int32 `db:"timeout_seconds" json:"timeout_seconds"` DisplayName []string `db:"display_name" json:"display_name"` + ID []uuid.UUID `db:"id" json:"id"` } func (q *sqlQuerier) InsertWorkspaceAgentScripts(ctx context.Context, arg InsertWorkspaceAgentScriptsParams) ([]WorkspaceAgentScript, error) { @@ -15623,6 +15626,7 @@ func (q *sqlQuerier) InsertWorkspaceAgentScripts(ctx context.Context, arg Insert pq.Array(arg.RunOnStop), pq.Array(arg.TimeoutSeconds), pq.Array(arg.DisplayName), + pq.Array(arg.ID), ) if err != nil { return nil, err @@ -15642,6 +15646,7 @@ func (q *sqlQuerier) InsertWorkspaceAgentScripts(ctx context.Context, arg Insert &i.RunOnStart, &i.RunOnStop, &i.TimeoutSeconds, + &i.ID, &i.DisplayName, ); err != nil { return nil, err diff --git a/coderd/database/queries/workspaceagents.sql b/coderd/database/queries/workspaceagents.sql index e703239668c7e..3de7531bfec2f 100644 --- a/coderd/database/queries/workspaceagents.sql +++ b/coderd/database/queries/workspaceagents.sql @@ -291,7 +291,7 @@ WHERE -- name: InsertWorkspaceAgentScriptTimings :one INSERT INTO workspace_agent_script_timings ( - agent_id, + script_id, display_name, started_at, ended_at, diff --git a/coderd/database/queries/workspacescripts.sql b/coderd/database/queries/workspacescripts.sql index 3e8d1fb07bd45..671a37dfa1e08 100644 --- a/coderd/database/queries/workspacescripts.sql +++ b/coderd/database/queries/workspacescripts.sql @@ -1,6 +1,6 @@ -- name: InsertWorkspaceAgentScripts :many INSERT INTO - workspace_agent_scripts ( workspace_agent_id, created_at, log_source_id, log_path, script, cron, start_blocks_login, run_on_start, run_on_stop, timeout_seconds, display_name ) + workspace_agent_scripts ( workspace_agent_id, created_at, log_source_id, log_path, script, cron, start_blocks_login, run_on_start, run_on_stop, timeout_seconds, display_name, id ) SELECT @workspace_agent_id :: uuid AS workspace_agent_id, @created_at :: timestamptz AS created_at, @@ -12,7 +12,8 @@ SELECT unnest(@run_on_start :: boolean [ ]) AS run_on_start, unnest(@run_on_stop :: boolean [ ]) AS run_on_stop, unnest(@timeout_seconds :: integer [ ]) AS timeout_seconds, - unnest(@display_name :: text [ ]) AS display_name + unnest(@display_name :: text [ ]) AS display_name, + unnest(@id :: uuid [ ]) AS id RETURNING workspace_agent_scripts.*; -- name: GetWorkspaceAgentScriptsByAgentIDs :many diff --git a/coderd/database/unique_constraint.go b/coderd/database/unique_constraint.go index 92e1515475420..1ce55f8fa17d6 100644 --- a/coderd/database/unique_constraint.go +++ b/coderd/database/unique_constraint.go @@ -67,6 +67,7 @@ const ( UniqueWorkspaceAgentLogSourcesPkey UniqueConstraint = "workspace_agent_log_sources_pkey" // ALTER TABLE ONLY workspace_agent_log_sources ADD CONSTRAINT workspace_agent_log_sources_pkey PRIMARY KEY (workspace_agent_id, id); UniqueWorkspaceAgentMetadataPkey UniqueConstraint = "workspace_agent_metadata_pkey" // ALTER TABLE ONLY workspace_agent_metadata ADD CONSTRAINT workspace_agent_metadata_pkey PRIMARY KEY (workspace_agent_id, key); UniqueWorkspaceAgentPortSharePkey UniqueConstraint = "workspace_agent_port_share_pkey" // ALTER TABLE ONLY workspace_agent_port_share ADD CONSTRAINT workspace_agent_port_share_pkey PRIMARY KEY (workspace_id, agent_name, port); + UniqueWorkspaceAgentScriptsIDKey UniqueConstraint = "workspace_agent_scripts_id_key" // ALTER TABLE ONLY workspace_agent_scripts ADD CONSTRAINT workspace_agent_scripts_id_key UNIQUE (id); UniqueWorkspaceAgentStartupLogsPkey UniqueConstraint = "workspace_agent_startup_logs_pkey" // ALTER TABLE ONLY workspace_agent_logs ADD CONSTRAINT workspace_agent_startup_logs_pkey PRIMARY KEY (id); UniqueWorkspaceAgentsPkey UniqueConstraint = "workspace_agents_pkey" // ALTER TABLE ONLY workspace_agents ADD CONSTRAINT workspace_agents_pkey PRIMARY KEY (id); UniqueWorkspaceAppStatsPkey UniqueConstraint = "workspace_app_stats_pkey" // ALTER TABLE ONLY workspace_app_stats ADD CONSTRAINT workspace_app_stats_pkey PRIMARY KEY (id); diff --git a/coderd/provisionerdserver/provisionerdserver.go b/coderd/provisionerdserver/provisionerdserver.go index 84739ac9cd78a..2db5bbd1062b1 100644 --- a/coderd/provisionerdserver/provisionerdserver.go +++ b/coderd/provisionerdserver/provisionerdserver.go @@ -1818,6 +1818,7 @@ func InsertWorkspaceResource(ctx context.Context, db database.Store, jobID uuid. logSourceIDs := make([]uuid.UUID, 0, len(prAgent.Scripts)) logSourceDisplayNames := make([]string, 0, len(prAgent.Scripts)) logSourceIcons := make([]string, 0, len(prAgent.Scripts)) + scriptIDs := make([]uuid.UUID, 0, len(prAgent.Scripts)) scriptDisplayName := make([]string, 0, len(prAgent.Scripts)) scriptLogPaths := make([]string, 0, len(prAgent.Scripts)) scriptSources := make([]string, 0, len(prAgent.Scripts)) @@ -1831,6 +1832,7 @@ func InsertWorkspaceResource(ctx context.Context, db database.Store, jobID uuid. logSourceIDs = append(logSourceIDs, uuid.New()) logSourceDisplayNames = append(logSourceDisplayNames, script.DisplayName) logSourceIcons = append(logSourceIcons, script.Icon) + scriptIDs = append(scriptIDs, uuid.New()) scriptDisplayName = append(scriptDisplayName, script.DisplayName) scriptLogPaths = append(scriptLogPaths, script.LogPath) scriptSources = append(scriptSources, script.Script) @@ -1864,6 +1866,7 @@ func InsertWorkspaceResource(ctx context.Context, db database.Store, jobID uuid. RunOnStart: scriptRunOnStart, RunOnStop: scriptRunOnStop, DisplayName: scriptDisplayName, + ID: scriptIDs, }) if err != nil { return xerrors.Errorf("insert agent scripts: %w", err) diff --git a/coderd/workspaceagents.go b/coderd/workspaceagents.go index be1a1c1069252..6b2d771f21974 100644 --- a/coderd/workspaceagents.go +++ b/coderd/workspaceagents.go @@ -969,6 +969,7 @@ func convertScripts(dbScripts []database.WorkspaceAgentScript) []codersdk.Worksp scripts := make([]codersdk.WorkspaceAgentScript, 0) for _, dbScript := range dbScripts { scripts = append(scripts, codersdk.WorkspaceAgentScript{ + ID: dbScript.ID, DisplayName: dbScript.DisplayName, LogPath: dbScript.LogPath, LogSourceID: dbScript.LogSourceID, diff --git a/codersdk/agentsdk/convert.go b/codersdk/agentsdk/convert.go index e648645a6b731..5de2ecbaafc31 100644 --- a/codersdk/agentsdk/convert.go +++ b/codersdk/agentsdk/convert.go @@ -158,13 +158,19 @@ func ProtoFromScripts(scripts []codersdk.WorkspaceAgentScript) []*proto.Workspac } func AgentScriptFromProto(protoScript *proto.WorkspaceAgentScript) (codersdk.WorkspaceAgentScript, error) { - id, err := uuid.FromBytes(protoScript.LogSourceId) + id, err := uuid.FromBytes(protoScript.Id) if err != nil { return codersdk.WorkspaceAgentScript{}, xerrors.Errorf("parse id: %w", err) } + logSourceID, err := uuid.FromBytes(protoScript.LogSourceId) + if err != nil { + return codersdk.WorkspaceAgentScript{}, xerrors.Errorf("parse log source id: %w", err) + } + return codersdk.WorkspaceAgentScript{ - LogSourceID: id, + ID: id, + LogSourceID: logSourceID, DisplayName: protoScript.DisplayName, LogPath: protoScript.LogPath, Script: protoScript.Script, diff --git a/codersdk/workspaceagents.go b/codersdk/workspaceagents.go index 497b4f79995f2..15300c32e7ece 100644 --- a/codersdk/workspaceagents.go +++ b/codersdk/workspaceagents.go @@ -185,6 +185,7 @@ type WorkspaceAgentLogSource struct { } type WorkspaceAgentScript struct { + ID uuid.UUID `json:"id" format:"uuid"` DisplayName string `json:"display_name"` LogSourceID uuid.UUID `json:"log_source_id" format:"uuid"` LogPath string `json:"log_path"` diff --git a/docs/reference/api/agents.md b/docs/reference/api/agents.md index ee15d88b2b3be..8e7f46bc7d366 100644 --- a/docs/reference/api/agents.md +++ b/docs/reference/api/agents.md @@ -488,6 +488,7 @@ curl -X GET http://coder-server:8080/api/v2/workspaceagents/{workspaceagent} \ { "cron": "string", "display_name": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", "log_path": "string", "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a", "run_on_start": true, diff --git a/docs/reference/api/builds.md b/docs/reference/api/builds.md index c40e5171ddb52..c0f1658e8ec8a 100644 --- a/docs/reference/api/builds.md +++ b/docs/reference/api/builds.md @@ -129,6 +129,7 @@ curl -X GET http://coder-server:8080/api/v2/users/{user}/workspace/{workspacenam { "cron": "string", "display_name": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", "log_path": "string", "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a", "run_on_start": true, @@ -313,6 +314,7 @@ curl -X GET http://coder-server:8080/api/v2/workspacebuilds/{workspacebuild} \ { "cron": "string", "display_name": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", "log_path": "string", "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a", "run_on_start": true, @@ -636,6 +638,7 @@ curl -X GET http://coder-server:8080/api/v2/workspacebuilds/{workspacebuild}/res { "cron": "string", "display_name": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", "log_path": "string", "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a", "run_on_start": true, @@ -742,6 +745,7 @@ Status Code **200** | `»» scripts` | array | false | | | | `»»» cron` | string | false | | | | `»»» display_name` | string | false | | | +| `»»» id` | string(uuid) | false | | | | `»»» log_path` | string | false | | | | `»»» log_source_id` | string(uuid) | false | | | | `»»» run_on_start` | boolean | false | | | @@ -929,6 +933,7 @@ curl -X GET http://coder-server:8080/api/v2/workspacebuilds/{workspacebuild}/sta { "cron": "string", "display_name": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", "log_path": "string", "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a", "run_on_start": true, @@ -1118,6 +1123,7 @@ curl -X GET http://coder-server:8080/api/v2/workspaces/{workspace}/builds \ { "cron": "string", "display_name": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", "log_path": "string", "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a", "run_on_start": true, @@ -1261,6 +1267,7 @@ Status Code **200** | `»»» scripts` | array | false | | | | `»»»» cron` | string | false | | | | `»»»» display_name` | string | false | | | +| `»»»» id` | string(uuid) | false | | | | `»»»» log_path` | string | false | | | | `»»»» log_source_id` | string(uuid) | false | | | | `»»»» run_on_start` | boolean | false | | | @@ -1502,6 +1509,7 @@ curl -X POST http://coder-server:8080/api/v2/workspaces/{workspace}/builds \ { "cron": "string", "display_name": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", "log_path": "string", "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a", "run_on_start": true, diff --git a/docs/reference/api/schemas.md b/docs/reference/api/schemas.md index 7e440d977da7e..c8f58d591170b 100644 --- a/docs/reference/api/schemas.md +++ b/docs/reference/api/schemas.md @@ -6455,6 +6455,7 @@ If the schedule is empty, the user will be updated to use the default schedule.| { "cron": "string", "display_name": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", "log_path": "string", "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a", "run_on_start": true, @@ -6635,6 +6636,7 @@ If the schedule is empty, the user will be updated to use the default schedule.| { "cron": "string", "display_name": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", "log_path": "string", "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a", "run_on_start": true, @@ -6904,6 +6906,7 @@ If the schedule is empty, the user will be updated to use the default schedule.| { "cron": "string", "display_name": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", "log_path": "string", "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a", "run_on_start": true, @@ -6920,6 +6923,7 @@ If the schedule is empty, the user will be updated to use the default schedule.| | -------------------- | ------- | -------- | ------------ | ----------- | | `cron` | string | false | | | | `display_name` | string | false | | | +| `id` | string | false | | | | `log_path` | string | false | | | | `log_source_id` | string | false | | | | `run_on_start` | boolean | false | | | @@ -7149,6 +7153,7 @@ If the schedule is empty, the user will be updated to use the default schedule.| { "cron": "string", "display_name": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", "log_path": "string", "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a", "run_on_start": true, @@ -7485,6 +7490,7 @@ If the schedule is empty, the user will be updated to use the default schedule.| { "cron": "string", "display_name": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", "log_path": "string", "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a", "run_on_start": true, @@ -7746,6 +7752,7 @@ If the schedule is empty, the user will be updated to use the default schedule.| { "cron": "string", "display_name": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", "log_path": "string", "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a", "run_on_start": true, diff --git a/docs/reference/api/templates.md b/docs/reference/api/templates.md index bd346e5b5a542..ceda61533ef5b 100644 --- a/docs/reference/api/templates.md +++ b/docs/reference/api/templates.md @@ -2001,6 +2001,7 @@ curl -X GET http://coder-server:8080/api/v2/templateversions/{templateversion}/d { "cron": "string", "display_name": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", "log_path": "string", "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a", "run_on_start": true, @@ -2107,6 +2108,7 @@ Status Code **200** | `»» scripts` | array | false | | | | `»»» cron` | string | false | | | | `»»» display_name` | string | false | | | +| `»»» id` | string(uuid) | false | | | | `»»» log_path` | string | false | | | | `»»» log_source_id` | string(uuid) | false | | | | `»»» run_on_start` | boolean | false | | | @@ -2425,6 +2427,7 @@ curl -X GET http://coder-server:8080/api/v2/templateversions/{templateversion}/r { "cron": "string", "display_name": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", "log_path": "string", "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a", "run_on_start": true, @@ -2531,6 +2534,7 @@ Status Code **200** | `»» scripts` | array | false | | | | `»»» cron` | string | false | | | | `»»» display_name` | string | false | | | +| `»»» id` | string(uuid) | false | | | | `»»» log_path` | string | false | | | | `»»» log_source_id` | string(uuid) | false | | | | `»»» run_on_start` | boolean | false | | | diff --git a/docs/reference/api/workspaces.md b/docs/reference/api/workspaces.md index 387c221639401..2987cf65159e4 100644 --- a/docs/reference/api/workspaces.md +++ b/docs/reference/api/workspaces.md @@ -168,6 +168,7 @@ of the template will be used. { "cron": "string", "display_name": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", "log_path": "string", "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a", "run_on_start": true, @@ -385,6 +386,7 @@ curl -X GET http://coder-server:8080/api/v2/users/{user}/workspace/{workspacenam { "cron": "string", "display_name": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", "log_path": "string", "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a", "run_on_start": true, @@ -626,6 +628,7 @@ of the template will be used. { "cron": "string", "display_name": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", "log_path": "string", "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a", "run_on_start": true, @@ -842,6 +845,7 @@ curl -X GET http://coder-server:8080/api/v2/workspaces \ { "cron": "string", "display_name": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", "log_path": "string", "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a", "run_on_start": true, @@ -1060,6 +1064,7 @@ curl -X GET http://coder-server:8080/api/v2/workspaces/{workspace} \ { "cron": "string", "display_name": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", "log_path": "string", "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a", "run_on_start": true, @@ -1393,6 +1398,7 @@ curl -X PUT http://coder-server:8080/api/v2/workspaces/{workspace}/dormant \ { "cron": "string", "display_name": "string", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", "log_path": "string", "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a", "run_on_start": true, diff --git a/site/src/api/typesGenerated.ts b/site/src/api/typesGenerated.ts index 8959b7076b2f0..031a433723086 100644 --- a/site/src/api/typesGenerated.ts +++ b/site/src/api/typesGenerated.ts @@ -1887,6 +1887,7 @@ export interface WorkspaceAgentPortShares { // From codersdk/workspaceagents.go export interface WorkspaceAgentScript { + readonly id: string; readonly display_name: string; readonly log_source_id: string; readonly log_path: string; diff --git a/site/src/testHelpers/entities.ts b/site/src/testHelpers/entities.ts index b2ef350907fbb..0aad6b5f0eb6b 100644 --- a/site/src/testHelpers/entities.ts +++ b/site/src/testHelpers/entities.ts @@ -886,6 +886,7 @@ export const MockWorkspaceAgentLogSource: TypesGen.WorkspaceAgentLogSource = { }; export const MockWorkspaceAgentScript: TypesGen.WorkspaceAgentScript = { + id: "08eaca83-1221-4fad-b882-d1136981f54d", display_name: "", log_source_id: MockWorkspaceAgentLogSource.id, cron: "", From 863c3dc1bc01e694d609b8b439f7ca353eba9ab7 Mon Sep 17 00:00:00 2001 From: Danielle Maywood Date: Thu, 19 Sep 2024 13:42:05 +0000 Subject: [PATCH 28/56] fix: fix broken tests and convert bug --- agent/agent_test.go | 2 ++ coderd/agentapi/manifest_test.go | 4 ++++ codersdk/agentsdk/convert.go | 1 + codersdk/agentsdk/convert_test.go | 2 ++ 4 files changed, 9 insertions(+) diff --git a/agent/agent_test.go b/agent/agent_test.go index 91e7c1c34e0c0..5ef7afdb0e920 100644 --- a/agent/agent_test.go +++ b/agent/agent_test.go @@ -1517,10 +1517,12 @@ func TestAgent_Lifecycle(t *testing.T) { agentsdk.Manifest{ DERPMap: derpMap, Scripts: []codersdk.WorkspaceAgentScript{{ + ID: uuid.New(), LogPath: "coder-startup-script.log", Script: "echo 1", RunOnStart: true, }, { + ID: uuid.New(), LogPath: "coder-shutdown-script.log", Script: "echo " + expected, RunOnStop: true, diff --git a/coderd/agentapi/manifest_test.go b/coderd/agentapi/manifest_test.go index 546c70e16fc18..e7a36081f64b4 100644 --- a/coderd/agentapi/manifest_test.go +++ b/coderd/agentapi/manifest_test.go @@ -108,6 +108,7 @@ func TestGetManifest(t *testing.T) { } scripts = []database.WorkspaceAgentScript{ { + ID: uuid.New(), WorkspaceAgentID: agent.ID, LogSourceID: uuid.New(), LogPath: "/cool/log/path/1", @@ -119,6 +120,7 @@ func TestGetManifest(t *testing.T) { TimeoutSeconds: 60, }, { + ID: uuid.New(), WorkspaceAgentID: agent.ID, LogSourceID: uuid.New(), LogPath: "/cool/log/path/2", @@ -227,6 +229,7 @@ func TestGetManifest(t *testing.T) { } protoScripts = []*agentproto.WorkspaceAgentScript{ { + Id: scripts[0].ID[:], LogSourceId: scripts[0].LogSourceID[:], LogPath: scripts[0].LogPath, Script: scripts[0].Script, @@ -237,6 +240,7 @@ func TestGetManifest(t *testing.T) { Timeout: durationpb.New(time.Duration(scripts[0].TimeoutSeconds) * time.Second), }, { + Id: scripts[1].ID[:], LogSourceId: scripts[1].LogSourceID[:], LogPath: scripts[1].LogPath, Script: scripts[1].Script, diff --git a/codersdk/agentsdk/convert.go b/codersdk/agentsdk/convert.go index 5de2ecbaafc31..8b47563089b78 100644 --- a/codersdk/agentsdk/convert.go +++ b/codersdk/agentsdk/convert.go @@ -184,6 +184,7 @@ func AgentScriptFromProto(protoScript *proto.WorkspaceAgentScript) (codersdk.Wor func ProtoFromScript(s codersdk.WorkspaceAgentScript) *proto.WorkspaceAgentScript { return &proto.WorkspaceAgentScript{ + Id: s.ID[:], DisplayName: s.DisplayName, LogSourceId: s.LogSourceID[:], LogPath: s.LogPath, diff --git a/codersdk/agentsdk/convert_test.go b/codersdk/agentsdk/convert_test.go index b7d9ee3fe2cfe..3c96a5a2beed6 100644 --- a/codersdk/agentsdk/convert_test.go +++ b/codersdk/agentsdk/convert_test.go @@ -106,6 +106,7 @@ func TestManifest(t *testing.T) { }, Scripts: []codersdk.WorkspaceAgentScript{ { + ID: uuid.New(), LogSourceID: uuid.New(), LogPath: "/var/log/script.log", Script: "script", @@ -116,6 +117,7 @@ func TestManifest(t *testing.T) { Timeout: time.Second, }, { + ID: uuid.New(), LogSourceID: uuid.New(), LogPath: "/var/log/script2.log", Script: "script2", From b8d5d1d9882adaa40a68d11657c8d86fd4997e59 Mon Sep 17 00:00:00 2001 From: Danielle Maywood Date: Thu, 19 Sep 2024 13:50:53 +0000 Subject: [PATCH 29/56] fix: update testdata fixtures --- .../testdata/fixtures/000157_workspace_agent_script.up.sql | 2 ++ .../fixtures/000255_workspace_agent_script_timings.up.sql | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/coderd/database/migrations/testdata/fixtures/000157_workspace_agent_script.up.sql b/coderd/database/migrations/testdata/fixtures/000157_workspace_agent_script.up.sql index 7523cd4714285..b0a041961b4ed 100644 --- a/coderd/database/migrations/testdata/fixtures/000157_workspace_agent_script.up.sql +++ b/coderd/database/migrations/testdata/fixtures/000157_workspace_agent_script.up.sql @@ -15,6 +15,7 @@ INSERT INTO workspace_agent_log_sources ( ) ON CONFLICT DO NOTHING; INSERT INTO workspace_agent_scripts ( + id, workspace_agent_id, created_at, log_source_id, @@ -26,6 +27,7 @@ INSERT INTO workspace_agent_scripts ( run_on_stop, timeout_seconds ) VALUES ( + 'a810e1ba-0b28-4db2-a5b6-1857ea72bf93', '45e89705-e09d-4850-bcec-f9a937f5d78d', '2022-11-02 13:03:45.046432+02', '0ff953c0-92a6-4fe6-a415-eb0139a36ad1', diff --git a/coderd/database/migrations/testdata/fixtures/000255_workspace_agent_script_timings.up.sql b/coderd/database/migrations/testdata/fixtures/000255_workspace_agent_script_timings.up.sql index f37513dcce84a..ac18bfc18b71e 100644 --- a/coderd/database/migrations/testdata/fixtures/000255_workspace_agent_script_timings.up.sql +++ b/coderd/database/migrations/testdata/fixtures/000255_workspace_agent_script_timings.up.sql @@ -1,3 +1,3 @@ -INSERT INTO workspace_agent_script_timings (agent_id, display_name, started_at, ended_at, exit_code, ran_on_start, blocked_login) +INSERT INTO workspace_agent_script_timings (script_id, display_name, started_at, ended_at, exit_code, ran_on_start, blocked_login) VALUES - ('45e89705-e09d-4850-bcec-f9a937f5d78d', 'Startup Script', NOW() - INTERVAL '1 hour 55 minutes', NOW() - INTERVAL '1 hour 50 minutes', 0, true, false); + ('a810e1ba-0b28-4db2-a5b6-1857ea72bf93', 'Startup Script', NOW() - INTERVAL '1 hour 55 minutes', NOW() - INTERVAL '1 hour 50 minutes', 0, true, false); From 61c26eab00c13546cb8e4aa4c3d24b3f759d0472 Mon Sep 17 00:00:00 2001 From: Danielle Maywood Date: Thu, 19 Sep 2024 14:07:40 +0000 Subject: [PATCH 30/56] fix: update testdata fixtures again --- .../testdata/fixtures/000157_workspace_agent_script.up.sql | 2 -- .../fixtures/000255_workspace_agent_script_timings.up.sql | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/coderd/database/migrations/testdata/fixtures/000157_workspace_agent_script.up.sql b/coderd/database/migrations/testdata/fixtures/000157_workspace_agent_script.up.sql index b0a041961b4ed..7523cd4714285 100644 --- a/coderd/database/migrations/testdata/fixtures/000157_workspace_agent_script.up.sql +++ b/coderd/database/migrations/testdata/fixtures/000157_workspace_agent_script.up.sql @@ -15,7 +15,6 @@ INSERT INTO workspace_agent_log_sources ( ) ON CONFLICT DO NOTHING; INSERT INTO workspace_agent_scripts ( - id, workspace_agent_id, created_at, log_source_id, @@ -27,7 +26,6 @@ INSERT INTO workspace_agent_scripts ( run_on_stop, timeout_seconds ) VALUES ( - 'a810e1ba-0b28-4db2-a5b6-1857ea72bf93', '45e89705-e09d-4850-bcec-f9a937f5d78d', '2022-11-02 13:03:45.046432+02', '0ff953c0-92a6-4fe6-a415-eb0139a36ad1', diff --git a/coderd/database/migrations/testdata/fixtures/000255_workspace_agent_script_timings.up.sql b/coderd/database/migrations/testdata/fixtures/000255_workspace_agent_script_timings.up.sql index ac18bfc18b71e..9b0059ac28a53 100644 --- a/coderd/database/migrations/testdata/fixtures/000255_workspace_agent_script_timings.up.sql +++ b/coderd/database/migrations/testdata/fixtures/000255_workspace_agent_script_timings.up.sql @@ -1,3 +1,3 @@ INSERT INTO workspace_agent_script_timings (script_id, display_name, started_at, ended_at, exit_code, ran_on_start, blocked_login) VALUES - ('a810e1ba-0b28-4db2-a5b6-1857ea72bf93', 'Startup Script', NOW() - INTERVAL '1 hour 55 minutes', NOW() - INTERVAL '1 hour 50 minutes', 0, true, false); + ((SELECT id FROM workspace_agent_scripts LIMIT 1), 'Startup Script', NOW() - INTERVAL '1 hour 55 minutes', NOW() - INTERVAL '1 hour 50 minutes', 0, true, false); From 7f8b6f94770658591239c47f601c25adde12745b Mon Sep 17 00:00:00 2001 From: Danielle Maywood Date: Fri, 20 Sep 2024 08:33:13 +0000 Subject: [PATCH 31/56] feat: capture stage and if script timed out --- agent/agent.go | 8 +- agent/agentscripts/agentscripts.go | 59 ++- agent/agentscripts/agentscripts_test.go | 14 +- agent/proto/agent.pb.go | 466 ++++++++++-------- agent/proto/agent.proto | 20 +- coderd/agentapi/scripts.go | 24 +- coderd/database/dbauthz/dbauthz_test.go | 1 + coderd/database/dbmem/dbmem.go | 14 +- coderd/database/dump.sql | 10 +- ...55_workspace_agent_script_timings.down.sql | 1 + ...0255_workspace_agent_script_timings.up.sql | 23 +- ...0255_workspace_agent_script_timings.up.sql | 4 +- coderd/database/models.go | 75 ++- coderd/database/queries.sql.go | 28 +- coderd/database/queries/workspaceagents.sql | 4 +- 15 files changed, 452 insertions(+), 299 deletions(-) diff --git a/agent/agent.go b/agent/agent.go index 1f88666ade522..3a01605639a35 100644 --- a/agent/agent.go +++ b/agent/agent.go @@ -949,9 +949,7 @@ func (a *agent) handleManifest(manifestOK *checkpoint) func(ctx context.Context, start := time.Now() // here we use the graceful context because the script runner is not directly tied // to the agent API. - err := a.scriptRunner.Execute(a.gracefulCtx, func(script codersdk.WorkspaceAgentScript) bool { - return script.RunOnStart - }) + err := a.scriptRunner.Execute(a.gracefulCtx, agentscripts.ExecuteStartScripts) // Measure the time immediately after the script has finished dur := time.Since(start).Seconds() if err != nil { @@ -1844,9 +1842,7 @@ func (a *agent) Close() error { a.gracefulCancel() lifecycleState := codersdk.WorkspaceAgentLifecycleOff - err = a.scriptRunner.Execute(a.hardCtx, func(script codersdk.WorkspaceAgentScript) bool { - return script.RunOnStop - }) + err = a.scriptRunner.Execute(a.hardCtx, agentscripts.ExecuteStopScripts) if err != nil { a.logger.Warn(a.hardCtx, "shutdown script(s) failed", slog.Error(err)) if errors.Is(err, agentscripts.ErrTimeout) { diff --git a/agent/agentscripts/agentscripts.go b/agent/agentscripts/agentscripts.go index 6cd4ef1110b5b..f27c2da4b0df6 100644 --- a/agent/agentscripts/agentscripts.go +++ b/agent/agentscripts/agentscripts.go @@ -141,7 +141,7 @@ func (r *Runner) Init(scripts []codersdk.WorkspaceAgentScript, scriptCompleted S } script := script _, err := r.cron.AddFunc(script.Cron, func() { - err := r.trackRun(r.cronCtx, script) + err := r.trackRun(r.cronCtx, script, ExecuteCronScripts) if err != nil { r.Logger.Warn(context.Background(), "run agent script on schedule", slog.Error(err)) } @@ -178,22 +178,31 @@ func (r *Runner) StartCron() { } } +type ExecuteOption int + +const ( + ExecuteAllScripts ExecuteOption = iota + ExecuteStartScripts + ExecuteStopScripts + ExecuteCronScripts +) + // Execute runs a set of scripts according to a filter. -func (r *Runner) Execute(ctx context.Context, filter func(script codersdk.WorkspaceAgentScript) bool) error { - if filter == nil { - // Execute em' all! - filter = func(script codersdk.WorkspaceAgentScript) bool { - return true - } - } +func (r *Runner) Execute(ctx context.Context, option ExecuteOption) error { var eg errgroup.Group for _, script := range r.scripts { - if !filter(script) { + runScript := (option == ExecuteStartScripts && script.RunOnStart) || + (option == ExecuteStopScripts && script.RunOnStop) || + (option == ExecuteCronScripts && script.Cron != "") || + option == ExecuteAllScripts + + if !runScript { continue } + script := script eg.Go(func() error { - err := r.trackRun(ctx, script) + err := r.trackRun(ctx, script, option) if err != nil { return xerrors.Errorf("run agent script %q: %w", script.LogSourceID, err) } @@ -204,8 +213,8 @@ func (r *Runner) Execute(ctx context.Context, filter func(script codersdk.Worksp } // trackRun wraps "run" with metrics. -func (r *Runner) trackRun(ctx context.Context, script codersdk.WorkspaceAgentScript) error { - err := r.run(ctx, script) +func (r *Runner) trackRun(ctx context.Context, script codersdk.WorkspaceAgentScript, option ExecuteOption) error { + err := r.run(ctx, script, option) if err != nil { r.scriptsExecuted.WithLabelValues("false").Add(1) } else { @@ -218,7 +227,7 @@ func (r *Runner) trackRun(ctx context.Context, script codersdk.WorkspaceAgentScr // If the timeout is exceeded, the process is sent an interrupt signal. // If the process does not exit after a few seconds, it is forcefully killed. // This function immediately returns after a timeout, and does not wait for the process to exit. -func (r *Runner) run(ctx context.Context, script codersdk.WorkspaceAgentScript) error { +func (r *Runner) run(ctx context.Context, script codersdk.WorkspaceAgentScript, option ExecuteOption) error { logPath := script.LogPath if logPath == "" { logPath = fmt.Sprintf("coder-script-%s.log", script.LogSourceID) @@ -321,15 +330,25 @@ func (r *Runner) run(ctx context.Context, script codersdk.WorkspaceAgentScript) logger.Info(ctx, fmt.Sprintf("%s script completed", logPath), slog.F("execution_time", execTime), slog.F("exit_code", exitCode)) } + var stage proto.Timing_Stage + switch option { + case ExecuteStartScripts: + stage = proto.Timing_START + case ExecuteStopScripts: + stage = proto.Timing_STOP + case ExecuteCronScripts: + stage = proto.Timing_CRON + } + _, err = r.scriptCompleted(ctx, &proto.WorkspaceAgentScriptCompletedRequest{ Timing: &proto.Timing{ - ScriptId: script.ID[:], - DisplayName: script.DisplayName, - Start: timestamppb.New(start), - End: timestamppb.New(end), - ExitCode: int32(exitCode), - RanOnStart: script.RunOnStart, - BlockedLogin: script.StartBlocksLogin, + ScriptId: script.ID[:], + DisplayName: script.DisplayName, + Start: timestamppb.New(start), + End: timestamppb.New(end), + ExitCode: int32(exitCode), + Stage: stage, + TimedOut: errors.Is(err, ErrTimeout), }, }) diff --git a/agent/agentscripts/agentscripts_test.go b/agent/agentscripts/agentscripts_test.go index 8aa8d70279629..fa550db11239b 100644 --- a/agent/agentscripts/agentscripts_test.go +++ b/agent/agentscripts/agentscripts_test.go @@ -41,9 +41,7 @@ func TestExecuteBasic(t *testing.T) { Script: "echo hello", }}, aAPI.ScriptCompleted) require.NoError(t, err) - require.NoError(t, runner.Execute(context.Background(), func(script codersdk.WorkspaceAgentScript) bool { - return true - })) + require.NoError(t, runner.Execute(context.Background(), agentscripts.ExecuteAllScripts)) log := testutil.RequireRecvCtx(ctx, t, fLogger.logs) require.Equal(t, "hello", log.Output) } @@ -73,9 +71,7 @@ func TestEnv(t *testing.T) { ctx := testutil.Context(t, testutil.WaitLong) done := testutil.Go(t, func() { - err := runner.Execute(ctx, func(script codersdk.WorkspaceAgentScript) bool { - return true - }) + err := runner.Execute(ctx, agentscripts.ExecuteAllScripts) assert.NoError(t, err) }) defer func() { @@ -113,7 +109,7 @@ func TestTimeout(t *testing.T) { Timeout: time.Millisecond, }}, aAPI.ScriptCompleted) require.NoError(t, err) - require.ErrorIs(t, runner.Execute(context.Background(), nil), agentscripts.ErrTimeout) + require.ErrorIs(t, runner.Execute(context.Background(), agentscripts.ExecuteAllScripts), agentscripts.ErrTimeout) } func TestScriptReportsTiming(t *testing.T) { @@ -133,9 +129,7 @@ func TestScriptReportsTiming(t *testing.T) { Script: "echo hello", }}, aAPI.ScriptCompleted) require.NoError(t, err) - require.NoError(t, runner.Execute(context.Background(), func(script codersdk.WorkspaceAgentScript) bool { - return true - })) + require.NoError(t, runner.Execute(context.Background(), agentscripts.ExecuteAllScripts)) log := testutil.RequireRecvCtx(ctx, t, fLogger.logs) require.Equal(t, "hello", log.Output) diff --git a/agent/proto/agent.pb.go b/agent/proto/agent.pb.go index 898c2b2687782..b0fb99297245e 100644 --- a/agent/proto/agent.pb.go +++ b/agent/proto/agent.pb.go @@ -414,6 +414,55 @@ func (Log_Level) EnumDescriptor() ([]byte, []int) { return file_agent_proto_agent_proto_rawDescGZIP(), []int{19, 0} } +type Timing_Stage int32 + +const ( + Timing_START Timing_Stage = 0 + Timing_STOP Timing_Stage = 1 + Timing_CRON Timing_Stage = 2 +) + +// Enum value maps for Timing_Stage. +var ( + Timing_Stage_name = map[int32]string{ + 0: "START", + 1: "STOP", + 2: "CRON", + } + Timing_Stage_value = map[string]int32{ + "START": 0, + "STOP": 1, + "CRON": 2, + } +) + +func (x Timing_Stage) Enum() *Timing_Stage { + p := new(Timing_Stage) + *p = x + return p +} + +func (x Timing_Stage) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (Timing_Stage) Descriptor() protoreflect.EnumDescriptor { + return file_agent_proto_agent_proto_enumTypes[7].Descriptor() +} + +func (Timing_Stage) Type() protoreflect.EnumType { + return &file_agent_proto_agent_proto_enumTypes[7] +} + +func (x Timing_Stage) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use Timing_Stage.Descriptor instead. +func (Timing_Stage) EnumDescriptor() ([]byte, []int) { + return file_agent_proto_agent_proto_rawDescGZIP(), []int{27, 0} +} + type WorkspaceApp struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -2121,13 +2170,13 @@ type Timing struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - DisplayName string `protobuf:"bytes,1,opt,name=display_name,json=displayName,proto3" json:"display_name,omitempty"` - Start *timestamppb.Timestamp `protobuf:"bytes,2,opt,name=start,proto3" json:"start,omitempty"` - End *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=end,proto3" json:"end,omitempty"` - ExitCode int32 `protobuf:"varint,4,opt,name=exit_code,json=exitCode,proto3" json:"exit_code,omitempty"` - RanOnStart bool `protobuf:"varint,5,opt,name=ran_on_start,json=ranOnStart,proto3" json:"ran_on_start,omitempty"` - BlockedLogin bool `protobuf:"varint,6,opt,name=blocked_login,json=blockedLogin,proto3" json:"blocked_login,omitempty"` - ScriptId []byte `protobuf:"bytes,7,opt,name=script_id,json=scriptId,proto3" json:"script_id,omitempty"` + ScriptId []byte `protobuf:"bytes,1,opt,name=script_id,json=scriptId,proto3" json:"script_id,omitempty"` + DisplayName string `protobuf:"bytes,2,opt,name=display_name,json=displayName,proto3" json:"display_name,omitempty"` + Start *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=start,proto3" json:"start,omitempty"` + End *timestamppb.Timestamp `protobuf:"bytes,4,opt,name=end,proto3" json:"end,omitempty"` + ExitCode int32 `protobuf:"varint,5,opt,name=exit_code,json=exitCode,proto3" json:"exit_code,omitempty"` + Stage Timing_Stage `protobuf:"varint,6,opt,name=stage,proto3,enum=coder.agent.v2.Timing_Stage" json:"stage,omitempty"` + TimedOut bool `protobuf:"varint,7,opt,name=timed_out,json=timedOut,proto3" json:"timed_out,omitempty"` } func (x *Timing) Reset() { @@ -2162,6 +2211,13 @@ func (*Timing) Descriptor() ([]byte, []int) { return file_agent_proto_agent_proto_rawDescGZIP(), []int{27} } +func (x *Timing) GetScriptId() []byte { + if x != nil { + return x.ScriptId + } + return nil +} + func (x *Timing) GetDisplayName() string { if x != nil { return x.DisplayName @@ -2190,27 +2246,20 @@ func (x *Timing) GetExitCode() int32 { return 0 } -func (x *Timing) GetRanOnStart() bool { +func (x *Timing) GetStage() Timing_Stage { if x != nil { - return x.RanOnStart + return x.Stage } - return false + return Timing_START } -func (x *Timing) GetBlockedLogin() bool { +func (x *Timing) GetTimedOut() bool { if x != nil { - return x.BlockedLogin + return x.TimedOut } return false } -func (x *Timing) GetScriptId() []byte { - if x != nil { - return x.ScriptId - } - return nil -} - type WorkspaceApp_Healthcheck struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -2975,96 +3024,99 @@ var file_agent_proto_agent_proto_rawDesc = []byte{ 0x6e, 0x67, 0x52, 0x06, 0x74, 0x69, 0x6d, 0x69, 0x6e, 0x67, 0x22, 0x27, 0x0a, 0x25, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x8c, 0x02, 0x0a, 0x06, 0x54, 0x69, 0x6d, 0x69, 0x6e, 0x67, 0x12, 0x21, - 0x0a, 0x0c, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, - 0x65, 0x12, 0x30, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x05, 0x73, 0x74, - 0x61, 0x72, 0x74, 0x12, 0x2c, 0x0a, 0x03, 0x65, 0x6e, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x03, 0x65, 0x6e, - 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x65, 0x78, 0x69, 0x74, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x65, 0x78, 0x69, 0x74, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x20, - 0x0a, 0x0c, 0x72, 0x61, 0x6e, 0x5f, 0x6f, 0x6e, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x05, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x72, 0x61, 0x6e, 0x4f, 0x6e, 0x53, 0x74, 0x61, 0x72, 0x74, - 0x12, 0x23, 0x0a, 0x0d, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x65, 0x64, 0x5f, 0x6c, 0x6f, 0x67, 0x69, - 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x65, 0x64, - 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x5f, - 0x69, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, - 0x49, 0x64, 0x2a, 0x63, 0x0a, 0x09, 0x41, 0x70, 0x70, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x12, - 0x1a, 0x0a, 0x16, 0x41, 0x50, 0x50, 0x5f, 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, 0x5f, 0x55, 0x4e, - 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x44, - 0x49, 0x53, 0x41, 0x42, 0x4c, 0x45, 0x44, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x49, 0x4e, 0x49, - 0x54, 0x49, 0x41, 0x4c, 0x49, 0x5a, 0x49, 0x4e, 0x47, 0x10, 0x02, 0x12, 0x0b, 0x0a, 0x07, 0x48, - 0x45, 0x41, 0x4c, 0x54, 0x48, 0x59, 0x10, 0x03, 0x12, 0x0d, 0x0a, 0x09, 0x55, 0x4e, 0x48, 0x45, - 0x41, 0x4c, 0x54, 0x48, 0x59, 0x10, 0x04, 0x32, 0xef, 0x07, 0x0a, 0x05, 0x41, 0x67, 0x65, 0x6e, - 0x74, 0x12, 0x4b, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, - 0x12, 0x22, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, - 0x32, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, - 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x12, 0x5a, - 0x0a, 0x10, 0x47, 0x65, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x42, 0x61, 0x6e, 0x6e, - 0x65, 0x72, 0x12, 0x27, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, - 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x42, 0x61, - 0x6e, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x63, 0x6f, - 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x12, 0x56, 0x0a, 0x0b, 0x55, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x22, 0x2e, 0x63, 0x6f, 0x64, 0x65, - 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, - 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x55, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x54, 0x0a, 0x0f, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4c, 0x69, 0x66, 0x65, - 0x63, 0x79, 0x63, 0x6c, 0x65, 0x12, 0x26, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, - 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4c, 0x69, 0x66, - 0x65, 0x63, 0x79, 0x63, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, - 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x4c, - 0x69, 0x66, 0x65, 0x63, 0x79, 0x63, 0x6c, 0x65, 0x12, 0x72, 0x0a, 0x15, 0x42, 0x61, 0x74, 0x63, - 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x70, 0x70, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, - 0x73, 0x12, 0x2b, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, - 0x76, 0x32, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x70, - 0x70, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, - 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, - 0x42, 0x61, 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x70, 0x70, 0x48, 0x65, - 0x61, 0x6c, 0x74, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4e, 0x0a, 0x0d, - 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x12, 0x24, 0x2e, - 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x55, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, - 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x12, 0x6e, 0x0a, 0x13, - 0x42, 0x61, 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, - 0x61, 0x74, 0x61, 0x12, 0x2a, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, + 0x6e, 0x73, 0x65, 0x22, 0xbe, 0x02, 0x0a, 0x06, 0x54, 0x69, 0x6d, 0x69, 0x6e, 0x67, 0x12, 0x1b, + 0x0a, 0x09, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x08, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x64, + 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x30, + 0x0a, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, + 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, + 0x12, 0x2c, 0x0a, 0x03, 0x65, 0x6e, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, + 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x03, 0x65, 0x6e, 0x64, 0x12, 0x1b, + 0x0a, 0x09, 0x65, 0x78, 0x69, 0x74, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x05, 0x52, 0x08, 0x65, 0x78, 0x69, 0x74, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x32, 0x0a, 0x05, 0x73, + 0x74, 0x61, 0x67, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1c, 0x2e, 0x63, 0x6f, 0x64, + 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x54, 0x69, 0x6d, 0x69, + 0x6e, 0x67, 0x2e, 0x53, 0x74, 0x61, 0x67, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x67, 0x65, 0x12, + 0x1b, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x64, 0x5f, 0x6f, 0x75, 0x74, 0x18, 0x07, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x08, 0x74, 0x69, 0x6d, 0x65, 0x64, 0x4f, 0x75, 0x74, 0x22, 0x26, 0x0a, 0x05, + 0x53, 0x74, 0x61, 0x67, 0x65, 0x12, 0x09, 0x0a, 0x05, 0x53, 0x54, 0x41, 0x52, 0x54, 0x10, 0x00, + 0x12, 0x08, 0x0a, 0x04, 0x53, 0x54, 0x4f, 0x50, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x43, 0x52, + 0x4f, 0x4e, 0x10, 0x02, 0x2a, 0x63, 0x0a, 0x09, 0x41, 0x70, 0x70, 0x48, 0x65, 0x61, 0x6c, 0x74, + 0x68, 0x12, 0x1a, 0x0a, 0x16, 0x41, 0x50, 0x50, 0x5f, 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, 0x5f, + 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0c, 0x0a, + 0x08, 0x44, 0x49, 0x53, 0x41, 0x42, 0x4c, 0x45, 0x44, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x49, + 0x4e, 0x49, 0x54, 0x49, 0x41, 0x4c, 0x49, 0x5a, 0x49, 0x4e, 0x47, 0x10, 0x02, 0x12, 0x0b, 0x0a, + 0x07, 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, 0x59, 0x10, 0x03, 0x12, 0x0d, 0x0a, 0x09, 0x55, 0x4e, + 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, 0x59, 0x10, 0x04, 0x32, 0xef, 0x07, 0x0a, 0x05, 0x41, 0x67, + 0x65, 0x6e, 0x74, 0x12, 0x4b, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, + 0x73, 0x74, 0x12, 0x22, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, + 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, + 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, + 0x12, 0x5a, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x42, 0x61, + 0x6e, 0x6e, 0x65, 0x72, 0x12, 0x27, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, + 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, + 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x53, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x12, 0x56, 0x0a, 0x0b, + 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x22, 0x2e, 0x63, 0x6f, + 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x23, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, + 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x54, 0x0a, 0x0f, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4c, 0x69, + 0x66, 0x65, 0x63, 0x79, 0x63, 0x6c, 0x65, 0x12, 0x26, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, + 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4c, + 0x69, 0x66, 0x65, 0x63, 0x79, 0x63, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x19, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, + 0x2e, 0x4c, 0x69, 0x66, 0x65, 0x63, 0x79, 0x63, 0x6c, 0x65, 0x12, 0x72, 0x0a, 0x15, 0x42, 0x61, + 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x70, 0x70, 0x48, 0x65, 0x61, 0x6c, + 0x74, 0x68, 0x73, 0x12, 0x2b, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x2b, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, - 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x74, 0x61, - 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x62, 0x0a, 0x0f, - 0x42, 0x61, 0x74, 0x63, 0x68, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4c, 0x6f, 0x67, 0x73, 0x12, - 0x26, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, - 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4c, 0x6f, 0x67, 0x73, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, - 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x43, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x77, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x41, 0x6e, 0x6e, 0x6f, 0x75, 0x6e, 0x63, 0x65, 0x6d, - 0x65, 0x6e, 0x74, 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x73, 0x12, 0x2d, 0x2e, 0x63, 0x6f, 0x64, - 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x41, - 0x6e, 0x6e, 0x6f, 0x75, 0x6e, 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x61, 0x6e, 0x6e, 0x65, - 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x63, 0x6f, 0x64, 0x65, - 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x6e, - 0x6e, 0x6f, 0x75, 0x6e, 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, - 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7e, 0x0a, 0x0f, 0x53, 0x63, 0x72, - 0x69, 0x70, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x12, 0x34, 0x2e, 0x63, - 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x57, 0x6f, - 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x53, 0x63, 0x72, 0x69, - 0x70, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x35, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, - 0x2e, 0x76, 0x32, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x41, 0x67, 0x65, - 0x6e, 0x74, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, - 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x27, 0x5a, 0x25, 0x67, 0x69, 0x74, - 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2f, 0x63, 0x6f, - 0x64, 0x65, 0x72, 0x2f, 0x76, 0x32, 0x2f, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2f, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x41, 0x70, 0x70, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x2c, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, + 0x32, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x70, 0x70, + 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4e, + 0x0a, 0x0d, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x12, + 0x24, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, + 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, + 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x12, 0x6e, + 0x0a, 0x13, 0x42, 0x61, 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x2a, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, + 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x2b, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, + 0x76, 0x32, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x62, + 0x0a, 0x0f, 0x42, 0x61, 0x74, 0x63, 0x68, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4c, 0x6f, 0x67, + 0x73, 0x12, 0x26, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, + 0x76, 0x32, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4c, 0x6f, + 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x63, 0x6f, 0x64, 0x65, + 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, + 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x77, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x41, 0x6e, 0x6e, 0x6f, 0x75, 0x6e, 0x63, + 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x73, 0x12, 0x2d, 0x2e, 0x63, + 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, + 0x74, 0x41, 0x6e, 0x6e, 0x6f, 0x75, 0x6e, 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x61, 0x6e, + 0x6e, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x63, 0x6f, + 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, + 0x41, 0x6e, 0x6e, 0x6f, 0x75, 0x6e, 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x61, 0x6e, 0x6e, + 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7e, 0x0a, 0x0f, 0x53, + 0x63, 0x72, 0x69, 0x70, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x12, 0x34, + 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, + 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x53, 0x63, + 0x72, 0x69, 0x70, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x35, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, + 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x41, + 0x67, 0x65, 0x6e, 0x74, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, + 0x74, 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x27, 0x5a, 0x25, 0x67, + 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2f, + 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2f, 0x76, 0x32, 0x2f, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2f, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -3079,7 +3131,7 @@ func file_agent_proto_agent_proto_rawDescGZIP() []byte { return file_agent_proto_agent_proto_rawDescData } -var file_agent_proto_agent_proto_enumTypes = make([]protoimpl.EnumInfo, 7) +var file_agent_proto_agent_proto_enumTypes = make([]protoimpl.EnumInfo, 8) var file_agent_proto_agent_proto_msgTypes = make([]protoimpl.MessageInfo, 36) var file_agent_proto_agent_proto_goTypes = []interface{}{ (AppHealth)(0), // 0: coder.agent.v2.AppHealth @@ -3089,109 +3141,111 @@ var file_agent_proto_agent_proto_goTypes = []interface{}{ (Lifecycle_State)(0), // 4: coder.agent.v2.Lifecycle.State (Startup_Subsystem)(0), // 5: coder.agent.v2.Startup.Subsystem (Log_Level)(0), // 6: coder.agent.v2.Log.Level - (*WorkspaceApp)(nil), // 7: coder.agent.v2.WorkspaceApp - (*WorkspaceAgentScript)(nil), // 8: coder.agent.v2.WorkspaceAgentScript - (*WorkspaceAgentMetadata)(nil), // 9: coder.agent.v2.WorkspaceAgentMetadata - (*Manifest)(nil), // 10: coder.agent.v2.Manifest - (*GetManifestRequest)(nil), // 11: coder.agent.v2.GetManifestRequest - (*ServiceBanner)(nil), // 12: coder.agent.v2.ServiceBanner - (*GetServiceBannerRequest)(nil), // 13: coder.agent.v2.GetServiceBannerRequest - (*Stats)(nil), // 14: coder.agent.v2.Stats - (*UpdateStatsRequest)(nil), // 15: coder.agent.v2.UpdateStatsRequest - (*UpdateStatsResponse)(nil), // 16: coder.agent.v2.UpdateStatsResponse - (*Lifecycle)(nil), // 17: coder.agent.v2.Lifecycle - (*UpdateLifecycleRequest)(nil), // 18: coder.agent.v2.UpdateLifecycleRequest - (*BatchUpdateAppHealthRequest)(nil), // 19: coder.agent.v2.BatchUpdateAppHealthRequest - (*BatchUpdateAppHealthResponse)(nil), // 20: coder.agent.v2.BatchUpdateAppHealthResponse - (*Startup)(nil), // 21: coder.agent.v2.Startup - (*UpdateStartupRequest)(nil), // 22: coder.agent.v2.UpdateStartupRequest - (*Metadata)(nil), // 23: coder.agent.v2.Metadata - (*BatchUpdateMetadataRequest)(nil), // 24: coder.agent.v2.BatchUpdateMetadataRequest - (*BatchUpdateMetadataResponse)(nil), // 25: coder.agent.v2.BatchUpdateMetadataResponse - (*Log)(nil), // 26: coder.agent.v2.Log - (*BatchCreateLogsRequest)(nil), // 27: coder.agent.v2.BatchCreateLogsRequest - (*BatchCreateLogsResponse)(nil), // 28: coder.agent.v2.BatchCreateLogsResponse - (*GetAnnouncementBannersRequest)(nil), // 29: coder.agent.v2.GetAnnouncementBannersRequest - (*GetAnnouncementBannersResponse)(nil), // 30: coder.agent.v2.GetAnnouncementBannersResponse - (*BannerConfig)(nil), // 31: coder.agent.v2.BannerConfig - (*WorkspaceAgentScriptCompletedRequest)(nil), // 32: coder.agent.v2.WorkspaceAgentScriptCompletedRequest - (*WorkspaceAgentScriptCompletedResponse)(nil), // 33: coder.agent.v2.WorkspaceAgentScriptCompletedResponse - (*Timing)(nil), // 34: coder.agent.v2.Timing - (*WorkspaceApp_Healthcheck)(nil), // 35: coder.agent.v2.WorkspaceApp.Healthcheck - (*WorkspaceAgentMetadata_Result)(nil), // 36: coder.agent.v2.WorkspaceAgentMetadata.Result - (*WorkspaceAgentMetadata_Description)(nil), // 37: coder.agent.v2.WorkspaceAgentMetadata.Description - nil, // 38: coder.agent.v2.Manifest.EnvironmentVariablesEntry - nil, // 39: coder.agent.v2.Stats.ConnectionsByProtoEntry - (*Stats_Metric)(nil), // 40: coder.agent.v2.Stats.Metric - (*Stats_Metric_Label)(nil), // 41: coder.agent.v2.Stats.Metric.Label - (*BatchUpdateAppHealthRequest_HealthUpdate)(nil), // 42: coder.agent.v2.BatchUpdateAppHealthRequest.HealthUpdate - (*durationpb.Duration)(nil), // 43: google.protobuf.Duration - (*proto.DERPMap)(nil), // 44: coder.tailnet.v2.DERPMap - (*timestamppb.Timestamp)(nil), // 45: google.protobuf.Timestamp + (Timing_Stage)(0), // 7: coder.agent.v2.Timing.Stage + (*WorkspaceApp)(nil), // 8: coder.agent.v2.WorkspaceApp + (*WorkspaceAgentScript)(nil), // 9: coder.agent.v2.WorkspaceAgentScript + (*WorkspaceAgentMetadata)(nil), // 10: coder.agent.v2.WorkspaceAgentMetadata + (*Manifest)(nil), // 11: coder.agent.v2.Manifest + (*GetManifestRequest)(nil), // 12: coder.agent.v2.GetManifestRequest + (*ServiceBanner)(nil), // 13: coder.agent.v2.ServiceBanner + (*GetServiceBannerRequest)(nil), // 14: coder.agent.v2.GetServiceBannerRequest + (*Stats)(nil), // 15: coder.agent.v2.Stats + (*UpdateStatsRequest)(nil), // 16: coder.agent.v2.UpdateStatsRequest + (*UpdateStatsResponse)(nil), // 17: coder.agent.v2.UpdateStatsResponse + (*Lifecycle)(nil), // 18: coder.agent.v2.Lifecycle + (*UpdateLifecycleRequest)(nil), // 19: coder.agent.v2.UpdateLifecycleRequest + (*BatchUpdateAppHealthRequest)(nil), // 20: coder.agent.v2.BatchUpdateAppHealthRequest + (*BatchUpdateAppHealthResponse)(nil), // 21: coder.agent.v2.BatchUpdateAppHealthResponse + (*Startup)(nil), // 22: coder.agent.v2.Startup + (*UpdateStartupRequest)(nil), // 23: coder.agent.v2.UpdateStartupRequest + (*Metadata)(nil), // 24: coder.agent.v2.Metadata + (*BatchUpdateMetadataRequest)(nil), // 25: coder.agent.v2.BatchUpdateMetadataRequest + (*BatchUpdateMetadataResponse)(nil), // 26: coder.agent.v2.BatchUpdateMetadataResponse + (*Log)(nil), // 27: coder.agent.v2.Log + (*BatchCreateLogsRequest)(nil), // 28: coder.agent.v2.BatchCreateLogsRequest + (*BatchCreateLogsResponse)(nil), // 29: coder.agent.v2.BatchCreateLogsResponse + (*GetAnnouncementBannersRequest)(nil), // 30: coder.agent.v2.GetAnnouncementBannersRequest + (*GetAnnouncementBannersResponse)(nil), // 31: coder.agent.v2.GetAnnouncementBannersResponse + (*BannerConfig)(nil), // 32: coder.agent.v2.BannerConfig + (*WorkspaceAgentScriptCompletedRequest)(nil), // 33: coder.agent.v2.WorkspaceAgentScriptCompletedRequest + (*WorkspaceAgentScriptCompletedResponse)(nil), // 34: coder.agent.v2.WorkspaceAgentScriptCompletedResponse + (*Timing)(nil), // 35: coder.agent.v2.Timing + (*WorkspaceApp_Healthcheck)(nil), // 36: coder.agent.v2.WorkspaceApp.Healthcheck + (*WorkspaceAgentMetadata_Result)(nil), // 37: coder.agent.v2.WorkspaceAgentMetadata.Result + (*WorkspaceAgentMetadata_Description)(nil), // 38: coder.agent.v2.WorkspaceAgentMetadata.Description + nil, // 39: coder.agent.v2.Manifest.EnvironmentVariablesEntry + nil, // 40: coder.agent.v2.Stats.ConnectionsByProtoEntry + (*Stats_Metric)(nil), // 41: coder.agent.v2.Stats.Metric + (*Stats_Metric_Label)(nil), // 42: coder.agent.v2.Stats.Metric.Label + (*BatchUpdateAppHealthRequest_HealthUpdate)(nil), // 43: coder.agent.v2.BatchUpdateAppHealthRequest.HealthUpdate + (*durationpb.Duration)(nil), // 44: google.protobuf.Duration + (*proto.DERPMap)(nil), // 45: coder.tailnet.v2.DERPMap + (*timestamppb.Timestamp)(nil), // 46: google.protobuf.Timestamp } var file_agent_proto_agent_proto_depIdxs = []int32{ 1, // 0: coder.agent.v2.WorkspaceApp.sharing_level:type_name -> coder.agent.v2.WorkspaceApp.SharingLevel - 35, // 1: coder.agent.v2.WorkspaceApp.healthcheck:type_name -> coder.agent.v2.WorkspaceApp.Healthcheck + 36, // 1: coder.agent.v2.WorkspaceApp.healthcheck:type_name -> coder.agent.v2.WorkspaceApp.Healthcheck 2, // 2: coder.agent.v2.WorkspaceApp.health:type_name -> coder.agent.v2.WorkspaceApp.Health - 43, // 3: coder.agent.v2.WorkspaceAgentScript.timeout:type_name -> google.protobuf.Duration - 36, // 4: coder.agent.v2.WorkspaceAgentMetadata.result:type_name -> coder.agent.v2.WorkspaceAgentMetadata.Result - 37, // 5: coder.agent.v2.WorkspaceAgentMetadata.description:type_name -> coder.agent.v2.WorkspaceAgentMetadata.Description - 38, // 6: coder.agent.v2.Manifest.environment_variables:type_name -> coder.agent.v2.Manifest.EnvironmentVariablesEntry - 44, // 7: coder.agent.v2.Manifest.derp_map:type_name -> coder.tailnet.v2.DERPMap - 8, // 8: coder.agent.v2.Manifest.scripts:type_name -> coder.agent.v2.WorkspaceAgentScript - 7, // 9: coder.agent.v2.Manifest.apps:type_name -> coder.agent.v2.WorkspaceApp - 37, // 10: coder.agent.v2.Manifest.metadata:type_name -> coder.agent.v2.WorkspaceAgentMetadata.Description - 39, // 11: coder.agent.v2.Stats.connections_by_proto:type_name -> coder.agent.v2.Stats.ConnectionsByProtoEntry - 40, // 12: coder.agent.v2.Stats.metrics:type_name -> coder.agent.v2.Stats.Metric - 14, // 13: coder.agent.v2.UpdateStatsRequest.stats:type_name -> coder.agent.v2.Stats - 43, // 14: coder.agent.v2.UpdateStatsResponse.report_interval:type_name -> google.protobuf.Duration + 44, // 3: coder.agent.v2.WorkspaceAgentScript.timeout:type_name -> google.protobuf.Duration + 37, // 4: coder.agent.v2.WorkspaceAgentMetadata.result:type_name -> coder.agent.v2.WorkspaceAgentMetadata.Result + 38, // 5: coder.agent.v2.WorkspaceAgentMetadata.description:type_name -> coder.agent.v2.WorkspaceAgentMetadata.Description + 39, // 6: coder.agent.v2.Manifest.environment_variables:type_name -> coder.agent.v2.Manifest.EnvironmentVariablesEntry + 45, // 7: coder.agent.v2.Manifest.derp_map:type_name -> coder.tailnet.v2.DERPMap + 9, // 8: coder.agent.v2.Manifest.scripts:type_name -> coder.agent.v2.WorkspaceAgentScript + 8, // 9: coder.agent.v2.Manifest.apps:type_name -> coder.agent.v2.WorkspaceApp + 38, // 10: coder.agent.v2.Manifest.metadata:type_name -> coder.agent.v2.WorkspaceAgentMetadata.Description + 40, // 11: coder.agent.v2.Stats.connections_by_proto:type_name -> coder.agent.v2.Stats.ConnectionsByProtoEntry + 41, // 12: coder.agent.v2.Stats.metrics:type_name -> coder.agent.v2.Stats.Metric + 15, // 13: coder.agent.v2.UpdateStatsRequest.stats:type_name -> coder.agent.v2.Stats + 44, // 14: coder.agent.v2.UpdateStatsResponse.report_interval:type_name -> google.protobuf.Duration 4, // 15: coder.agent.v2.Lifecycle.state:type_name -> coder.agent.v2.Lifecycle.State - 45, // 16: coder.agent.v2.Lifecycle.changed_at:type_name -> google.protobuf.Timestamp - 17, // 17: coder.agent.v2.UpdateLifecycleRequest.lifecycle:type_name -> coder.agent.v2.Lifecycle - 42, // 18: coder.agent.v2.BatchUpdateAppHealthRequest.updates:type_name -> coder.agent.v2.BatchUpdateAppHealthRequest.HealthUpdate + 46, // 16: coder.agent.v2.Lifecycle.changed_at:type_name -> google.protobuf.Timestamp + 18, // 17: coder.agent.v2.UpdateLifecycleRequest.lifecycle:type_name -> coder.agent.v2.Lifecycle + 43, // 18: coder.agent.v2.BatchUpdateAppHealthRequest.updates:type_name -> coder.agent.v2.BatchUpdateAppHealthRequest.HealthUpdate 5, // 19: coder.agent.v2.Startup.subsystems:type_name -> coder.agent.v2.Startup.Subsystem - 21, // 20: coder.agent.v2.UpdateStartupRequest.startup:type_name -> coder.agent.v2.Startup - 36, // 21: coder.agent.v2.Metadata.result:type_name -> coder.agent.v2.WorkspaceAgentMetadata.Result - 23, // 22: coder.agent.v2.BatchUpdateMetadataRequest.metadata:type_name -> coder.agent.v2.Metadata - 45, // 23: coder.agent.v2.Log.created_at:type_name -> google.protobuf.Timestamp + 22, // 20: coder.agent.v2.UpdateStartupRequest.startup:type_name -> coder.agent.v2.Startup + 37, // 21: coder.agent.v2.Metadata.result:type_name -> coder.agent.v2.WorkspaceAgentMetadata.Result + 24, // 22: coder.agent.v2.BatchUpdateMetadataRequest.metadata:type_name -> coder.agent.v2.Metadata + 46, // 23: coder.agent.v2.Log.created_at:type_name -> google.protobuf.Timestamp 6, // 24: coder.agent.v2.Log.level:type_name -> coder.agent.v2.Log.Level - 26, // 25: coder.agent.v2.BatchCreateLogsRequest.logs:type_name -> coder.agent.v2.Log - 31, // 26: coder.agent.v2.GetAnnouncementBannersResponse.announcement_banners:type_name -> coder.agent.v2.BannerConfig - 34, // 27: coder.agent.v2.WorkspaceAgentScriptCompletedRequest.timing:type_name -> coder.agent.v2.Timing - 45, // 28: coder.agent.v2.Timing.start:type_name -> google.protobuf.Timestamp - 45, // 29: coder.agent.v2.Timing.end:type_name -> google.protobuf.Timestamp - 43, // 30: coder.agent.v2.WorkspaceApp.Healthcheck.interval:type_name -> google.protobuf.Duration - 45, // 31: coder.agent.v2.WorkspaceAgentMetadata.Result.collected_at:type_name -> google.protobuf.Timestamp - 43, // 32: coder.agent.v2.WorkspaceAgentMetadata.Description.interval:type_name -> google.protobuf.Duration - 43, // 33: coder.agent.v2.WorkspaceAgentMetadata.Description.timeout:type_name -> google.protobuf.Duration - 3, // 34: coder.agent.v2.Stats.Metric.type:type_name -> coder.agent.v2.Stats.Metric.Type - 41, // 35: coder.agent.v2.Stats.Metric.labels:type_name -> coder.agent.v2.Stats.Metric.Label - 0, // 36: coder.agent.v2.BatchUpdateAppHealthRequest.HealthUpdate.health:type_name -> coder.agent.v2.AppHealth - 11, // 37: coder.agent.v2.Agent.GetManifest:input_type -> coder.agent.v2.GetManifestRequest - 13, // 38: coder.agent.v2.Agent.GetServiceBanner:input_type -> coder.agent.v2.GetServiceBannerRequest - 15, // 39: coder.agent.v2.Agent.UpdateStats:input_type -> coder.agent.v2.UpdateStatsRequest - 18, // 40: coder.agent.v2.Agent.UpdateLifecycle:input_type -> coder.agent.v2.UpdateLifecycleRequest - 19, // 41: coder.agent.v2.Agent.BatchUpdateAppHealths:input_type -> coder.agent.v2.BatchUpdateAppHealthRequest - 22, // 42: coder.agent.v2.Agent.UpdateStartup:input_type -> coder.agent.v2.UpdateStartupRequest - 24, // 43: coder.agent.v2.Agent.BatchUpdateMetadata:input_type -> coder.agent.v2.BatchUpdateMetadataRequest - 27, // 44: coder.agent.v2.Agent.BatchCreateLogs:input_type -> coder.agent.v2.BatchCreateLogsRequest - 29, // 45: coder.agent.v2.Agent.GetAnnouncementBanners:input_type -> coder.agent.v2.GetAnnouncementBannersRequest - 32, // 46: coder.agent.v2.Agent.ScriptCompleted:input_type -> coder.agent.v2.WorkspaceAgentScriptCompletedRequest - 10, // 47: coder.agent.v2.Agent.GetManifest:output_type -> coder.agent.v2.Manifest - 12, // 48: coder.agent.v2.Agent.GetServiceBanner:output_type -> coder.agent.v2.ServiceBanner - 16, // 49: coder.agent.v2.Agent.UpdateStats:output_type -> coder.agent.v2.UpdateStatsResponse - 17, // 50: coder.agent.v2.Agent.UpdateLifecycle:output_type -> coder.agent.v2.Lifecycle - 20, // 51: coder.agent.v2.Agent.BatchUpdateAppHealths:output_type -> coder.agent.v2.BatchUpdateAppHealthResponse - 21, // 52: coder.agent.v2.Agent.UpdateStartup:output_type -> coder.agent.v2.Startup - 25, // 53: coder.agent.v2.Agent.BatchUpdateMetadata:output_type -> coder.agent.v2.BatchUpdateMetadataResponse - 28, // 54: coder.agent.v2.Agent.BatchCreateLogs:output_type -> coder.agent.v2.BatchCreateLogsResponse - 30, // 55: coder.agent.v2.Agent.GetAnnouncementBanners:output_type -> coder.agent.v2.GetAnnouncementBannersResponse - 33, // 56: coder.agent.v2.Agent.ScriptCompleted:output_type -> coder.agent.v2.WorkspaceAgentScriptCompletedResponse - 47, // [47:57] is the sub-list for method output_type - 37, // [37:47] is the sub-list for method input_type - 37, // [37:37] is the sub-list for extension type_name - 37, // [37:37] is the sub-list for extension extendee - 0, // [0:37] is the sub-list for field type_name + 27, // 25: coder.agent.v2.BatchCreateLogsRequest.logs:type_name -> coder.agent.v2.Log + 32, // 26: coder.agent.v2.GetAnnouncementBannersResponse.announcement_banners:type_name -> coder.agent.v2.BannerConfig + 35, // 27: coder.agent.v2.WorkspaceAgentScriptCompletedRequest.timing:type_name -> coder.agent.v2.Timing + 46, // 28: coder.agent.v2.Timing.start:type_name -> google.protobuf.Timestamp + 46, // 29: coder.agent.v2.Timing.end:type_name -> google.protobuf.Timestamp + 7, // 30: coder.agent.v2.Timing.stage:type_name -> coder.agent.v2.Timing.Stage + 44, // 31: coder.agent.v2.WorkspaceApp.Healthcheck.interval:type_name -> google.protobuf.Duration + 46, // 32: coder.agent.v2.WorkspaceAgentMetadata.Result.collected_at:type_name -> google.protobuf.Timestamp + 44, // 33: coder.agent.v2.WorkspaceAgentMetadata.Description.interval:type_name -> google.protobuf.Duration + 44, // 34: coder.agent.v2.WorkspaceAgentMetadata.Description.timeout:type_name -> google.protobuf.Duration + 3, // 35: coder.agent.v2.Stats.Metric.type:type_name -> coder.agent.v2.Stats.Metric.Type + 42, // 36: coder.agent.v2.Stats.Metric.labels:type_name -> coder.agent.v2.Stats.Metric.Label + 0, // 37: coder.agent.v2.BatchUpdateAppHealthRequest.HealthUpdate.health:type_name -> coder.agent.v2.AppHealth + 12, // 38: coder.agent.v2.Agent.GetManifest:input_type -> coder.agent.v2.GetManifestRequest + 14, // 39: coder.agent.v2.Agent.GetServiceBanner:input_type -> coder.agent.v2.GetServiceBannerRequest + 16, // 40: coder.agent.v2.Agent.UpdateStats:input_type -> coder.agent.v2.UpdateStatsRequest + 19, // 41: coder.agent.v2.Agent.UpdateLifecycle:input_type -> coder.agent.v2.UpdateLifecycleRequest + 20, // 42: coder.agent.v2.Agent.BatchUpdateAppHealths:input_type -> coder.agent.v2.BatchUpdateAppHealthRequest + 23, // 43: coder.agent.v2.Agent.UpdateStartup:input_type -> coder.agent.v2.UpdateStartupRequest + 25, // 44: coder.agent.v2.Agent.BatchUpdateMetadata:input_type -> coder.agent.v2.BatchUpdateMetadataRequest + 28, // 45: coder.agent.v2.Agent.BatchCreateLogs:input_type -> coder.agent.v2.BatchCreateLogsRequest + 30, // 46: coder.agent.v2.Agent.GetAnnouncementBanners:input_type -> coder.agent.v2.GetAnnouncementBannersRequest + 33, // 47: coder.agent.v2.Agent.ScriptCompleted:input_type -> coder.agent.v2.WorkspaceAgentScriptCompletedRequest + 11, // 48: coder.agent.v2.Agent.GetManifest:output_type -> coder.agent.v2.Manifest + 13, // 49: coder.agent.v2.Agent.GetServiceBanner:output_type -> coder.agent.v2.ServiceBanner + 17, // 50: coder.agent.v2.Agent.UpdateStats:output_type -> coder.agent.v2.UpdateStatsResponse + 18, // 51: coder.agent.v2.Agent.UpdateLifecycle:output_type -> coder.agent.v2.Lifecycle + 21, // 52: coder.agent.v2.Agent.BatchUpdateAppHealths:output_type -> coder.agent.v2.BatchUpdateAppHealthResponse + 22, // 53: coder.agent.v2.Agent.UpdateStartup:output_type -> coder.agent.v2.Startup + 26, // 54: coder.agent.v2.Agent.BatchUpdateMetadata:output_type -> coder.agent.v2.BatchUpdateMetadataResponse + 29, // 55: coder.agent.v2.Agent.BatchCreateLogs:output_type -> coder.agent.v2.BatchCreateLogsResponse + 31, // 56: coder.agent.v2.Agent.GetAnnouncementBanners:output_type -> coder.agent.v2.GetAnnouncementBannersResponse + 34, // 57: coder.agent.v2.Agent.ScriptCompleted:output_type -> coder.agent.v2.WorkspaceAgentScriptCompletedResponse + 48, // [48:58] is the sub-list for method output_type + 38, // [38:48] is the sub-list for method input_type + 38, // [38:38] is the sub-list for extension type_name + 38, // [38:38] is the sub-list for extension extendee + 0, // [0:38] is the sub-list for field type_name } func init() { file_agent_proto_agent_proto_init() } @@ -3614,7 +3668,7 @@ func file_agent_proto_agent_proto_init() { File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_agent_proto_agent_proto_rawDesc, - NumEnums: 7, + NumEnums: 8, NumMessages: 36, NumExtensions: 0, NumServices: 1, diff --git a/agent/proto/agent.proto b/agent/proto/agent.proto index c26df0eaa6f4e..cab148b96a2ba 100644 --- a/agent/proto/agent.proto +++ b/agent/proto/agent.proto @@ -274,13 +274,19 @@ message WorkspaceAgentScriptCompletedResponse { } message Timing { - string display_name = 1; - google.protobuf.Timestamp start = 2; - google.protobuf.Timestamp end = 3; - int32 exit_code = 4; - bool ran_on_start = 5; - bool blocked_login = 6; - bytes script_id = 7; + bytes script_id = 1; + string display_name = 2; + google.protobuf.Timestamp start = 3; + google.protobuf.Timestamp end = 4; + int32 exit_code = 5; + + enum Stage { + START = 0; + STOP = 1; + CRON = 2; + } + Stage stage = 6; + bool timed_out = 7; } service Agent { diff --git a/coderd/agentapi/scripts.go b/coderd/agentapi/scripts.go index 6f866dbb7a32b..504ed18d3495a 100644 --- a/coderd/agentapi/scripts.go +++ b/coderd/agentapi/scripts.go @@ -23,14 +23,24 @@ func (s *ScriptsAPI) ScriptCompleted(ctx context.Context, req *agentproto.Worksp return nil, xerrors.Errorf("script id from bytes: %w", err) } + var stage database.WorkspaceAgentScriptTimingStage + switch req.Timing.Stage { + case agentproto.Timing_START: + stage = database.WorkspaceAgentScriptTimingStageStart + case agentproto.Timing_STOP: + stage = database.WorkspaceAgentScriptTimingStageStop + case agentproto.Timing_CRON: + stage = database.WorkspaceAgentScriptTimingStageCron + } + _, err = s.Database.InsertWorkspaceAgentScriptTimings(ctx, database.InsertWorkspaceAgentScriptTimingsParams{ - ScriptID: scriptID, - DisplayName: req.Timing.DisplayName, - StartedAt: req.Timing.Start.AsTime(), - EndedAt: req.Timing.End.AsTime(), - ExitCode: req.Timing.ExitCode, - RanOnStart: req.Timing.RanOnStart, - BlockedLogin: req.Timing.BlockedLogin, + ScriptID: scriptID, + Stage: stage, + DisplayName: req.Timing.DisplayName, + StartedAt: req.Timing.Start.AsTime(), + EndedAt: req.Timing.End.AsTime(), + ExitCode: req.Timing.ExitCode, + TimedOut: req.Timing.TimedOut, }) if err != nil { return nil, xerrors.Errorf("insert workspace agent script timings into database: %w", err) diff --git a/coderd/database/dbauthz/dbauthz_test.go b/coderd/database/dbauthz/dbauthz_test.go index 023298b4c5482..b6605a08bfd51 100644 --- a/coderd/database/dbauthz/dbauthz_test.go +++ b/coderd/database/dbauthz/dbauthz_test.go @@ -2635,6 +2635,7 @@ func (s *MethodTestSuite) TestSystemFunctions() { s.Run("InsertWorkspaceAgentScriptTimings", s.Subtest(func(db database.Store, check *expects) { check.Args(database.InsertWorkspaceAgentScriptTimingsParams{ ScriptID: uuid.New(), + Stage: database.WorkspaceAgentScriptTimingStageStart, }).Asserts( /* rbac.ResourceSystem, policy.ActionCreate */ ) })) s.Run("InsertWorkspaceAgentScripts", s.Subtest(func(db database.Store, check *expects) { diff --git a/coderd/database/dbmem/dbmem.go b/coderd/database/dbmem/dbmem.go index 8a8bfeb9946e0..5e95732cf1ff1 100644 --- a/coderd/database/dbmem/dbmem.go +++ b/coderd/database/dbmem/dbmem.go @@ -7838,13 +7838,13 @@ func (q *FakeQuerier) InsertWorkspaceAgentScriptTimings(_ context.Context, arg d //nolint:gosimple // Stop linter suggesting 'arg' should be of type database.WorkspaceAgentScriptTiming scriptTiming := database.WorkspaceAgentScriptTiming{ - ScriptID: arg.ScriptID, - StartedAt: arg.StartedAt, - EndedAt: arg.EndedAt, - ExitCode: arg.ExitCode, - DisplayName: arg.DisplayName, - RanOnStart: arg.RanOnStart, - BlockedLogin: arg.BlockedLogin, + ScriptID: arg.ScriptID, + StartedAt: arg.StartedAt, + EndedAt: arg.EndedAt, + ExitCode: arg.ExitCode, + DisplayName: arg.DisplayName, + Stage: arg.Stage, + TimedOut: arg.TimedOut, } q.workspaceAgentScriptTimings = append(q.workspaceAgentScriptTimings, scriptTiming) diff --git a/coderd/database/dump.sql b/coderd/database/dump.sql index 00664becf20d4..eb87e0e0cb749 100644 --- a/coderd/database/dump.sql +++ b/coderd/database/dump.sql @@ -216,6 +216,12 @@ CREATE TYPE workspace_agent_lifecycle_state AS ENUM ( 'off' ); +CREATE TYPE workspace_agent_script_timing_stage AS ENUM ( + 'start', + 'stop', + 'cron' +); + CREATE TYPE workspace_agent_subsystem AS ENUM ( 'envbuilder', 'envbox', @@ -1361,8 +1367,8 @@ CREATE TABLE workspace_agent_script_timings ( started_at timestamp with time zone NOT NULL, ended_at timestamp with time zone NOT NULL, exit_code integer NOT NULL, - ran_on_start boolean NOT NULL, - blocked_login boolean NOT NULL + stage workspace_agent_script_timing_stage NOT NULL, + timed_out boolean NOT NULL ); CREATE TABLE workspace_agent_scripts ( diff --git a/coderd/database/migrations/000255_workspace_agent_script_timings.down.sql b/coderd/database/migrations/000255_workspace_agent_script_timings.down.sql index 97f0f400a2616..364c56ab75c8d 100644 --- a/coderd/database/migrations/000255_workspace_agent_script_timings.down.sql +++ b/coderd/database/migrations/000255_workspace_agent_script_timings.down.sql @@ -1,3 +1,4 @@ +DROP TYPE IF EXISTS workspace_agent_script_timing_stage CASCADE; DROP TABLE IF EXISTS workspace_agent_script_timings; ALTER TABLE workspace_agent_scripts DROP COLUMN display_name; diff --git a/coderd/database/migrations/000255_workspace_agent_script_timings.up.sql b/coderd/database/migrations/000255_workspace_agent_script_timings.up.sql index 0938f2a8b8e70..b07aad30840c8 100644 --- a/coderd/database/migrations/000255_workspace_agent_script_timings.up.sql +++ b/coderd/database/migrations/000255_workspace_agent_script_timings.up.sql @@ -1,14 +1,19 @@ ALTER TABLE workspace_agent_scripts ADD COLUMN id uuid unique not null default gen_random_uuid(); +ALTER TABLE workspace_agent_scripts ADD COLUMN display_name text not null default ''; + +CREATE TYPE workspace_agent_script_timing_stage AS ENUM ( + 'start', + 'stop', + 'cron' + ); CREATE TABLE workspace_agent_script_timings ( - script_id uuid not null references workspace_agent_scripts (id) on delete cascade, - display_name text not null, - started_at timestamp with time zone not null, - ended_at timestamp with time zone not null, - exit_code int not null, - ran_on_start bool not null, - blocked_login bool not null + script_id uuid not null references workspace_agent_scripts (id) on delete cascade, + display_name text not null, + started_at timestamp with time zone not null, + ended_at timestamp with time zone not null, + exit_code int not null, + stage workspace_agent_script_timing_stage not null, + timed_out bool not null ); - -ALTER TABLE workspace_agent_scripts ADD COLUMN display_name text not null default ''; diff --git a/coderd/database/migrations/testdata/fixtures/000255_workspace_agent_script_timings.up.sql b/coderd/database/migrations/testdata/fixtures/000255_workspace_agent_script_timings.up.sql index 9b0059ac28a53..4f75ea3abe3a8 100644 --- a/coderd/database/migrations/testdata/fixtures/000255_workspace_agent_script_timings.up.sql +++ b/coderd/database/migrations/testdata/fixtures/000255_workspace_agent_script_timings.up.sql @@ -1,3 +1,3 @@ -INSERT INTO workspace_agent_script_timings (script_id, display_name, started_at, ended_at, exit_code, ran_on_start, blocked_login) +INSERT INTO workspace_agent_script_timings (script_id, display_name, started_at, ended_at, exit_code, stage, timed_out) VALUES - ((SELECT id FROM workspace_agent_scripts LIMIT 1), 'Startup Script', NOW() - INTERVAL '1 hour 55 minutes', NOW() - INTERVAL '1 hour 50 minutes', 0, true, false); + ((SELECT id FROM workspace_agent_scripts LIMIT 1), 'Startup Script', NOW() - INTERVAL '1 hour 55 minutes', NOW() - INTERVAL '1 hour 50 minutes', 0, 'start', false); diff --git a/coderd/database/models.go b/coderd/database/models.go index 7744fc73ae2c9..ec29e0012a529 100644 --- a/coderd/database/models.go +++ b/coderd/database/models.go @@ -1881,6 +1881,67 @@ func AllWorkspaceAgentLifecycleStateValues() []WorkspaceAgentLifecycleState { } } +type WorkspaceAgentScriptTimingStage string + +const ( + WorkspaceAgentScriptTimingStageStart WorkspaceAgentScriptTimingStage = "start" + WorkspaceAgentScriptTimingStageStop WorkspaceAgentScriptTimingStage = "stop" + WorkspaceAgentScriptTimingStageCron WorkspaceAgentScriptTimingStage = "cron" +) + +func (e *WorkspaceAgentScriptTimingStage) Scan(src interface{}) error { + switch s := src.(type) { + case []byte: + *e = WorkspaceAgentScriptTimingStage(s) + case string: + *e = WorkspaceAgentScriptTimingStage(s) + default: + return fmt.Errorf("unsupported scan type for WorkspaceAgentScriptTimingStage: %T", src) + } + return nil +} + +type NullWorkspaceAgentScriptTimingStage struct { + WorkspaceAgentScriptTimingStage WorkspaceAgentScriptTimingStage `json:"workspace_agent_script_timing_stage"` + Valid bool `json:"valid"` // Valid is true if WorkspaceAgentScriptTimingStage is not NULL +} + +// Scan implements the Scanner interface. +func (ns *NullWorkspaceAgentScriptTimingStage) Scan(value interface{}) error { + if value == nil { + ns.WorkspaceAgentScriptTimingStage, ns.Valid = "", false + return nil + } + ns.Valid = true + return ns.WorkspaceAgentScriptTimingStage.Scan(value) +} + +// Value implements the driver Valuer interface. +func (ns NullWorkspaceAgentScriptTimingStage) Value() (driver.Value, error) { + if !ns.Valid { + return nil, nil + } + return string(ns.WorkspaceAgentScriptTimingStage), nil +} + +func (e WorkspaceAgentScriptTimingStage) Valid() bool { + switch e { + case WorkspaceAgentScriptTimingStageStart, + WorkspaceAgentScriptTimingStageStop, + WorkspaceAgentScriptTimingStageCron: + return true + } + return false +} + +func AllWorkspaceAgentScriptTimingStageValues() []WorkspaceAgentScriptTimingStage { + return []WorkspaceAgentScriptTimingStage{ + WorkspaceAgentScriptTimingStageStart, + WorkspaceAgentScriptTimingStageStop, + WorkspaceAgentScriptTimingStageCron, + } +} + type WorkspaceAgentSubsystem string const ( @@ -2885,13 +2946,13 @@ type WorkspaceAgentScript struct { } type WorkspaceAgentScriptTiming struct { - ScriptID uuid.UUID `db:"script_id" json:"script_id"` - DisplayName string `db:"display_name" json:"display_name"` - StartedAt time.Time `db:"started_at" json:"started_at"` - EndedAt time.Time `db:"ended_at" json:"ended_at"` - ExitCode int32 `db:"exit_code" json:"exit_code"` - RanOnStart bool `db:"ran_on_start" json:"ran_on_start"` - BlockedLogin bool `db:"blocked_login" json:"blocked_login"` + ScriptID uuid.UUID `db:"script_id" json:"script_id"` + DisplayName string `db:"display_name" json:"display_name"` + StartedAt time.Time `db:"started_at" json:"started_at"` + EndedAt time.Time `db:"ended_at" json:"ended_at"` + ExitCode int32 `db:"exit_code" json:"exit_code"` + Stage WorkspaceAgentScriptTimingStage `db:"stage" json:"stage"` + TimedOut bool `db:"timed_out" json:"timed_out"` } type WorkspaceAgentStat struct { diff --git a/coderd/database/queries.sql.go b/coderd/database/queries.sql.go index 4a7309bf0f24f..813e5e38b9abf 100644 --- a/coderd/database/queries.sql.go +++ b/coderd/database/queries.sql.go @@ -11810,21 +11810,21 @@ INSERT INTO started_at, ended_at, exit_code, - ran_on_start, - blocked_login + stage, + timed_out ) VALUES - ($1, $2, $3, $4, $5, $6, $7) RETURNING script_id, display_name, started_at, ended_at, exit_code, ran_on_start, blocked_login + ($1, $2, $3, $4, $5, $6, $7) RETURNING script_id, display_name, started_at, ended_at, exit_code, stage, timed_out ` type InsertWorkspaceAgentScriptTimingsParams struct { - ScriptID uuid.UUID `db:"script_id" json:"script_id"` - DisplayName string `db:"display_name" json:"display_name"` - StartedAt time.Time `db:"started_at" json:"started_at"` - EndedAt time.Time `db:"ended_at" json:"ended_at"` - ExitCode int32 `db:"exit_code" json:"exit_code"` - RanOnStart bool `db:"ran_on_start" json:"ran_on_start"` - BlockedLogin bool `db:"blocked_login" json:"blocked_login"` + ScriptID uuid.UUID `db:"script_id" json:"script_id"` + DisplayName string `db:"display_name" json:"display_name"` + StartedAt time.Time `db:"started_at" json:"started_at"` + EndedAt time.Time `db:"ended_at" json:"ended_at"` + ExitCode int32 `db:"exit_code" json:"exit_code"` + Stage WorkspaceAgentScriptTimingStage `db:"stage" json:"stage"` + TimedOut bool `db:"timed_out" json:"timed_out"` } func (q *sqlQuerier) InsertWorkspaceAgentScriptTimings(ctx context.Context, arg InsertWorkspaceAgentScriptTimingsParams) (WorkspaceAgentScriptTiming, error) { @@ -11834,8 +11834,8 @@ func (q *sqlQuerier) InsertWorkspaceAgentScriptTimings(ctx context.Context, arg arg.StartedAt, arg.EndedAt, arg.ExitCode, - arg.RanOnStart, - arg.BlockedLogin, + arg.Stage, + arg.TimedOut, ) var i WorkspaceAgentScriptTiming err := row.Scan( @@ -11844,8 +11844,8 @@ func (q *sqlQuerier) InsertWorkspaceAgentScriptTimings(ctx context.Context, arg &i.StartedAt, &i.EndedAt, &i.ExitCode, - &i.RanOnStart, - &i.BlockedLogin, + &i.Stage, + &i.TimedOut, ) return i, err } diff --git a/coderd/database/queries/workspaceagents.sql b/coderd/database/queries/workspaceagents.sql index 3de7531bfec2f..8c264c049494e 100644 --- a/coderd/database/queries/workspaceagents.sql +++ b/coderd/database/queries/workspaceagents.sql @@ -296,8 +296,8 @@ INSERT INTO started_at, ended_at, exit_code, - ran_on_start, - blocked_login + stage, + timed_out ) VALUES ($1, $2, $3, $4, $5, $6, $7) RETURNING *; From c20ac32e7a2b882949c120f5fc8f8e77a6408dae Mon Sep 17 00:00:00 2001 From: Danielle Maywood Date: Fri, 20 Sep 2024 08:40:40 +0000 Subject: [PATCH 32/56] fix: update migration number --- ...gs.down.sql => 000256_workspace_agent_script_timings.down.sql} | 0 ...imings.up.sql => 000256_workspace_agent_script_timings.up.sql} | 0 ...imings.up.sql => 000256_workspace_agent_script_timings.up.sql} | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename coderd/database/migrations/{000255_workspace_agent_script_timings.down.sql => 000256_workspace_agent_script_timings.down.sql} (100%) rename coderd/database/migrations/{000255_workspace_agent_script_timings.up.sql => 000256_workspace_agent_script_timings.up.sql} (100%) rename coderd/database/migrations/testdata/fixtures/{000255_workspace_agent_script_timings.up.sql => 000256_workspace_agent_script_timings.up.sql} (100%) diff --git a/coderd/database/migrations/000255_workspace_agent_script_timings.down.sql b/coderd/database/migrations/000256_workspace_agent_script_timings.down.sql similarity index 100% rename from coderd/database/migrations/000255_workspace_agent_script_timings.down.sql rename to coderd/database/migrations/000256_workspace_agent_script_timings.down.sql diff --git a/coderd/database/migrations/000255_workspace_agent_script_timings.up.sql b/coderd/database/migrations/000256_workspace_agent_script_timings.up.sql similarity index 100% rename from coderd/database/migrations/000255_workspace_agent_script_timings.up.sql rename to coderd/database/migrations/000256_workspace_agent_script_timings.up.sql diff --git a/coderd/database/migrations/testdata/fixtures/000255_workspace_agent_script_timings.up.sql b/coderd/database/migrations/testdata/fixtures/000256_workspace_agent_script_timings.up.sql similarity index 100% rename from coderd/database/migrations/testdata/fixtures/000255_workspace_agent_script_timings.up.sql rename to coderd/database/migrations/testdata/fixtures/000256_workspace_agent_script_timings.up.sql From c65213352f54e59c4dc92904f88fdb9a8f2f2412 Mon Sep 17 00:00:00 2001 From: Danielle Maywood Date: Fri, 20 Sep 2024 09:16:22 +0000 Subject: [PATCH 33/56] test: add test for script api --- coderd/agentapi/api.go | 1 - coderd/agentapi/scripts.go | 1 - coderd/agentapi/scripts_test.go | 116 ++++++++++++++++++++++++++++++++ 3 files changed, 116 insertions(+), 2 deletions(-) create mode 100644 coderd/agentapi/scripts_test.go diff --git a/coderd/agentapi/api.go b/coderd/agentapi/api.go index dca1ce96712bb..bea1fa5d881a3 100644 --- a/coderd/agentapi/api.go +++ b/coderd/agentapi/api.go @@ -154,7 +154,6 @@ func New(opts Options) *API { } api.ScriptsAPI = &ScriptsAPI{ - AgentID: opts.AgentID, Database: opts.Database, } diff --git a/coderd/agentapi/scripts.go b/coderd/agentapi/scripts.go index 504ed18d3495a..36185e8493e9c 100644 --- a/coderd/agentapi/scripts.go +++ b/coderd/agentapi/scripts.go @@ -11,7 +11,6 @@ import ( ) type ScriptsAPI struct { - AgentID uuid.UUID Database database.Store } diff --git a/coderd/agentapi/scripts_test.go b/coderd/agentapi/scripts_test.go new file mode 100644 index 0000000000000..5d2c6b6513004 --- /dev/null +++ b/coderd/agentapi/scripts_test.go @@ -0,0 +1,116 @@ +package agentapi_test + +import ( + "context" + "testing" + "time" + + "github.com/google/uuid" + "go.uber.org/mock/gomock" + "google.golang.org/protobuf/types/known/timestamppb" + + agentproto "github.com/coder/coder/v2/agent/proto" + "github.com/coder/coder/v2/coderd/agentapi" + "github.com/coder/coder/v2/coderd/database" + "github.com/coder/coder/v2/coderd/database/dbmock" + "github.com/coder/coder/v2/coderd/database/dbtime" +) + +func TestScriptCompleted(t *testing.T) { + t.Parallel() + + tests := []struct { + scriptID uuid.UUID + timing *agentproto.Timing + }{ + { + scriptID: uuid.New(), + timing: &agentproto.Timing{ + Stage: agentproto.Timing_START, + DisplayName: "Start Script", + Start: timestamppb.New(dbtime.Now()), + End: timestamppb.New(dbtime.Now().Add(time.Second)), + TimedOut: false, + ExitCode: 0, + }, + }, + { + scriptID: uuid.New(), + timing: &agentproto.Timing{ + Stage: agentproto.Timing_STOP, + DisplayName: "Stop Script", + Start: timestamppb.New(dbtime.Now()), + End: timestamppb.New(dbtime.Now().Add(time.Second)), + TimedOut: false, + ExitCode: 0, + }, + }, + { + scriptID: uuid.New(), + timing: &agentproto.Timing{ + Stage: agentproto.Timing_CRON, + DisplayName: "Cron Script", + Start: timestamppb.New(dbtime.Now()), + End: timestamppb.New(dbtime.Now().Add(time.Second)), + TimedOut: false, + ExitCode: 0, + }, + }, + { + scriptID: uuid.New(), + timing: &agentproto.Timing{ + Stage: agentproto.Timing_START, + DisplayName: "Timed Out Script", + Start: timestamppb.New(dbtime.Now()), + End: timestamppb.New(dbtime.Now().Add(time.Second)), + TimedOut: true, + ExitCode: 255, + }, + }, + { + scriptID: uuid.New(), + timing: &agentproto.Timing{ + Stage: agentproto.Timing_START, + DisplayName: "Failed Script", + Start: timestamppb.New(dbtime.Now()), + End: timestamppb.New(dbtime.Now().Add(time.Second)), + TimedOut: true, + ExitCode: 1, + }, + }, + } + + for _, tt := range tests { + // Setup the script ID + tt.timing.ScriptId = tt.scriptID[:] + + mDB := dbmock.NewMockStore(gomock.NewController(t)) + mDB.EXPECT().InsertWorkspaceAgentScriptTimings(gomock.Any(), database.InsertWorkspaceAgentScriptTimingsParams{ + ScriptID: tt.scriptID, + Stage: protoScriptTimingStageToDatabase(tt.timing.Stage), + DisplayName: tt.timing.DisplayName, + StartedAt: tt.timing.Start.AsTime(), + EndedAt: tt.timing.End.AsTime(), + TimedOut: tt.timing.TimedOut, + ExitCode: tt.timing.ExitCode, + }) + + api := &agentapi.ScriptsAPI{Database: mDB} + api.ScriptCompleted(context.Background(), &agentproto.WorkspaceAgentScriptCompletedRequest{ + Timing: tt.timing, + }) + } +} + +func protoScriptTimingStageToDatabase(stage agentproto.Timing_Stage) database.WorkspaceAgentScriptTimingStage { + var dbStage database.WorkspaceAgentScriptTimingStage + switch stage { + case agentproto.Timing_START: + dbStage = database.WorkspaceAgentScriptTimingStageStart + case agentproto.Timing_STOP: + dbStage = database.WorkspaceAgentScriptTimingStageStop + case agentproto.Timing_CRON: + dbStage = database.WorkspaceAgentScriptTimingStageCron + } + return dbStage +} From 1199b64684ff8571584feb23ca0916e36797fc4e Mon Sep 17 00:00:00 2001 From: Danielle Maywood Date: Fri, 20 Sep 2024 09:23:10 +0000 Subject: [PATCH 34/56] fix: fake db query --- coderd/database/dbmem/dbmem.go | 1 + 1 file changed, 1 insertion(+) diff --git a/coderd/database/dbmem/dbmem.go b/coderd/database/dbmem/dbmem.go index 5e95732cf1ff1..f52ddfd37352b 100644 --- a/coderd/database/dbmem/dbmem.go +++ b/coderd/database/dbmem/dbmem.go @@ -7866,6 +7866,7 @@ func (q *FakeQuerier) InsertWorkspaceAgentScripts(_ context.Context, arg databas script := database.WorkspaceAgentScript{ LogSourceID: source, WorkspaceAgentID: arg.WorkspaceAgentID, + ID: arg.ID[index], DisplayName: arg.DisplayName[index], LogPath: arg.LogPath[index], Script: arg.Script[index], From afa61ebc66ebd0b284d1574deb2684e8e4ac890a Mon Sep 17 00:00:00 2001 From: Danielle Maywood Date: Fri, 20 Sep 2024 10:13:12 +0000 Subject: [PATCH 35/56] fix: use UTC time --- agent/agentscripts/agentscripts.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/agent/agentscripts/agentscripts.go b/agent/agentscripts/agentscripts.go index f27c2da4b0df6..313d703b76755 100644 --- a/agent/agentscripts/agentscripts.go +++ b/agent/agentscripts/agentscripts.go @@ -314,9 +314,9 @@ func (r *Runner) run(ctx context.Context, script codersdk.WorkspaceAgentScript, cmd.Stdout = io.MultiWriter(fileWriter, infoW) cmd.Stderr = io.MultiWriter(fileWriter, errW) - start := time.Now() + start := time.Now().UTC() defer func() { - end := time.Now() + end := time.Now().UTC() execTime := end.Sub(start) exitCode := 0 if err != nil { From 8d325e27c808dca44f069bbb9ae41885f9a3f246 Mon Sep 17 00:00:00 2001 From: Danielle Maywood Date: Fri, 20 Sep 2024 10:15:47 +0000 Subject: [PATCH 36/56] fix: ensure r.scriptComplete is not nil --- agent/agentscripts/agentscripts.go | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/agent/agentscripts/agentscripts.go b/agent/agentscripts/agentscripts.go index 313d703b76755..9c902f1ceae30 100644 --- a/agent/agentscripts/agentscripts.go +++ b/agent/agentscripts/agentscripts.go @@ -340,20 +340,22 @@ func (r *Runner) run(ctx context.Context, script codersdk.WorkspaceAgentScript, stage = proto.Timing_CRON } - _, err = r.scriptCompleted(ctx, &proto.WorkspaceAgentScriptCompletedRequest{ - Timing: &proto.Timing{ - ScriptId: script.ID[:], - DisplayName: script.DisplayName, - Start: timestamppb.New(start), - End: timestamppb.New(end), - ExitCode: int32(exitCode), - Stage: stage, - TimedOut: errors.Is(err, ErrTimeout), - }, - }) + if r.scriptCompleted != nil { + _, err = r.scriptCompleted(ctx, &proto.WorkspaceAgentScriptCompletedRequest{ + Timing: &proto.Timing{ + ScriptId: script.ID[:], + DisplayName: script.DisplayName, + Start: timestamppb.New(start), + End: timestamppb.New(end), + ExitCode: int32(exitCode), + Stage: stage, + TimedOut: errors.Is(err, ErrTimeout), + }, + }) - if err != nil { - logger.Error(ctx, fmt.Sprintf("reporting script completed: %s", err.Error())) + if err != nil { + logger.Error(ctx, fmt.Sprintf("reporting script completed: %s", err.Error())) + } } }() From aeee582d83eda68782cf6ecf5e93ffb00890dd3a Mon Sep 17 00:00:00 2001 From: Danielle Maywood Date: Fri, 20 Sep 2024 10:16:24 +0000 Subject: [PATCH 37/56] fix: move err check to right after call --- agent/agentscripts/agentscripts.go | 1 - 1 file changed, 1 deletion(-) diff --git a/agent/agentscripts/agentscripts.go b/agent/agentscripts/agentscripts.go index 9c902f1ceae30..bfa438e275f23 100644 --- a/agent/agentscripts/agentscripts.go +++ b/agent/agentscripts/agentscripts.go @@ -352,7 +352,6 @@ func (r *Runner) run(ctx context.Context, script codersdk.WorkspaceAgentScript, TimedOut: errors.Is(err, ErrTimeout), }, }) - if err != nil { logger.Error(ctx, fmt.Sprintf("reporting script completed: %s", err.Error())) } From 424069cc732dbb56e018425ad90640fbfe77d3c5 Mon Sep 17 00:00:00 2001 From: Danielle Maywood Date: Fri, 20 Sep 2024 11:13:56 +0000 Subject: [PATCH 38/56] fix: uppercase sql --- ...00256_workspace_agent_script_timings.up.sql | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/coderd/database/migrations/000256_workspace_agent_script_timings.up.sql b/coderd/database/migrations/000256_workspace_agent_script_timings.up.sql index b07aad30840c8..58bbaadfdfc95 100644 --- a/coderd/database/migrations/000256_workspace_agent_script_timings.up.sql +++ b/coderd/database/migrations/000256_workspace_agent_script_timings.up.sql @@ -1,5 +1,5 @@ -ALTER TABLE workspace_agent_scripts ADD COLUMN id uuid unique not null default gen_random_uuid(); -ALTER TABLE workspace_agent_scripts ADD COLUMN display_name text not null default ''; +ALTER TABLE workspace_agent_scripts ADD COLUMN id uuid UNIQUE NOT NULL DEFAULT gen_random_uuid(); +ALTER TABLE workspace_agent_scripts ADD COLUMN display_name text NOT NULL DEFAULT ''; CREATE TYPE workspace_agent_script_timing_stage AS ENUM ( 'start', @@ -9,11 +9,11 @@ CREATE TYPE workspace_agent_script_timing_stage AS ENUM ( CREATE TABLE workspace_agent_script_timings ( - script_id uuid not null references workspace_agent_scripts (id) on delete cascade, - display_name text not null, - started_at timestamp with time zone not null, - ended_at timestamp with time zone not null, - exit_code int not null, - stage workspace_agent_script_timing_stage not null, - timed_out bool not null + script_id uuid NOT NULL REFERENCES workspace_agent_scripts (id) ON DELETE CASCADE, + display_name text NOT NULL, + started_at timestamp with time zone NOT NULL, + ended_at timestamp with time zone NOT NULL, + exit_code int NOT NULL, + stage workspace_agent_script_timing_stage NOT NULL, + timed_out bool NOT NULL ); From 9b43a94ce99ba3174e0ff9be87f86b92ae1aceb7 Mon Sep 17 00:00:00 2001 From: Danielle Maywood Date: Fri, 20 Sep 2024 11:14:25 +0000 Subject: [PATCH 39/56] fix: use dbtime.Now() --- agent/agentscripts/agentscripts.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/agent/agentscripts/agentscripts.go b/agent/agentscripts/agentscripts.go index bfa438e275f23..4c591e1e89a0b 100644 --- a/agent/agentscripts/agentscripts.go +++ b/agent/agentscripts/agentscripts.go @@ -25,6 +25,7 @@ import ( "github.com/coder/coder/v2/agent/agentssh" "github.com/coder/coder/v2/agent/proto" + "github.com/coder/coder/v2/coderd/database/dbtime" "github.com/coder/coder/v2/codersdk" "github.com/coder/coder/v2/codersdk/agentsdk" ) @@ -314,9 +315,9 @@ func (r *Runner) run(ctx context.Context, script codersdk.WorkspaceAgentScript, cmd.Stdout = io.MultiWriter(fileWriter, infoW) cmd.Stderr = io.MultiWriter(fileWriter, errW) - start := time.Now().UTC() + start := dbtime.Now() defer func() { - end := time.Now().UTC() + end := dbtime.Now() execTime := end.Sub(start) exitCode := 0 if err != nil { From ed31199f8feba64a990974acf365c90a18975dc2 Mon Sep 17 00:00:00 2001 From: Danielle Maywood Date: Fri, 20 Sep 2024 11:19:43 +0000 Subject: [PATCH 40/56] fix: debug log on r.scriptCompleted being nil --- agent/agentscripts/agentscripts.go | 33 ++++++++++++++++-------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/agent/agentscripts/agentscripts.go b/agent/agentscripts/agentscripts.go index 4c591e1e89a0b..257489ded5547 100644 --- a/agent/agentscripts/agentscripts.go +++ b/agent/agentscripts/agentscripts.go @@ -331,6 +331,11 @@ func (r *Runner) run(ctx context.Context, script codersdk.WorkspaceAgentScript, logger.Info(ctx, fmt.Sprintf("%s script completed", logPath), slog.F("execution_time", execTime), slog.F("exit_code", exitCode)) } + if r.scriptCompleted == nil { + logger.Debug(ctx, "r.scriptCompleted unexpectedly nil") + return + } + var stage proto.Timing_Stage switch option { case ExecuteStartScripts: @@ -341,21 +346,19 @@ func (r *Runner) run(ctx context.Context, script codersdk.WorkspaceAgentScript, stage = proto.Timing_CRON } - if r.scriptCompleted != nil { - _, err = r.scriptCompleted(ctx, &proto.WorkspaceAgentScriptCompletedRequest{ - Timing: &proto.Timing{ - ScriptId: script.ID[:], - DisplayName: script.DisplayName, - Start: timestamppb.New(start), - End: timestamppb.New(end), - ExitCode: int32(exitCode), - Stage: stage, - TimedOut: errors.Is(err, ErrTimeout), - }, - }) - if err != nil { - logger.Error(ctx, fmt.Sprintf("reporting script completed: %s", err.Error())) - } + _, err = r.scriptCompleted(ctx, &proto.WorkspaceAgentScriptCompletedRequest{ + Timing: &proto.Timing{ + ScriptId: script.ID[:], + DisplayName: script.DisplayName, + Start: timestamppb.New(start), + End: timestamppb.New(end), + ExitCode: int32(exitCode), + Stage: stage, + TimedOut: errors.Is(err, ErrTimeout), + }, + }) + if err != nil { + logger.Error(ctx, fmt.Sprintf("reporting script completed: %s", err.Error())) } }() From 881471149b2849f1e30bf00c2a60c84a964e8de0 Mon Sep 17 00:00:00 2001 From: Danielle Maywood Date: Fri, 20 Sep 2024 13:23:28 +0000 Subject: [PATCH 41/56] fix: ensure correct rbac permissions --- coderd/database/dbauthz/dbauthz.go | 6 +++--- coderd/database/dbauthz/dbauthz_test.go | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/coderd/database/dbauthz/dbauthz.go b/coderd/database/dbauthz/dbauthz.go index 9565ebc1eda7d..483dbfdf84a83 100644 --- a/coderd/database/dbauthz/dbauthz.go +++ b/coderd/database/dbauthz/dbauthz.go @@ -3028,9 +3028,9 @@ func (q *querier) InsertWorkspaceAgentMetadata(ctx context.Context, arg database } func (q *querier) InsertWorkspaceAgentScriptTimings(ctx context.Context, arg database.InsertWorkspaceAgentScriptTimingsParams) (database.WorkspaceAgentScriptTiming, error) { - // if err := q.authorizeContext(ctx, policy.ActionCreate, rbac.ResourceSystem); err != nil { - // return nil, err - // } + if err := q.authorizeContext(ctx, policy.ActionCreate, rbac.ResourceSystem); err != nil { + return database.WorkspaceAgentScriptTiming{}, err + } return q.db.InsertWorkspaceAgentScriptTimings(ctx, arg) } diff --git a/coderd/database/dbauthz/dbauthz_test.go b/coderd/database/dbauthz/dbauthz_test.go index b6605a08bfd51..266d477c2976e 100644 --- a/coderd/database/dbauthz/dbauthz_test.go +++ b/coderd/database/dbauthz/dbauthz_test.go @@ -2636,7 +2636,7 @@ func (s *MethodTestSuite) TestSystemFunctions() { check.Args(database.InsertWorkspaceAgentScriptTimingsParams{ ScriptID: uuid.New(), Stage: database.WorkspaceAgentScriptTimingStageStart, - }).Asserts( /* rbac.ResourceSystem, policy.ActionCreate */ ) + }).Asserts(rbac.ResourceSystem, policy.ActionCreate) })) s.Run("InsertWorkspaceAgentScripts", s.Subtest(func(db database.Store, check *expects) { check.Args(database.InsertWorkspaceAgentScriptsParams{}).Asserts(rbac.ResourceSystem, policy.ActionCreate) From 0414623eeaee8c632e21bc069266be0f6cd36246 Mon Sep 17 00:00:00 2001 From: Danielle Maywood Date: Fri, 20 Sep 2024 13:36:33 +0000 Subject: [PATCH 42/56] chore: remove DisplayName --- agent/proto/agent.pb.go | 764 +++++++++--------- agent/proto/agent.proto | 1 - coderd/agentapi/manifest.go | 1 - coderd/database/dbmem/dbmem.go | 1 - coderd/database/dump.sql | 3 +- ...7_workspace_agent_script_timings.down.sql} | 1 - ...257_workspace_agent_script_timings.up.sql} | 1 - ...257_workspace_agent_script_timings.up.sql} | 0 coderd/database/models.go | 1 - coderd/database/queries.sql.go | 11 +- coderd/database/queries/workspacescripts.sql | 1 - .../provisionerdserver/provisionerdserver.go | 1 - coderd/workspaceagents.go | 1 - codersdk/agentsdk/convert.go | 2 - 14 files changed, 381 insertions(+), 408 deletions(-) rename coderd/database/migrations/{000256_workspace_agent_script_timings.down.sql => 000257_workspace_agent_script_timings.down.sql} (73%) rename coderd/database/migrations/{000256_workspace_agent_script_timings.up.sql => 000257_workspace_agent_script_timings.up.sql} (89%) rename coderd/database/migrations/testdata/fixtures/{000256_workspace_agent_script_timings.up.sql => 000257_workspace_agent_script_timings.up.sql} (100%) diff --git a/agent/proto/agent.pb.go b/agent/proto/agent.pb.go index b0fb99297245e..8644bf5a92c27 100644 --- a/agent/proto/agent.pb.go +++ b/agent/proto/agent.pb.go @@ -619,7 +619,6 @@ type WorkspaceAgentScript struct { RunOnStop bool `protobuf:"varint,6,opt,name=run_on_stop,json=runOnStop,proto3" json:"run_on_stop,omitempty"` StartBlocksLogin bool `protobuf:"varint,7,opt,name=start_blocks_login,json=startBlocksLogin,proto3" json:"start_blocks_login,omitempty"` Timeout *durationpb.Duration `protobuf:"bytes,8,opt,name=timeout,proto3" json:"timeout,omitempty"` - DisplayName string `protobuf:"bytes,9,opt,name=display_name,json=displayName,proto3" json:"display_name,omitempty"` Id []byte `protobuf:"bytes,10,opt,name=id,proto3" json:"id,omitempty"` } @@ -711,13 +710,6 @@ func (x *WorkspaceAgentScript) GetTimeout() *durationpb.Duration { return nil } -func (x *WorkspaceAgentScript) GetDisplayName() string { - if x != nil { - return x.DisplayName - } - return "" -} - func (x *WorkspaceAgentScript) GetId() []byte { if x != nil { return x.Id @@ -2714,7 +2706,7 @@ var file_agent_proto_agent_proto_rawDesc = []byte{ 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x44, 0x49, 0x53, 0x41, 0x42, 0x4c, 0x45, 0x44, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x49, 0x4e, 0x49, 0x54, 0x49, 0x41, 0x4c, 0x49, 0x5a, 0x49, 0x4e, 0x47, 0x10, 0x02, 0x12, 0x0b, 0x0a, 0x07, 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, 0x59, 0x10, 0x03, 0x12, - 0x0d, 0x0a, 0x09, 0x55, 0x4e, 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, 0x59, 0x10, 0x04, 0x22, 0xd9, + 0x0d, 0x0a, 0x09, 0x55, 0x4e, 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, 0x59, 0x10, 0x04, 0x22, 0xb6, 0x02, 0x0a, 0x14, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x12, 0x22, 0x0a, 0x0d, 0x6c, 0x6f, 0x67, 0x5f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, @@ -2733,390 +2725,388 @@ var file_agent_proto_agent_proto_rawDesc = []byte{ 0x69, 0x6e, 0x12, 0x33, 0x0a, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x07, - 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x64, 0x69, 0x73, 0x70, 0x6c, - 0x61, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, - 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, - 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, 0x69, 0x64, 0x22, 0x86, 0x04, 0x0a, 0x16, 0x57, - 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x4d, 0x65, 0x74, - 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x45, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, - 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, - 0x41, 0x67, 0x65, 0x6e, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x65, - 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x54, 0x0a, 0x0b, - 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x0a, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x02, 0x69, 0x64, 0x22, 0x86, 0x04, 0x0a, 0x16, 0x57, 0x6f, 0x72, 0x6b, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, + 0x74, 0x61, 0x12, 0x45, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, + 0x2e, 0x76, 0x32, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x41, 0x67, 0x65, + 0x6e, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6c, + 0x74, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x54, 0x0a, 0x0b, 0x64, 0x65, 0x73, + 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x32, + 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, + 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x4d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x1a, + 0x85, 0x01, 0x0a, 0x06, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x3d, 0x0a, 0x0c, 0x63, 0x6f, + 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0b, 0x63, 0x6f, + 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x67, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x03, 0x61, 0x67, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x1a, 0xc6, 0x01, 0x0a, 0x0b, 0x44, 0x65, 0x73, 0x63, + 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x21, 0x0a, 0x0c, 0x64, 0x69, 0x73, 0x70, 0x6c, + 0x61, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, + 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, + 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x16, 0x0a, 0x06, + 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x63, + 0x72, 0x69, 0x70, 0x74, 0x12, 0x35, 0x0a, 0x08, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x52, 0x08, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x12, 0x33, 0x0a, 0x07, 0x74, + 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, + 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, + 0x22, 0xea, 0x06, 0x0a, 0x08, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x12, 0x19, 0x0a, + 0x08, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x07, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x67, 0x65, 0x6e, + 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x67, + 0x65, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x6f, 0x77, 0x6e, 0x65, 0x72, + 0x5f, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0d, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x55, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x21, + 0x0a, 0x0c, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x0e, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x49, + 0x64, 0x12, 0x25, 0x0a, 0x0e, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x10, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x77, 0x6f, 0x72, 0x6b, 0x73, + 0x70, 0x61, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x28, 0x0a, 0x10, 0x67, 0x69, 0x74, 0x5f, + 0x61, 0x75, 0x74, 0x68, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0d, 0x52, 0x0e, 0x67, 0x69, 0x74, 0x41, 0x75, 0x74, 0x68, 0x43, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x73, 0x12, 0x67, 0x0a, 0x15, 0x65, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, + 0x74, 0x5f, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, - 0x76, 0x32, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x41, 0x67, 0x65, 0x6e, - 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, - 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, - 0x6f, 0x6e, 0x1a, 0x85, 0x01, 0x0a, 0x06, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x3d, 0x0a, - 0x0c, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, - 0x0b, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x10, 0x0a, 0x03, - 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x03, 0x61, 0x67, 0x65, 0x12, 0x14, - 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x1a, 0xc6, 0x01, 0x0a, 0x0b, 0x44, - 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x21, 0x0a, 0x0c, 0x64, 0x69, - 0x73, 0x70, 0x6c, 0x61, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x10, 0x0a, - 0x03, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, - 0x16, 0x0a, 0x06, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x06, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x12, 0x35, 0x0a, 0x08, 0x69, 0x6e, 0x74, 0x65, 0x72, - 0x76, 0x61, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x08, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x12, 0x33, - 0x0a, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x07, 0x74, 0x69, 0x6d, 0x65, - 0x6f, 0x75, 0x74, 0x22, 0xea, 0x06, 0x0a, 0x08, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, - 0x12, 0x19, 0x0a, 0x08, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0c, 0x52, 0x07, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x61, - 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x09, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x6f, 0x77, - 0x6e, 0x65, 0x72, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x0d, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0d, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x55, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, - 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x69, - 0x64, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, - 0x63, 0x65, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x0e, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, - 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x10, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x77, 0x6f, - 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x28, 0x0a, 0x10, 0x67, - 0x69, 0x74, 0x5f, 0x61, 0x75, 0x74, 0x68, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0e, 0x67, 0x69, 0x74, 0x41, 0x75, 0x74, 0x68, 0x43, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x73, 0x12, 0x67, 0x0a, 0x15, 0x65, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, - 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x03, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, - 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x2e, 0x45, - 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, - 0x6c, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x14, 0x65, 0x6e, 0x76, 0x69, 0x72, 0x6f, - 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, 0x1c, - 0x0a, 0x09, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x09, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x32, 0x0a, 0x16, - 0x76, 0x73, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x70, 0x72, 0x6f, - 0x78, 0x79, 0x5f, 0x75, 0x72, 0x69, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x76, 0x73, - 0x43, 0x6f, 0x64, 0x65, 0x50, 0x6f, 0x72, 0x74, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x55, 0x72, 0x69, - 0x12, 0x1b, 0x0a, 0x09, 0x6d, 0x6f, 0x74, 0x64, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x06, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x08, 0x6d, 0x6f, 0x74, 0x64, 0x50, 0x61, 0x74, 0x68, 0x12, 0x3c, 0x0a, - 0x1a, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x5f, - 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x18, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, - 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x32, 0x0a, 0x15, 0x64, - 0x65, 0x72, 0x70, 0x5f, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x5f, 0x77, 0x65, 0x62, 0x73, 0x6f, 0x63, - 0x6b, 0x65, 0x74, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x13, 0x64, 0x65, 0x72, 0x70, - 0x46, 0x6f, 0x72, 0x63, 0x65, 0x57, 0x65, 0x62, 0x73, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x12, - 0x34, 0x0a, 0x08, 0x64, 0x65, 0x72, 0x70, 0x5f, 0x6d, 0x61, 0x70, 0x18, 0x09, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x74, 0x61, 0x69, 0x6c, 0x6e, 0x65, - 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x44, 0x45, 0x52, 0x50, 0x4d, 0x61, 0x70, 0x52, 0x07, 0x64, 0x65, - 0x72, 0x70, 0x4d, 0x61, 0x70, 0x12, 0x3e, 0x0a, 0x07, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x73, - 0x18, 0x0a, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, + 0x76, 0x32, 0x2e, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x2e, 0x45, 0x6e, 0x76, 0x69, + 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, + 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x14, 0x65, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, + 0x6e, 0x74, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x64, + 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, + 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x32, 0x0a, 0x16, 0x76, 0x73, 0x5f, + 0x63, 0x6f, 0x64, 0x65, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x5f, + 0x75, 0x72, 0x69, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x76, 0x73, 0x43, 0x6f, 0x64, + 0x65, 0x50, 0x6f, 0x72, 0x74, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x55, 0x72, 0x69, 0x12, 0x1b, 0x0a, + 0x09, 0x6d, 0x6f, 0x74, 0x64, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x08, 0x6d, 0x6f, 0x74, 0x64, 0x50, 0x61, 0x74, 0x68, 0x12, 0x3c, 0x0a, 0x1a, 0x64, 0x69, + 0x73, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x5f, 0x63, 0x6f, 0x6e, + 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x18, + 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x43, 0x6f, 0x6e, + 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x32, 0x0a, 0x15, 0x64, 0x65, 0x72, 0x70, + 0x5f, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x5f, 0x77, 0x65, 0x62, 0x73, 0x6f, 0x63, 0x6b, 0x65, 0x74, + 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x13, 0x64, 0x65, 0x72, 0x70, 0x46, 0x6f, 0x72, + 0x63, 0x65, 0x57, 0x65, 0x62, 0x73, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x12, 0x34, 0x0a, 0x08, + 0x64, 0x65, 0x72, 0x70, 0x5f, 0x6d, 0x61, 0x70, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, + 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x74, 0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74, 0x2e, 0x76, + 0x32, 0x2e, 0x44, 0x45, 0x52, 0x50, 0x4d, 0x61, 0x70, 0x52, 0x07, 0x64, 0x65, 0x72, 0x70, 0x4d, + 0x61, 0x70, 0x12, 0x3e, 0x0a, 0x07, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x73, 0x18, 0x0a, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, + 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x41, 0x67, + 0x65, 0x6e, 0x74, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x52, 0x07, 0x73, 0x63, 0x72, 0x69, 0x70, + 0x74, 0x73, 0x12, 0x30, 0x0a, 0x04, 0x61, 0x70, 0x70, 0x73, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x1c, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, + 0x32, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x41, 0x70, 0x70, 0x52, 0x04, + 0x61, 0x70, 0x70, 0x73, 0x12, 0x4e, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x18, 0x0c, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, - 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x52, 0x07, 0x73, 0x63, - 0x72, 0x69, 0x70, 0x74, 0x73, 0x12, 0x30, 0x0a, 0x04, 0x61, 0x70, 0x70, 0x73, 0x18, 0x0b, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, - 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x41, 0x70, - 0x70, 0x52, 0x04, 0x61, 0x70, 0x70, 0x73, 0x12, 0x4e, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, - 0x61, 0x74, 0x61, 0x18, 0x0c, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x63, 0x6f, 0x64, 0x65, - 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, - 0x70, 0x61, 0x63, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, - 0x61, 0x2e, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x08, 0x6d, - 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x1a, 0x47, 0x0a, 0x19, 0x45, 0x6e, 0x76, 0x69, 0x72, - 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x45, - 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, - 0x22, 0x14, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x6e, 0x0a, 0x0d, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, - 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, - 0x64, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x29, 0x0a, 0x10, 0x62, - 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, - 0x64, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x22, 0x19, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x53, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x22, 0xb3, 0x07, 0x0a, 0x05, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x5f, 0x0a, 0x14, 0x63, - 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x5f, 0x62, 0x79, 0x5f, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x63, 0x6f, 0x64, 0x65, + 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x44, + 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0x1a, 0x47, 0x0a, 0x19, 0x45, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, + 0x65, 0x6e, 0x74, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, + 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, + 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x14, 0x0a, + 0x12, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x22, 0x6e, 0x0a, 0x0d, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x42, 0x61, + 0x6e, 0x6e, 0x65, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x18, + 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x29, 0x0a, 0x10, 0x62, 0x61, 0x63, 0x6b, + 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0f, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x43, 0x6f, + 0x6c, 0x6f, 0x72, 0x22, 0x19, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0xb3, + 0x07, 0x0a, 0x05, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x5f, 0x0a, 0x14, 0x63, 0x6f, 0x6e, 0x6e, + 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x5f, 0x62, 0x79, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, + 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x73, 0x2e, 0x43, 0x6f, + 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x42, 0x79, 0x50, 0x72, 0x6f, 0x74, 0x6f, + 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x12, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x42, 0x79, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x29, 0x0a, 0x10, 0x63, 0x6f, 0x6e, + 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x03, 0x52, 0x0f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x43, + 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x3f, 0x0a, 0x1c, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x5f, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x6e, 0x5f, 0x6c, 0x61, 0x74, 0x65, 0x6e, 0x63, + 0x79, 0x5f, 0x6d, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x01, 0x52, 0x19, 0x63, 0x6f, 0x6e, 0x6e, + 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x64, 0x69, 0x61, 0x6e, 0x4c, 0x61, 0x74, 0x65, + 0x6e, 0x63, 0x79, 0x4d, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x78, 0x5f, 0x70, 0x61, 0x63, 0x6b, + 0x65, 0x74, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x72, 0x78, 0x50, 0x61, 0x63, + 0x6b, 0x65, 0x74, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x72, 0x78, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, + 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x72, 0x78, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, + 0x1d, 0x0a, 0x0a, 0x74, 0x78, 0x5f, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x18, 0x06, 0x20, + 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x78, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x12, 0x19, + 0x0a, 0x08, 0x74, 0x78, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, + 0x52, 0x07, 0x74, 0x78, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x30, 0x0a, 0x14, 0x73, 0x65, 0x73, + 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x76, 0x73, 0x63, 0x6f, 0x64, + 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x03, 0x52, 0x12, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, + 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x56, 0x73, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x36, 0x0a, 0x17, 0x73, + 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x6a, 0x65, 0x74, + 0x62, 0x72, 0x61, 0x69, 0x6e, 0x73, 0x18, 0x09, 0x20, 0x01, 0x28, 0x03, 0x52, 0x15, 0x73, 0x65, + 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x4a, 0x65, 0x74, 0x62, 0x72, 0x61, + 0x69, 0x6e, 0x73, 0x12, 0x43, 0x0a, 0x1e, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x63, + 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x72, 0x65, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6e, + 0x67, 0x5f, 0x70, 0x74, 0x79, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x03, 0x52, 0x1b, 0x73, 0x65, 0x73, + 0x73, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x63, 0x6f, 0x6e, 0x6e, 0x65, + 0x63, 0x74, 0x69, 0x6e, 0x67, 0x50, 0x74, 0x79, 0x12, 0x2a, 0x0a, 0x11, 0x73, 0x65, 0x73, 0x73, + 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x73, 0x73, 0x68, 0x18, 0x0b, 0x20, + 0x01, 0x28, 0x03, 0x52, 0x0f, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x75, 0x6e, + 0x74, 0x53, 0x73, 0x68, 0x12, 0x36, 0x0a, 0x07, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x18, + 0x0c, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, + 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x73, 0x2e, 0x4d, 0x65, 0x74, + 0x72, 0x69, 0x63, 0x52, 0x07, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x1a, 0x45, 0x0a, 0x17, + 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x42, 0x79, 0x50, 0x72, 0x6f, + 0x74, 0x6f, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, + 0x02, 0x38, 0x01, 0x1a, 0x8e, 0x02, 0x0a, 0x06, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x12, 0x12, + 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x12, 0x35, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, + 0x32, 0x21, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, + 0x32, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x73, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x54, + 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x01, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, + 0x3a, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x22, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, + 0x2e, 0x53, 0x74, 0x61, 0x74, 0x73, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x4c, 0x61, + 0x62, 0x65, 0x6c, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x1a, 0x31, 0x0a, 0x05, 0x4c, + 0x61, 0x62, 0x65, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x34, + 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, + 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, + 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x47, 0x41, 0x55, + 0x47, 0x45, 0x10, 0x02, 0x22, 0x41, 0x0a, 0x12, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, + 0x61, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2b, 0x0a, 0x05, 0x73, 0x74, + 0x61, 0x74, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x73, - 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x42, 0x79, 0x50, 0x72, - 0x6f, 0x74, 0x6f, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x12, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x42, 0x79, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x29, 0x0a, 0x10, - 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x3f, 0x0a, 0x1c, 0x63, 0x6f, 0x6e, 0x6e, 0x65, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x6e, 0x5f, 0x6c, 0x61, 0x74, - 0x65, 0x6e, 0x63, 0x79, 0x5f, 0x6d, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x01, 0x52, 0x19, 0x63, - 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x64, 0x69, 0x61, 0x6e, 0x4c, - 0x61, 0x74, 0x65, 0x6e, 0x63, 0x79, 0x4d, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x78, 0x5f, 0x70, - 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x72, 0x78, - 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x72, 0x78, 0x5f, 0x62, 0x79, - 0x74, 0x65, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x72, 0x78, 0x42, 0x79, 0x74, - 0x65, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x74, 0x78, 0x5f, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, - 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x78, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, - 0x73, 0x12, 0x19, 0x0a, 0x08, 0x74, 0x78, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x07, 0x20, - 0x01, 0x28, 0x03, 0x52, 0x07, 0x74, 0x78, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x30, 0x0a, 0x14, - 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x76, 0x73, - 0x63, 0x6f, 0x64, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x03, 0x52, 0x12, 0x73, 0x65, 0x73, 0x73, - 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x56, 0x73, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x36, - 0x0a, 0x17, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, - 0x6a, 0x65, 0x74, 0x62, 0x72, 0x61, 0x69, 0x6e, 0x73, 0x18, 0x09, 0x20, 0x01, 0x28, 0x03, 0x52, - 0x15, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x4a, 0x65, 0x74, - 0x62, 0x72, 0x61, 0x69, 0x6e, 0x73, 0x12, 0x43, 0x0a, 0x1e, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, - 0x6e, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x72, 0x65, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, - 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x70, 0x74, 0x79, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x03, 0x52, 0x1b, - 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x63, 0x6f, - 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6e, 0x67, 0x50, 0x74, 0x79, 0x12, 0x2a, 0x0a, 0x11, 0x73, - 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x73, 0x73, 0x68, - 0x18, 0x0b, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0f, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x43, - 0x6f, 0x75, 0x6e, 0x74, 0x53, 0x73, 0x68, 0x12, 0x36, 0x0a, 0x07, 0x6d, 0x65, 0x74, 0x72, 0x69, - 0x63, 0x73, 0x18, 0x0c, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, - 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x73, 0x2e, - 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x52, 0x07, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x1a, - 0x45, 0x0a, 0x17, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x42, 0x79, - 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, - 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, - 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x8e, 0x02, 0x0a, 0x06, 0x4d, 0x65, 0x74, 0x72, 0x69, - 0x63, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x35, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0e, 0x32, 0x21, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, - 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x73, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, - 0x63, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x05, - 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x01, 0x52, 0x05, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x12, 0x3a, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x04, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, - 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x73, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, - 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x1a, 0x31, - 0x0a, 0x05, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x22, 0x34, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x59, 0x50, - 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, - 0x0b, 0x0a, 0x07, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, - 0x47, 0x41, 0x55, 0x47, 0x45, 0x10, 0x02, 0x22, 0x41, 0x0a, 0x12, 0x55, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2b, 0x0a, - 0x05, 0x73, 0x74, 0x61, 0x74, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x63, - 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x74, - 0x61, 0x74, 0x73, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x73, 0x22, 0x59, 0x0a, 0x13, 0x55, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x42, 0x0a, 0x0f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x69, 0x6e, 0x74, 0x65, - 0x72, 0x76, 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0e, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x49, 0x6e, 0x74, - 0x65, 0x72, 0x76, 0x61, 0x6c, 0x22, 0xae, 0x02, 0x0a, 0x09, 0x4c, 0x69, 0x66, 0x65, 0x63, 0x79, - 0x63, 0x6c, 0x65, 0x12, 0x35, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0e, 0x32, 0x1f, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, - 0x2e, 0x76, 0x32, 0x2e, 0x4c, 0x69, 0x66, 0x65, 0x63, 0x79, 0x63, 0x6c, 0x65, 0x2e, 0x53, 0x74, - 0x61, 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x68, - 0x61, 0x6e, 0x67, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, - 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x63, 0x68, 0x61, 0x6e, - 0x67, 0x65, 0x64, 0x41, 0x74, 0x22, 0xae, 0x01, 0x0a, 0x05, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, - 0x15, 0x0a, 0x11, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, - 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, - 0x44, 0x10, 0x01, 0x12, 0x0c, 0x0a, 0x08, 0x53, 0x54, 0x41, 0x52, 0x54, 0x49, 0x4e, 0x47, 0x10, - 0x02, 0x12, 0x11, 0x0a, 0x0d, 0x53, 0x54, 0x41, 0x52, 0x54, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x4f, - 0x55, 0x54, 0x10, 0x03, 0x12, 0x0f, 0x0a, 0x0b, 0x53, 0x54, 0x41, 0x52, 0x54, 0x5f, 0x45, 0x52, - 0x52, 0x4f, 0x52, 0x10, 0x04, 0x12, 0x09, 0x0a, 0x05, 0x52, 0x45, 0x41, 0x44, 0x59, 0x10, 0x05, - 0x12, 0x11, 0x0a, 0x0d, 0x53, 0x48, 0x55, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x5f, 0x44, 0x4f, 0x57, - 0x4e, 0x10, 0x06, 0x12, 0x14, 0x0a, 0x10, 0x53, 0x48, 0x55, 0x54, 0x44, 0x4f, 0x57, 0x4e, 0x5f, - 0x54, 0x49, 0x4d, 0x45, 0x4f, 0x55, 0x54, 0x10, 0x07, 0x12, 0x12, 0x0a, 0x0e, 0x53, 0x48, 0x55, - 0x54, 0x44, 0x4f, 0x57, 0x4e, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x08, 0x12, 0x07, 0x0a, - 0x03, 0x4f, 0x46, 0x46, 0x10, 0x09, 0x22, 0x51, 0x0a, 0x16, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x4c, 0x69, 0x66, 0x65, 0x63, 0x79, 0x63, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x37, 0x0a, 0x09, 0x6c, 0x69, 0x66, 0x65, 0x63, 0x79, 0x63, 0x6c, 0x65, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, - 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x4c, 0x69, 0x66, 0x65, 0x63, 0x79, 0x63, 0x6c, 0x65, 0x52, 0x09, - 0x6c, 0x69, 0x66, 0x65, 0x63, 0x79, 0x63, 0x6c, 0x65, 0x22, 0xc4, 0x01, 0x0a, 0x1b, 0x42, 0x61, - 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x70, 0x70, 0x48, 0x65, 0x61, 0x6c, - 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x52, 0x0a, 0x07, 0x75, 0x70, 0x64, - 0x61, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x38, 0x2e, 0x63, 0x6f, 0x64, - 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x42, 0x61, 0x74, 0x63, - 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x70, 0x70, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x55, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x52, 0x07, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x1a, 0x51, 0x0a, - 0x0c, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x0e, 0x0a, - 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, 0x69, 0x64, 0x12, 0x31, 0x0a, - 0x06, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x19, 0x2e, - 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x41, - 0x70, 0x70, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, 0x06, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, - 0x22, 0x1e, 0x0a, 0x1c, 0x42, 0x61, 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, - 0x70, 0x70, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0xe8, 0x01, 0x0a, 0x07, 0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x12, 0x18, 0x0a, 0x07, - 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, - 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x2d, 0x0a, 0x12, 0x65, 0x78, 0x70, 0x61, 0x6e, 0x64, - 0x65, 0x64, 0x5f, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x11, 0x65, 0x78, 0x70, 0x61, 0x6e, 0x64, 0x65, 0x64, 0x44, 0x69, 0x72, 0x65, - 0x63, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x41, 0x0a, 0x0a, 0x73, 0x75, 0x62, 0x73, 0x79, 0x73, 0x74, - 0x65, 0x6d, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x21, 0x2e, 0x63, 0x6f, 0x64, 0x65, - 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, - 0x75, 0x70, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x52, 0x0a, 0x73, 0x75, - 0x62, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x73, 0x22, 0x51, 0x0a, 0x09, 0x53, 0x75, 0x62, 0x73, - 0x79, 0x73, 0x74, 0x65, 0x6d, 0x12, 0x19, 0x0a, 0x15, 0x53, 0x55, 0x42, 0x53, 0x59, 0x53, 0x54, - 0x45, 0x4d, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, - 0x12, 0x0a, 0x0a, 0x06, 0x45, 0x4e, 0x56, 0x42, 0x4f, 0x58, 0x10, 0x01, 0x12, 0x0e, 0x0a, 0x0a, - 0x45, 0x4e, 0x56, 0x42, 0x55, 0x49, 0x4c, 0x44, 0x45, 0x52, 0x10, 0x02, 0x12, 0x0d, 0x0a, 0x09, - 0x45, 0x58, 0x45, 0x43, 0x54, 0x52, 0x41, 0x43, 0x45, 0x10, 0x03, 0x22, 0x49, 0x0a, 0x14, 0x55, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x31, 0x0a, 0x07, 0x73, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, - 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x52, 0x07, 0x73, - 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x22, 0x63, 0x0a, 0x08, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, - 0x74, 0x61, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x03, 0x6b, 0x65, 0x79, 0x12, 0x45, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, - 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x41, - 0x67, 0x65, 0x6e, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x65, 0x73, - 0x75, 0x6c, 0x74, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x52, 0x0a, 0x1a, 0x42, - 0x61, 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, - 0x74, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x34, 0x0a, 0x08, 0x6d, 0x65, 0x74, - 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x63, 0x6f, - 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x4d, 0x65, 0x74, - 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x22, - 0x1d, 0x0a, 0x1b, 0x42, 0x61, 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x65, - 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xde, - 0x01, 0x0a, 0x03, 0x4c, 0x6f, 0x67, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, - 0x64, 0x5f, 0x61, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, + 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x73, 0x22, 0x59, 0x0a, 0x13, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x42, + 0x0a, 0x0f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, + 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x52, 0x0e, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, + 0x61, 0x6c, 0x22, 0xae, 0x02, 0x0a, 0x09, 0x4c, 0x69, 0x66, 0x65, 0x63, 0x79, 0x63, 0x6c, 0x65, + 0x12, 0x35, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, + 0x1f, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, + 0x2e, 0x4c, 0x69, 0x66, 0x65, 0x63, 0x79, 0x63, 0x6c, 0x65, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, + 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x68, 0x61, 0x6e, 0x67, + 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, + 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, + 0x41, 0x74, 0x22, 0xae, 0x01, 0x0a, 0x05, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x15, 0x0a, 0x11, + 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, + 0x44, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x44, 0x10, 0x01, + 0x12, 0x0c, 0x0a, 0x08, 0x53, 0x54, 0x41, 0x52, 0x54, 0x49, 0x4e, 0x47, 0x10, 0x02, 0x12, 0x11, + 0x0a, 0x0d, 0x53, 0x54, 0x41, 0x52, 0x54, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x4f, 0x55, 0x54, 0x10, + 0x03, 0x12, 0x0f, 0x0a, 0x0b, 0x53, 0x54, 0x41, 0x52, 0x54, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, + 0x10, 0x04, 0x12, 0x09, 0x0a, 0x05, 0x52, 0x45, 0x41, 0x44, 0x59, 0x10, 0x05, 0x12, 0x11, 0x0a, + 0x0d, 0x53, 0x48, 0x55, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x5f, 0x44, 0x4f, 0x57, 0x4e, 0x10, 0x06, + 0x12, 0x14, 0x0a, 0x10, 0x53, 0x48, 0x55, 0x54, 0x44, 0x4f, 0x57, 0x4e, 0x5f, 0x54, 0x49, 0x4d, + 0x45, 0x4f, 0x55, 0x54, 0x10, 0x07, 0x12, 0x12, 0x0a, 0x0e, 0x53, 0x48, 0x55, 0x54, 0x44, 0x4f, + 0x57, 0x4e, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x08, 0x12, 0x07, 0x0a, 0x03, 0x4f, 0x46, + 0x46, 0x10, 0x09, 0x22, 0x51, 0x0a, 0x16, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4c, 0x69, 0x66, + 0x65, 0x63, 0x79, 0x63, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x37, 0x0a, + 0x09, 0x6c, 0x69, 0x66, 0x65, 0x63, 0x79, 0x63, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x19, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, + 0x32, 0x2e, 0x4c, 0x69, 0x66, 0x65, 0x63, 0x79, 0x63, 0x6c, 0x65, 0x52, 0x09, 0x6c, 0x69, 0x66, + 0x65, 0x63, 0x79, 0x63, 0x6c, 0x65, 0x22, 0xc4, 0x01, 0x0a, 0x1b, 0x42, 0x61, 0x74, 0x63, 0x68, + 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x70, 0x70, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x52, 0x0a, 0x07, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x38, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, + 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x41, 0x70, 0x70, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x52, 0x07, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x1a, 0x51, 0x0a, 0x0c, 0x48, 0x65, + 0x61, 0x6c, 0x74, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, 0x69, 0x64, 0x12, 0x31, 0x0a, 0x06, 0x68, 0x65, + 0x61, 0x6c, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x19, 0x2e, 0x63, 0x6f, 0x64, + 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x41, 0x70, 0x70, 0x48, + 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, 0x06, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x22, 0x1e, 0x0a, + 0x1c, 0x42, 0x61, 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x70, 0x70, 0x48, + 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xe8, 0x01, + 0x0a, 0x07, 0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, + 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x12, 0x2d, 0x0a, 0x12, 0x65, 0x78, 0x70, 0x61, 0x6e, 0x64, 0x65, 0x64, 0x5f, + 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x11, 0x65, 0x78, 0x70, 0x61, 0x6e, 0x64, 0x65, 0x64, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, + 0x72, 0x79, 0x12, 0x41, 0x0a, 0x0a, 0x73, 0x75, 0x62, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x73, + 0x18, 0x03, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x21, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, + 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x2e, + 0x53, 0x75, 0x62, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x52, 0x0a, 0x73, 0x75, 0x62, 0x73, 0x79, + 0x73, 0x74, 0x65, 0x6d, 0x73, 0x22, 0x51, 0x0a, 0x09, 0x53, 0x75, 0x62, 0x73, 0x79, 0x73, 0x74, + 0x65, 0x6d, 0x12, 0x19, 0x0a, 0x15, 0x53, 0x55, 0x42, 0x53, 0x59, 0x53, 0x54, 0x45, 0x4d, 0x5f, + 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0a, 0x0a, + 0x06, 0x45, 0x4e, 0x56, 0x42, 0x4f, 0x58, 0x10, 0x01, 0x12, 0x0e, 0x0a, 0x0a, 0x45, 0x4e, 0x56, + 0x42, 0x55, 0x49, 0x4c, 0x44, 0x45, 0x52, 0x10, 0x02, 0x12, 0x0d, 0x0a, 0x09, 0x45, 0x58, 0x45, + 0x43, 0x54, 0x52, 0x41, 0x43, 0x45, 0x10, 0x03, 0x22, 0x49, 0x0a, 0x14, 0x55, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x31, 0x0a, 0x07, 0x73, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x17, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, + 0x76, 0x32, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x52, 0x07, 0x73, 0x74, 0x61, 0x72, + 0x74, 0x75, 0x70, 0x22, 0x63, 0x0a, 0x08, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, + 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, + 0x79, 0x12, 0x45, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x2d, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, + 0x76, 0x32, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x41, 0x67, 0x65, 0x6e, + 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, + 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x52, 0x0a, 0x1a, 0x42, 0x61, 0x74, 0x63, + 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x34, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, + 0x74, 0x61, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, + 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, + 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x22, 0x1d, 0x0a, 0x1b, + 0x42, 0x61, 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xde, 0x01, 0x0a, 0x03, + 0x4c, 0x6f, 0x67, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, + 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, + 0x61, 0x6d, 0x70, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x16, + 0x0a, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, + 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x12, 0x2f, 0x0a, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x19, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, + 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x4c, 0x6f, 0x67, 0x2e, 0x4c, 0x65, 0x76, 0x65, 0x6c, + 0x52, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x22, 0x53, 0x0a, 0x05, 0x4c, 0x65, 0x76, 0x65, 0x6c, + 0x12, 0x15, 0x0a, 0x11, 0x4c, 0x45, 0x56, 0x45, 0x4c, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, + 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x54, 0x52, 0x41, 0x43, 0x45, + 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x44, 0x45, 0x42, 0x55, 0x47, 0x10, 0x02, 0x12, 0x08, 0x0a, + 0x04, 0x49, 0x4e, 0x46, 0x4f, 0x10, 0x03, 0x12, 0x08, 0x0a, 0x04, 0x57, 0x41, 0x52, 0x4e, 0x10, + 0x04, 0x12, 0x09, 0x0a, 0x05, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x05, 0x22, 0x65, 0x0a, 0x16, + 0x42, 0x61, 0x74, 0x63, 0x68, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4c, 0x6f, 0x67, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x22, 0x0a, 0x0d, 0x6c, 0x6f, 0x67, 0x5f, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x6c, + 0x6f, 0x67, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x64, 0x12, 0x27, 0x0a, 0x04, 0x6c, 0x6f, + 0x67, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, + 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x4c, 0x6f, 0x67, 0x52, 0x04, 0x6c, + 0x6f, 0x67, 0x73, 0x22, 0x47, 0x0a, 0x17, 0x42, 0x61, 0x74, 0x63, 0x68, 0x43, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2c, + 0x0a, 0x12, 0x6c, 0x6f, 0x67, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x5f, 0x65, 0x78, 0x63, 0x65, + 0x65, 0x64, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x6c, 0x6f, 0x67, 0x4c, + 0x69, 0x6d, 0x69, 0x74, 0x45, 0x78, 0x63, 0x65, 0x65, 0x64, 0x65, 0x64, 0x22, 0x1f, 0x0a, 0x1d, + 0x47, 0x65, 0x74, 0x41, 0x6e, 0x6e, 0x6f, 0x75, 0x6e, 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, + 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x71, 0x0a, + 0x1e, 0x47, 0x65, 0x74, 0x41, 0x6e, 0x6e, 0x6f, 0x75, 0x6e, 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, + 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x4f, 0x0a, 0x14, 0x61, 0x6e, 0x6e, 0x6f, 0x75, 0x6e, 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x5f, + 0x62, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, + 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x42, + 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x13, 0x61, 0x6e, 0x6e, + 0x6f, 0x75, 0x6e, 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x73, + 0x22, 0x6d, 0x0a, 0x0c, 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x12, 0x29, 0x0a, 0x10, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, + 0x6e, 0x64, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, + 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x22, + 0x56, 0x0a, 0x24, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x41, 0x67, 0x65, 0x6e, + 0x74, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2e, 0x0a, 0x06, 0x74, 0x69, 0x6d, 0x69, 0x6e, + 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, + 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x54, 0x69, 0x6d, 0x69, 0x6e, 0x67, 0x52, + 0x06, 0x74, 0x69, 0x6d, 0x69, 0x6e, 0x67, 0x22, 0x27, 0x0a, 0x25, 0x57, 0x6f, 0x72, 0x6b, 0x73, + 0x70, 0x61, 0x63, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x43, + 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0xbe, 0x02, 0x0a, 0x06, 0x54, 0x69, 0x6d, 0x69, 0x6e, 0x67, 0x12, 0x1b, 0x0a, 0x09, 0x73, + 0x63, 0x72, 0x69, 0x70, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, + 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x64, 0x69, 0x73, 0x70, + 0x6c, 0x61, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, + 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x30, 0x0a, 0x05, 0x73, + 0x74, 0x61, 0x72, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, - 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, - 0x74, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x12, 0x2f, 0x0a, 0x05, 0x6c, 0x65, 0x76, - 0x65, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x19, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, - 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x4c, 0x6f, 0x67, 0x2e, 0x4c, 0x65, - 0x76, 0x65, 0x6c, 0x52, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x22, 0x53, 0x0a, 0x05, 0x4c, 0x65, - 0x76, 0x65, 0x6c, 0x12, 0x15, 0x0a, 0x11, 0x4c, 0x45, 0x56, 0x45, 0x4c, 0x5f, 0x55, 0x4e, 0x53, - 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x54, 0x52, - 0x41, 0x43, 0x45, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x44, 0x45, 0x42, 0x55, 0x47, 0x10, 0x02, - 0x12, 0x08, 0x0a, 0x04, 0x49, 0x4e, 0x46, 0x4f, 0x10, 0x03, 0x12, 0x08, 0x0a, 0x04, 0x57, 0x41, - 0x52, 0x4e, 0x10, 0x04, 0x12, 0x09, 0x0a, 0x05, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x05, 0x22, - 0x65, 0x0a, 0x16, 0x42, 0x61, 0x74, 0x63, 0x68, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4c, 0x6f, - 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x22, 0x0a, 0x0d, 0x6c, 0x6f, 0x67, - 0x5f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, - 0x52, 0x0b, 0x6c, 0x6f, 0x67, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x64, 0x12, 0x27, 0x0a, - 0x04, 0x6c, 0x6f, 0x67, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x63, 0x6f, - 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x4c, 0x6f, 0x67, - 0x52, 0x04, 0x6c, 0x6f, 0x67, 0x73, 0x22, 0x47, 0x0a, 0x17, 0x42, 0x61, 0x74, 0x63, 0x68, 0x43, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x2c, 0x0a, 0x12, 0x6c, 0x6f, 0x67, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x5f, 0x65, - 0x78, 0x63, 0x65, 0x65, 0x64, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x6c, - 0x6f, 0x67, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x45, 0x78, 0x63, 0x65, 0x65, 0x64, 0x65, 0x64, 0x22, - 0x1f, 0x0a, 0x1d, 0x47, 0x65, 0x74, 0x41, 0x6e, 0x6e, 0x6f, 0x75, 0x6e, 0x63, 0x65, 0x6d, 0x65, - 0x6e, 0x74, 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x22, 0x71, 0x0a, 0x1e, 0x47, 0x65, 0x74, 0x41, 0x6e, 0x6e, 0x6f, 0x75, 0x6e, 0x63, 0x65, 0x6d, - 0x65, 0x6e, 0x74, 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x4f, 0x0a, 0x14, 0x61, 0x6e, 0x6e, 0x6f, 0x75, 0x6e, 0x63, 0x65, 0x6d, 0x65, - 0x6e, 0x74, 0x5f, 0x62, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x1c, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, - 0x32, 0x2e, 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x13, - 0x61, 0x6e, 0x6e, 0x6f, 0x75, 0x6e, 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x61, 0x6e, 0x6e, - 0x65, 0x72, 0x73, 0x22, 0x6d, 0x0a, 0x0c, 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x43, 0x6f, 0x6e, - 0x66, 0x69, 0x67, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x18, 0x0a, - 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, - 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x29, 0x0a, 0x10, 0x62, 0x61, 0x63, 0x6b, 0x67, - 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0f, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x43, 0x6f, 0x6c, - 0x6f, 0x72, 0x22, 0x56, 0x0a, 0x24, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x41, - 0x67, 0x65, 0x6e, 0x74, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, - 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2e, 0x0a, 0x06, 0x74, 0x69, - 0x6d, 0x69, 0x6e, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x63, 0x6f, 0x64, - 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x54, 0x69, 0x6d, 0x69, - 0x6e, 0x67, 0x52, 0x06, 0x74, 0x69, 0x6d, 0x69, 0x6e, 0x67, 0x22, 0x27, 0x0a, 0x25, 0x57, 0x6f, - 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x53, 0x63, 0x72, 0x69, - 0x70, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0xbe, 0x02, 0x0a, 0x06, 0x54, 0x69, 0x6d, 0x69, 0x6e, 0x67, 0x12, 0x1b, - 0x0a, 0x09, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x08, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x64, - 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x30, - 0x0a, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, - 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, - 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, - 0x12, 0x2c, 0x0a, 0x03, 0x65, 0x6e, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, - 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, - 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x03, 0x65, 0x6e, 0x64, 0x12, 0x1b, - 0x0a, 0x09, 0x65, 0x78, 0x69, 0x74, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, - 0x05, 0x52, 0x08, 0x65, 0x78, 0x69, 0x74, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x32, 0x0a, 0x05, 0x73, - 0x74, 0x61, 0x67, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1c, 0x2e, 0x63, 0x6f, 0x64, - 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x54, 0x69, 0x6d, 0x69, - 0x6e, 0x67, 0x2e, 0x53, 0x74, 0x61, 0x67, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x67, 0x65, 0x12, - 0x1b, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x64, 0x5f, 0x6f, 0x75, 0x74, 0x18, 0x07, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x08, 0x74, 0x69, 0x6d, 0x65, 0x64, 0x4f, 0x75, 0x74, 0x22, 0x26, 0x0a, 0x05, - 0x53, 0x74, 0x61, 0x67, 0x65, 0x12, 0x09, 0x0a, 0x05, 0x53, 0x54, 0x41, 0x52, 0x54, 0x10, 0x00, - 0x12, 0x08, 0x0a, 0x04, 0x53, 0x54, 0x4f, 0x50, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x43, 0x52, - 0x4f, 0x4e, 0x10, 0x02, 0x2a, 0x63, 0x0a, 0x09, 0x41, 0x70, 0x70, 0x48, 0x65, 0x61, 0x6c, 0x74, - 0x68, 0x12, 0x1a, 0x0a, 0x16, 0x41, 0x50, 0x50, 0x5f, 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, 0x5f, - 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0c, 0x0a, - 0x08, 0x44, 0x49, 0x53, 0x41, 0x42, 0x4c, 0x45, 0x44, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x49, - 0x4e, 0x49, 0x54, 0x49, 0x41, 0x4c, 0x49, 0x5a, 0x49, 0x4e, 0x47, 0x10, 0x02, 0x12, 0x0b, 0x0a, - 0x07, 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, 0x59, 0x10, 0x03, 0x12, 0x0d, 0x0a, 0x09, 0x55, 0x4e, - 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, 0x59, 0x10, 0x04, 0x32, 0xef, 0x07, 0x0a, 0x05, 0x41, 0x67, - 0x65, 0x6e, 0x74, 0x12, 0x4b, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, - 0x73, 0x74, 0x12, 0x22, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, - 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, - 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, - 0x12, 0x5a, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x42, 0x61, - 0x6e, 0x6e, 0x65, 0x72, 0x12, 0x27, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, - 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, - 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x53, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x12, 0x56, 0x0a, 0x0b, - 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x22, 0x2e, 0x63, 0x6f, - 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x70, 0x64, - 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x23, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, - 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x54, 0x0a, 0x0f, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4c, 0x69, - 0x66, 0x65, 0x63, 0x79, 0x63, 0x6c, 0x65, 0x12, 0x26, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, - 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4c, - 0x69, 0x66, 0x65, 0x63, 0x79, 0x63, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x19, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, - 0x2e, 0x4c, 0x69, 0x66, 0x65, 0x63, 0x79, 0x63, 0x6c, 0x65, 0x12, 0x72, 0x0a, 0x15, 0x42, 0x61, - 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x70, 0x70, 0x48, 0x65, 0x61, 0x6c, - 0x74, 0x68, 0x73, 0x12, 0x2b, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, - 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x41, 0x70, 0x70, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x2c, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, + 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x12, 0x2c, 0x0a, + 0x03, 0x65, 0x6e, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, + 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x03, 0x65, 0x6e, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x65, + 0x78, 0x69, 0x74, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, + 0x65, 0x78, 0x69, 0x74, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x32, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x67, + 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1c, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, + 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x54, 0x69, 0x6d, 0x69, 0x6e, 0x67, 0x2e, + 0x53, 0x74, 0x61, 0x67, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x67, 0x65, 0x12, 0x1b, 0x0a, 0x09, + 0x74, 0x69, 0x6d, 0x65, 0x64, 0x5f, 0x6f, 0x75, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x08, 0x74, 0x69, 0x6d, 0x65, 0x64, 0x4f, 0x75, 0x74, 0x22, 0x26, 0x0a, 0x05, 0x53, 0x74, 0x61, + 0x67, 0x65, 0x12, 0x09, 0x0a, 0x05, 0x53, 0x54, 0x41, 0x52, 0x54, 0x10, 0x00, 0x12, 0x08, 0x0a, + 0x04, 0x53, 0x54, 0x4f, 0x50, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x43, 0x52, 0x4f, 0x4e, 0x10, + 0x02, 0x2a, 0x63, 0x0a, 0x09, 0x41, 0x70, 0x70, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x12, 0x1a, + 0x0a, 0x16, 0x41, 0x50, 0x50, 0x5f, 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, 0x5f, 0x55, 0x4e, 0x53, + 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x44, 0x49, + 0x53, 0x41, 0x42, 0x4c, 0x45, 0x44, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x49, 0x4e, 0x49, 0x54, + 0x49, 0x41, 0x4c, 0x49, 0x5a, 0x49, 0x4e, 0x47, 0x10, 0x02, 0x12, 0x0b, 0x0a, 0x07, 0x48, 0x45, + 0x41, 0x4c, 0x54, 0x48, 0x59, 0x10, 0x03, 0x12, 0x0d, 0x0a, 0x09, 0x55, 0x4e, 0x48, 0x45, 0x41, + 0x4c, 0x54, 0x48, 0x59, 0x10, 0x04, 0x32, 0xef, 0x07, 0x0a, 0x05, 0x41, 0x67, 0x65, 0x6e, 0x74, + 0x12, 0x4b, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x12, + 0x22, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, + 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, + 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x12, 0x5a, 0x0a, + 0x10, 0x47, 0x65, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x42, 0x61, 0x6e, 0x6e, 0x65, + 0x72, 0x12, 0x27, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, + 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x42, 0x61, 0x6e, + 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x63, 0x6f, 0x64, + 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x12, 0x56, 0x0a, 0x0b, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x22, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, + 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x63, + 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x54, 0x0a, 0x0f, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4c, 0x69, 0x66, 0x65, 0x63, + 0x79, 0x63, 0x6c, 0x65, 0x12, 0x26, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, + 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4c, 0x69, 0x66, 0x65, + 0x63, 0x79, 0x63, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x63, + 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x4c, 0x69, + 0x66, 0x65, 0x63, 0x79, 0x63, 0x6c, 0x65, 0x12, 0x72, 0x0a, 0x15, 0x42, 0x61, 0x74, 0x63, 0x68, + 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x70, 0x70, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x73, + 0x12, 0x2b, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x70, 0x70, - 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4e, - 0x0a, 0x0d, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x12, - 0x24, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, - 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, - 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x12, 0x6e, - 0x0a, 0x13, 0x42, 0x61, 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x74, - 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x2a, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, - 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x2b, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, - 0x76, 0x32, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x65, - 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x62, - 0x0a, 0x0f, 0x42, 0x61, 0x74, 0x63, 0x68, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4c, 0x6f, 0x67, - 0x73, 0x12, 0x26, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, - 0x76, 0x32, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4c, 0x6f, - 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x63, 0x6f, 0x64, 0x65, - 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, - 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x77, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x41, 0x6e, 0x6e, 0x6f, 0x75, 0x6e, 0x63, - 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x73, 0x12, 0x2d, 0x2e, 0x63, - 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, - 0x74, 0x41, 0x6e, 0x6e, 0x6f, 0x75, 0x6e, 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x61, 0x6e, - 0x6e, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x63, 0x6f, - 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, - 0x41, 0x6e, 0x6e, 0x6f, 0x75, 0x6e, 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x61, 0x6e, 0x6e, - 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7e, 0x0a, 0x0f, 0x53, - 0x63, 0x72, 0x69, 0x70, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x12, 0x34, + 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, + 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x42, + 0x61, 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x70, 0x70, 0x48, 0x65, 0x61, + 0x6c, 0x74, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4e, 0x0a, 0x0d, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x12, 0x24, 0x2e, 0x63, + 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, + 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x12, 0x6e, 0x0a, 0x13, 0x42, + 0x61, 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, + 0x74, 0x61, 0x12, 0x2a, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, + 0x2e, 0x76, 0x32, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, - 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x53, 0x63, - 0x72, 0x69, 0x70, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x35, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, - 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x41, - 0x67, 0x65, 0x6e, 0x74, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, - 0x74, 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x27, 0x5a, 0x25, 0x67, - 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2f, - 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2f, 0x76, 0x32, 0x2f, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2f, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x42, 0x61, 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x62, 0x0a, 0x0f, 0x42, + 0x61, 0x74, 0x63, 0x68, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4c, 0x6f, 0x67, 0x73, 0x12, 0x26, + 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, + 0x42, 0x61, 0x74, 0x63, 0x68, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4c, 0x6f, 0x67, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, + 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x43, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x77, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x41, 0x6e, 0x6e, 0x6f, 0x75, 0x6e, 0x63, 0x65, 0x6d, 0x65, + 0x6e, 0x74, 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x73, 0x12, 0x2d, 0x2e, 0x63, 0x6f, 0x64, 0x65, + 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x6e, + 0x6e, 0x6f, 0x75, 0x6e, 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, + 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x6e, 0x6e, + 0x6f, 0x75, 0x6e, 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7e, 0x0a, 0x0f, 0x53, 0x63, 0x72, 0x69, + 0x70, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x12, 0x34, 0x2e, 0x63, 0x6f, + 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x57, 0x6f, 0x72, + 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x53, 0x63, 0x72, 0x69, 0x70, + 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x35, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, + 0x76, 0x32, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x41, 0x67, 0x65, 0x6e, + 0x74, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x27, 0x5a, 0x25, 0x67, 0x69, 0x74, 0x68, + 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2f, 0x63, 0x6f, 0x64, + 0x65, 0x72, 0x2f, 0x76, 0x32, 0x2f, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2f, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/agent/proto/agent.proto b/agent/proto/agent.proto index cab148b96a2ba..3552612f7d728 100644 --- a/agent/proto/agent.proto +++ b/agent/proto/agent.proto @@ -53,7 +53,6 @@ message WorkspaceAgentScript { bool run_on_stop = 6; bool start_blocks_login = 7; google.protobuf.Duration timeout = 8; - string display_name = 9; bytes id = 10; } diff --git a/coderd/agentapi/manifest.go b/coderd/agentapi/manifest.go index b3ad5edc484f8..a58bf6941cb04 100644 --- a/coderd/agentapi/manifest.go +++ b/coderd/agentapi/manifest.go @@ -179,7 +179,6 @@ func dbAgentScriptsToProto(scripts []database.WorkspaceAgentScript) []*agentprot func dbAgentScriptToProto(script database.WorkspaceAgentScript) *agentproto.WorkspaceAgentScript { return &agentproto.WorkspaceAgentScript{ Id: script.ID[:], - DisplayName: script.DisplayName, LogSourceId: script.LogSourceID[:], LogPath: script.LogPath, Script: script.Script, diff --git a/coderd/database/dbmem/dbmem.go b/coderd/database/dbmem/dbmem.go index f52ddfd37352b..e94c3dd70992c 100644 --- a/coderd/database/dbmem/dbmem.go +++ b/coderd/database/dbmem/dbmem.go @@ -7867,7 +7867,6 @@ func (q *FakeQuerier) InsertWorkspaceAgentScripts(_ context.Context, arg databas LogSourceID: source, WorkspaceAgentID: arg.WorkspaceAgentID, ID: arg.ID[index], - DisplayName: arg.DisplayName[index], LogPath: arg.LogPath[index], Script: arg.Script[index], Cron: arg.Cron[index], diff --git a/coderd/database/dump.sql b/coderd/database/dump.sql index eb87e0e0cb749..d230a8be40ffd 100644 --- a/coderd/database/dump.sql +++ b/coderd/database/dump.sql @@ -1382,8 +1382,7 @@ CREATE TABLE workspace_agent_scripts ( run_on_start boolean NOT NULL, run_on_stop boolean NOT NULL, timeout_seconds integer NOT NULL, - id uuid DEFAULT gen_random_uuid() NOT NULL, - display_name text DEFAULT ''::text NOT NULL + id uuid DEFAULT gen_random_uuid() NOT NULL ); CREATE SEQUENCE workspace_agent_startup_logs_id_seq diff --git a/coderd/database/migrations/000256_workspace_agent_script_timings.down.sql b/coderd/database/migrations/000257_workspace_agent_script_timings.down.sql similarity index 73% rename from coderd/database/migrations/000256_workspace_agent_script_timings.down.sql rename to coderd/database/migrations/000257_workspace_agent_script_timings.down.sql index 364c56ab75c8d..32c1980a08379 100644 --- a/coderd/database/migrations/000256_workspace_agent_script_timings.down.sql +++ b/coderd/database/migrations/000257_workspace_agent_script_timings.down.sql @@ -1,5 +1,4 @@ DROP TYPE IF EXISTS workspace_agent_script_timing_stage CASCADE; DROP TABLE IF EXISTS workspace_agent_script_timings; -ALTER TABLE workspace_agent_scripts DROP COLUMN display_name; ALTER TABLE workspace_agent_scripts DROP COLUMN id; diff --git a/coderd/database/migrations/000256_workspace_agent_script_timings.up.sql b/coderd/database/migrations/000257_workspace_agent_script_timings.up.sql similarity index 89% rename from coderd/database/migrations/000256_workspace_agent_script_timings.up.sql rename to coderd/database/migrations/000257_workspace_agent_script_timings.up.sql index 58bbaadfdfc95..0d9092ce233af 100644 --- a/coderd/database/migrations/000256_workspace_agent_script_timings.up.sql +++ b/coderd/database/migrations/000257_workspace_agent_script_timings.up.sql @@ -1,5 +1,4 @@ ALTER TABLE workspace_agent_scripts ADD COLUMN id uuid UNIQUE NOT NULL DEFAULT gen_random_uuid(); -ALTER TABLE workspace_agent_scripts ADD COLUMN display_name text NOT NULL DEFAULT ''; CREATE TYPE workspace_agent_script_timing_stage AS ENUM ( 'start', diff --git a/coderd/database/migrations/testdata/fixtures/000256_workspace_agent_script_timings.up.sql b/coderd/database/migrations/testdata/fixtures/000257_workspace_agent_script_timings.up.sql similarity index 100% rename from coderd/database/migrations/testdata/fixtures/000256_workspace_agent_script_timings.up.sql rename to coderd/database/migrations/testdata/fixtures/000257_workspace_agent_script_timings.up.sql diff --git a/coderd/database/models.go b/coderd/database/models.go index ec29e0012a529..786daadc550a2 100644 --- a/coderd/database/models.go +++ b/coderd/database/models.go @@ -2942,7 +2942,6 @@ type WorkspaceAgentScript struct { RunOnStop bool `db:"run_on_stop" json:"run_on_stop"` TimeoutSeconds int32 `db:"timeout_seconds" json:"timeout_seconds"` ID uuid.UUID `db:"id" json:"id"` - DisplayName string `db:"display_name" json:"display_name"` } type WorkspaceAgentScriptTiming struct { diff --git a/coderd/database/queries.sql.go b/coderd/database/queries.sql.go index 813e5e38b9abf..1506f7c851b12 100644 --- a/coderd/database/queries.sql.go +++ b/coderd/database/queries.sql.go @@ -15540,7 +15540,7 @@ func (q *sqlQuerier) UpdateWorkspacesDormantDeletingAtByTemplateID(ctx context.C } const getWorkspaceAgentScriptsByAgentIDs = `-- name: GetWorkspaceAgentScriptsByAgentIDs :many -SELECT workspace_agent_id, log_source_id, log_path, created_at, script, cron, start_blocks_login, run_on_start, run_on_stop, timeout_seconds, id, display_name FROM workspace_agent_scripts WHERE workspace_agent_id = ANY($1 :: uuid [ ]) +SELECT workspace_agent_id, log_source_id, log_path, created_at, script, cron, start_blocks_login, run_on_start, run_on_stop, timeout_seconds, id FROM workspace_agent_scripts WHERE workspace_agent_id = ANY($1 :: uuid [ ]) ` func (q *sqlQuerier) GetWorkspaceAgentScriptsByAgentIDs(ctx context.Context, ids []uuid.UUID) ([]WorkspaceAgentScript, error) { @@ -15564,7 +15564,6 @@ func (q *sqlQuerier) GetWorkspaceAgentScriptsByAgentIDs(ctx context.Context, ids &i.RunOnStop, &i.TimeoutSeconds, &i.ID, - &i.DisplayName, ); err != nil { return nil, err } @@ -15593,9 +15592,8 @@ SELECT unnest($8 :: boolean [ ]) AS run_on_start, unnest($9 :: boolean [ ]) AS run_on_stop, unnest($10 :: integer [ ]) AS timeout_seconds, - unnest($11 :: text [ ]) AS display_name, - unnest($12 :: uuid [ ]) AS id -RETURNING workspace_agent_scripts.workspace_agent_id, workspace_agent_scripts.log_source_id, workspace_agent_scripts.log_path, workspace_agent_scripts.created_at, workspace_agent_scripts.script, workspace_agent_scripts.cron, workspace_agent_scripts.start_blocks_login, workspace_agent_scripts.run_on_start, workspace_agent_scripts.run_on_stop, workspace_agent_scripts.timeout_seconds, workspace_agent_scripts.id, workspace_agent_scripts.display_name + unnest($11 :: uuid [ ]) AS id +RETURNING workspace_agent_scripts.workspace_agent_id, workspace_agent_scripts.log_source_id, workspace_agent_scripts.log_path, workspace_agent_scripts.created_at, workspace_agent_scripts.script, workspace_agent_scripts.cron, workspace_agent_scripts.start_blocks_login, workspace_agent_scripts.run_on_start, workspace_agent_scripts.run_on_stop, workspace_agent_scripts.timeout_seconds, workspace_agent_scripts.id ` type InsertWorkspaceAgentScriptsParams struct { @@ -15609,7 +15607,6 @@ type InsertWorkspaceAgentScriptsParams struct { RunOnStart []bool `db:"run_on_start" json:"run_on_start"` RunOnStop []bool `db:"run_on_stop" json:"run_on_stop"` TimeoutSeconds []int32 `db:"timeout_seconds" json:"timeout_seconds"` - DisplayName []string `db:"display_name" json:"display_name"` ID []uuid.UUID `db:"id" json:"id"` } @@ -15625,7 +15622,6 @@ func (q *sqlQuerier) InsertWorkspaceAgentScripts(ctx context.Context, arg Insert pq.Array(arg.RunOnStart), pq.Array(arg.RunOnStop), pq.Array(arg.TimeoutSeconds), - pq.Array(arg.DisplayName), pq.Array(arg.ID), ) if err != nil { @@ -15647,7 +15643,6 @@ func (q *sqlQuerier) InsertWorkspaceAgentScripts(ctx context.Context, arg Insert &i.RunOnStop, &i.TimeoutSeconds, &i.ID, - &i.DisplayName, ); err != nil { return nil, err } diff --git a/coderd/database/queries/workspacescripts.sql b/coderd/database/queries/workspacescripts.sql index 671a37dfa1e08..3aeb9bf1db503 100644 --- a/coderd/database/queries/workspacescripts.sql +++ b/coderd/database/queries/workspacescripts.sql @@ -12,7 +12,6 @@ SELECT unnest(@run_on_start :: boolean [ ]) AS run_on_start, unnest(@run_on_stop :: boolean [ ]) AS run_on_stop, unnest(@timeout_seconds :: integer [ ]) AS timeout_seconds, - unnest(@display_name :: text [ ]) AS display_name, unnest(@id :: uuid [ ]) AS id RETURNING workspace_agent_scripts.*; diff --git a/coderd/provisionerdserver/provisionerdserver.go b/coderd/provisionerdserver/provisionerdserver.go index 2db5bbd1062b1..f1ec6cf197139 100644 --- a/coderd/provisionerdserver/provisionerdserver.go +++ b/coderd/provisionerdserver/provisionerdserver.go @@ -1865,7 +1865,6 @@ func InsertWorkspaceResource(ctx context.Context, db database.Store, jobID uuid. StartBlocksLogin: scriptStartBlocksLogin, RunOnStart: scriptRunOnStart, RunOnStop: scriptRunOnStop, - DisplayName: scriptDisplayName, ID: scriptIDs, }) if err != nil { diff --git a/coderd/workspaceagents.go b/coderd/workspaceagents.go index 6b2d771f21974..b86ff2705f6a9 100644 --- a/coderd/workspaceagents.go +++ b/coderd/workspaceagents.go @@ -970,7 +970,6 @@ func convertScripts(dbScripts []database.WorkspaceAgentScript) []codersdk.Worksp for _, dbScript := range dbScripts { scripts = append(scripts, codersdk.WorkspaceAgentScript{ ID: dbScript.ID, - DisplayName: dbScript.DisplayName, LogPath: dbScript.LogPath, LogSourceID: dbScript.LogSourceID, Script: dbScript.Script, diff --git a/codersdk/agentsdk/convert.go b/codersdk/agentsdk/convert.go index 8b47563089b78..c8503d37c090d 100644 --- a/codersdk/agentsdk/convert.go +++ b/codersdk/agentsdk/convert.go @@ -171,7 +171,6 @@ func AgentScriptFromProto(protoScript *proto.WorkspaceAgentScript) (codersdk.Wor return codersdk.WorkspaceAgentScript{ ID: id, LogSourceID: logSourceID, - DisplayName: protoScript.DisplayName, LogPath: protoScript.LogPath, Script: protoScript.Script, Cron: protoScript.Cron, @@ -185,7 +184,6 @@ func AgentScriptFromProto(protoScript *proto.WorkspaceAgentScript) (codersdk.Wor func ProtoFromScript(s codersdk.WorkspaceAgentScript) *proto.WorkspaceAgentScript { return &proto.WorkspaceAgentScript{ Id: s.ID[:], - DisplayName: s.DisplayName, LogSourceId: s.LogSourceID[:], LogPath: s.LogPath, Script: s.Script, From 08a466ac7158493cc6ebae9a69daac52ff1a9833 Mon Sep 17 00:00:00 2001 From: Danielle Maywood Date: Fri, 20 Sep 2024 14:03:57 +0000 Subject: [PATCH 43/56] fix: get tests passing --- coderd/database/dump.sql | 1 + site/src/testHelpers/entities.ts | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/coderd/database/dump.sql b/coderd/database/dump.sql index 69cb13d2902f4..d9fb663b8cdca 100644 --- a/coderd/database/dump.sql +++ b/coderd/database/dump.sql @@ -2295,3 +2295,4 @@ ALTER TABLE ONLY workspaces ALTER TABLE ONLY workspaces ADD CONSTRAINT workspaces_template_id_fkey FOREIGN KEY (template_id) REFERENCES templates(id) ON DELETE RESTRICT; + diff --git a/site/src/testHelpers/entities.ts b/site/src/testHelpers/entities.ts index 4d75912fcb517..9bd865b127c42 100644 --- a/site/src/testHelpers/entities.ts +++ b/site/src/testHelpers/entities.ts @@ -887,7 +887,6 @@ export const MockWorkspaceAgentLogSource: TypesGen.WorkspaceAgentLogSource = { export const MockWorkspaceAgentScript: TypesGen.WorkspaceAgentScript = { id: "08eaca83-1221-4fad-b882-d1136981f54d", - display_name: "", log_source_id: MockWorkspaceAgentLogSource.id, cron: "", log_path: "", From 8e7c7573105f0b1ba19287055117ada12f56d1a2 Mon Sep 17 00:00:00 2001 From: Danielle Maywood Date: Fri, 20 Sep 2024 14:12:57 +0000 Subject: [PATCH 44/56] fix: remove space in sql up --- .../migrations/000257_workspace_agent_script_timings.up.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coderd/database/migrations/000257_workspace_agent_script_timings.up.sql b/coderd/database/migrations/000257_workspace_agent_script_timings.up.sql index 0d9092ce233af..cb619b820a62a 100644 --- a/coderd/database/migrations/000257_workspace_agent_script_timings.up.sql +++ b/coderd/database/migrations/000257_workspace_agent_script_timings.up.sql @@ -1,4 +1,4 @@ -ALTER TABLE workspace_agent_scripts ADD COLUMN id uuid UNIQUE NOT NULL DEFAULT gen_random_uuid(); +ALTER TABLE workspace_agent_scripts ADD COLUMN id uuid UNIQUE NOT NULL DEFAULT gen_random_uuid(); CREATE TYPE workspace_agent_script_timing_stage AS ENUM ( 'start', From 621071e604d6f1c9b7c3b65d7090e907400839a4 Mon Sep 17 00:00:00 2001 From: Danielle Maywood Date: Fri, 20 Sep 2024 14:25:44 +0000 Subject: [PATCH 45/56] docs: document ExecuteOption --- agent/agentscripts/agentscripts.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/agent/agentscripts/agentscripts.go b/agent/agentscripts/agentscripts.go index 257489ded5547..e332ad3ffaaa1 100644 --- a/agent/agentscripts/agentscripts.go +++ b/agent/agentscripts/agentscripts.go @@ -179,8 +179,10 @@ func (r *Runner) StartCron() { } } +// ExecuteOption describes what scripts we want to execute. type ExecuteOption int +// ExecuteOption enums. const ( ExecuteAllScripts ExecuteOption = iota ExecuteStartScripts From 3b4df924a165c53355c38178b037f5b0cd247708 Mon Sep 17 00:00:00 2001 From: Danielle Maywood Date: Fri, 20 Sep 2024 14:43:50 +0000 Subject: [PATCH 46/56] fix: drop 'RETURNING' from sql --- coderd/agentapi/scripts.go | 2 +- coderd/database/dbauthz/dbauthz.go | 4 +-- coderd/database/dbmem/dbmem.go | 29 ++++++++++----------- coderd/database/dbmetrics/dbmetrics.go | 6 ++--- coderd/database/dbmock/dbmock.go | 7 +++-- coderd/database/querier.go | 2 +- coderd/database/queries.sql.go | 20 ++++---------- coderd/database/queries/workspaceagents.sql | 4 +-- 8 files changed, 31 insertions(+), 43 deletions(-) diff --git a/coderd/agentapi/scripts.go b/coderd/agentapi/scripts.go index 36185e8493e9c..116558373ee9f 100644 --- a/coderd/agentapi/scripts.go +++ b/coderd/agentapi/scripts.go @@ -32,7 +32,7 @@ func (s *ScriptsAPI) ScriptCompleted(ctx context.Context, req *agentproto.Worksp stage = database.WorkspaceAgentScriptTimingStageCron } - _, err = s.Database.InsertWorkspaceAgentScriptTimings(ctx, database.InsertWorkspaceAgentScriptTimingsParams{ + err = s.Database.InsertWorkspaceAgentScriptTimings(ctx, database.InsertWorkspaceAgentScriptTimingsParams{ ScriptID: scriptID, Stage: stage, DisplayName: req.Timing.DisplayName, diff --git a/coderd/database/dbauthz/dbauthz.go b/coderd/database/dbauthz/dbauthz.go index 483dbfdf84a83..83ad60bb8351e 100644 --- a/coderd/database/dbauthz/dbauthz.go +++ b/coderd/database/dbauthz/dbauthz.go @@ -3027,9 +3027,9 @@ func (q *querier) InsertWorkspaceAgentMetadata(ctx context.Context, arg database return q.db.InsertWorkspaceAgentMetadata(ctx, arg) } -func (q *querier) InsertWorkspaceAgentScriptTimings(ctx context.Context, arg database.InsertWorkspaceAgentScriptTimingsParams) (database.WorkspaceAgentScriptTiming, error) { +func (q *querier) InsertWorkspaceAgentScriptTimings(ctx context.Context, arg database.InsertWorkspaceAgentScriptTimingsParams) error { if err := q.authorizeContext(ctx, policy.ActionCreate, rbac.ResourceSystem); err != nil { - return database.WorkspaceAgentScriptTiming{}, err + return err } return q.db.InsertWorkspaceAgentScriptTimings(ctx, arg) } diff --git a/coderd/database/dbmem/dbmem.go b/coderd/database/dbmem/dbmem.go index e94c3dd70992c..972748adbaf85 100644 --- a/coderd/database/dbmem/dbmem.go +++ b/coderd/database/dbmem/dbmem.go @@ -7827,29 +7827,28 @@ func (q *FakeQuerier) InsertWorkspaceAgentMetadata(_ context.Context, arg databa return nil } -func (q *FakeQuerier) InsertWorkspaceAgentScriptTimings(_ context.Context, arg database.InsertWorkspaceAgentScriptTimingsParams) (database.WorkspaceAgentScriptTiming, error) { +func (q *FakeQuerier) InsertWorkspaceAgentScriptTimings(_ context.Context, arg database.InsertWorkspaceAgentScriptTimingsParams) error { err := validateDatabaseType(arg) if err != nil { - return database.WorkspaceAgentScriptTiming{}, err + return err } q.mutex.Lock() defer q.mutex.Unlock() - //nolint:gosimple // Stop linter suggesting 'arg' should be of type database.WorkspaceAgentScriptTiming - scriptTiming := database.WorkspaceAgentScriptTiming{ - ScriptID: arg.ScriptID, - StartedAt: arg.StartedAt, - EndedAt: arg.EndedAt, - ExitCode: arg.ExitCode, - DisplayName: arg.DisplayName, - Stage: arg.Stage, - TimedOut: arg.TimedOut, - } - - q.workspaceAgentScriptTimings = append(q.workspaceAgentScriptTimings, scriptTiming) + q.workspaceAgentScriptTimings = append(q.workspaceAgentScriptTimings, + database.WorkspaceAgentScriptTiming{ + ScriptID: arg.ScriptID, + StartedAt: arg.StartedAt, + EndedAt: arg.EndedAt, + ExitCode: arg.ExitCode, + DisplayName: arg.DisplayName, + Stage: arg.Stage, + TimedOut: arg.TimedOut, + }, + ) - return scriptTiming, nil + return nil } func (q *FakeQuerier) InsertWorkspaceAgentScripts(_ context.Context, arg database.InsertWorkspaceAgentScriptsParams) ([]database.WorkspaceAgentScript, error) { diff --git a/coderd/database/dbmetrics/dbmetrics.go b/coderd/database/dbmetrics/dbmetrics.go index 37855f29aed18..afdd6e35a14a2 100644 --- a/coderd/database/dbmetrics/dbmetrics.go +++ b/coderd/database/dbmetrics/dbmetrics.go @@ -1929,11 +1929,11 @@ func (m metricsStore) InsertWorkspaceAgentMetadata(ctx context.Context, arg data return err } -func (m metricsStore) InsertWorkspaceAgentScriptTimings(ctx context.Context, arg database.InsertWorkspaceAgentScriptTimingsParams) (database.WorkspaceAgentScriptTiming, error) { +func (m metricsStore) InsertWorkspaceAgentScriptTimings(ctx context.Context, arg database.InsertWorkspaceAgentScriptTimingsParams) error { start := time.Now() - r0, r1 := m.s.InsertWorkspaceAgentScriptTimings(ctx, arg) + err := m.s.InsertWorkspaceAgentScriptTimings(ctx, arg) m.queryLatencies.WithLabelValues("InsertWorkspaceAgentScriptTimings").Observe(time.Since(start).Seconds()) - return r0, r1 + return err } func (m metricsStore) InsertWorkspaceAgentScripts(ctx context.Context, arg database.InsertWorkspaceAgentScriptsParams) ([]database.WorkspaceAgentScript, error) { diff --git a/coderd/database/dbmock/dbmock.go b/coderd/database/dbmock/dbmock.go index 7647aef27271f..d85f29e154f17 100644 --- a/coderd/database/dbmock/dbmock.go +++ b/coderd/database/dbmock/dbmock.go @@ -4065,12 +4065,11 @@ func (mr *MockStoreMockRecorder) InsertWorkspaceAgentMetadata(arg0, arg1 any) *g } // InsertWorkspaceAgentScriptTimings mocks base method. -func (m *MockStore) InsertWorkspaceAgentScriptTimings(arg0 context.Context, arg1 database.InsertWorkspaceAgentScriptTimingsParams) (database.WorkspaceAgentScriptTiming, error) { +func (m *MockStore) InsertWorkspaceAgentScriptTimings(arg0 context.Context, arg1 database.InsertWorkspaceAgentScriptTimingsParams) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "InsertWorkspaceAgentScriptTimings", arg0, arg1) - ret0, _ := ret[0].(database.WorkspaceAgentScriptTiming) - ret1, _ := ret[1].(error) - return ret0, ret1 + ret0, _ := ret[0].(error) + return ret0 } // InsertWorkspaceAgentScriptTimings indicates an expected call of InsertWorkspaceAgentScriptTimings. diff --git a/coderd/database/querier.go b/coderd/database/querier.go index 1505d084c1dc4..46086fa72d072 100644 --- a/coderd/database/querier.go +++ b/coderd/database/querier.go @@ -394,7 +394,7 @@ type sqlcQuerier interface { InsertWorkspaceAgentLogSources(ctx context.Context, arg InsertWorkspaceAgentLogSourcesParams) ([]WorkspaceAgentLogSource, error) InsertWorkspaceAgentLogs(ctx context.Context, arg InsertWorkspaceAgentLogsParams) ([]WorkspaceAgentLog, error) InsertWorkspaceAgentMetadata(ctx context.Context, arg InsertWorkspaceAgentMetadataParams) error - InsertWorkspaceAgentScriptTimings(ctx context.Context, arg InsertWorkspaceAgentScriptTimingsParams) (WorkspaceAgentScriptTiming, error) + InsertWorkspaceAgentScriptTimings(ctx context.Context, arg InsertWorkspaceAgentScriptTimingsParams) error InsertWorkspaceAgentScripts(ctx context.Context, arg InsertWorkspaceAgentScriptsParams) ([]WorkspaceAgentScript, error) InsertWorkspaceAgentStats(ctx context.Context, arg InsertWorkspaceAgentStatsParams) error InsertWorkspaceApp(ctx context.Context, arg InsertWorkspaceAppParams) (WorkspaceApp, error) diff --git a/coderd/database/queries.sql.go b/coderd/database/queries.sql.go index 82c8a75b5a4e2..25199e25fbe4f 100644 --- a/coderd/database/queries.sql.go +++ b/coderd/database/queries.sql.go @@ -11802,7 +11802,7 @@ func (q *sqlQuerier) InsertWorkspaceAgentMetadata(ctx context.Context, arg Inser return err } -const insertWorkspaceAgentScriptTimings = `-- name: InsertWorkspaceAgentScriptTimings :one +const insertWorkspaceAgentScriptTimings = `-- name: InsertWorkspaceAgentScriptTimings :exec INSERT INTO workspace_agent_script_timings ( script_id, @@ -11814,7 +11814,7 @@ INSERT INTO timed_out ) VALUES - ($1, $2, $3, $4, $5, $6, $7) RETURNING script_id, display_name, started_at, ended_at, exit_code, stage, timed_out + ($1, $2, $3, $4, $5, $6, $7) ` type InsertWorkspaceAgentScriptTimingsParams struct { @@ -11827,8 +11827,8 @@ type InsertWorkspaceAgentScriptTimingsParams struct { TimedOut bool `db:"timed_out" json:"timed_out"` } -func (q *sqlQuerier) InsertWorkspaceAgentScriptTimings(ctx context.Context, arg InsertWorkspaceAgentScriptTimingsParams) (WorkspaceAgentScriptTiming, error) { - row := q.db.QueryRowContext(ctx, insertWorkspaceAgentScriptTimings, +func (q *sqlQuerier) InsertWorkspaceAgentScriptTimings(ctx context.Context, arg InsertWorkspaceAgentScriptTimingsParams) error { + _, err := q.db.ExecContext(ctx, insertWorkspaceAgentScriptTimings, arg.ScriptID, arg.DisplayName, arg.StartedAt, @@ -11837,17 +11837,7 @@ func (q *sqlQuerier) InsertWorkspaceAgentScriptTimings(ctx context.Context, arg arg.Stage, arg.TimedOut, ) - var i WorkspaceAgentScriptTiming - err := row.Scan( - &i.ScriptID, - &i.DisplayName, - &i.StartedAt, - &i.EndedAt, - &i.ExitCode, - &i.Stage, - &i.TimedOut, - ) - return i, err + return err } const updateWorkspaceAgentConnectionByID = `-- name: UpdateWorkspaceAgentConnectionByID :exec diff --git a/coderd/database/queries/workspaceagents.sql b/coderd/database/queries/workspaceagents.sql index 8c264c049494e..1abbf207c4fc4 100644 --- a/coderd/database/queries/workspaceagents.sql +++ b/coderd/database/queries/workspaceagents.sql @@ -288,7 +288,7 @@ WHERE ) ; --- name: InsertWorkspaceAgentScriptTimings :one +-- name: InsertWorkspaceAgentScriptTimings :exec INSERT INTO workspace_agent_script_timings ( script_id, @@ -300,4 +300,4 @@ INSERT INTO timed_out ) VALUES - ($1, $2, $3, $4, $5, $6, $7) RETURNING *; + ($1, $2, $3, $4, $5, $6, $7); From 44127b8ae481aa3fc1b98acac1483b948b7a3bce Mon Sep 17 00:00:00 2001 From: Danielle Maywood Date: Fri, 20 Sep 2024 15:35:04 +0000 Subject: [PATCH 47/56] chore: remove 'display_name' from timing table --- agent/agentscripts/agentscripts.go | 13 +- agent/agentscripts/agentscripts_test.go | 1 - agent/proto/agent.pb.go | 198 +++++++++--------- agent/proto/agent.proto | 11 +- coderd/agentapi/scripts.go | 16 +- coderd/agentapi/scripts_test.go | 68 +++--- coderd/database/dbmem/dbmem.go | 14 +- coderd/database/dump.sql | 4 +- ...0257_workspace_agent_script_timings.up.sql | 3 +- coderd/database/models.go | 13 +- coderd/database/queries.sql.go | 17 +- coderd/database/queries/workspaceagents.sql | 3 +- coderd/database/unique_constraint.go | 1 + 13 files changed, 172 insertions(+), 190 deletions(-) diff --git a/agent/agentscripts/agentscripts.go b/agent/agentscripts/agentscripts.go index e332ad3ffaaa1..950abdedfb620 100644 --- a/agent/agentscripts/agentscripts.go +++ b/agent/agentscripts/agentscripts.go @@ -350,13 +350,12 @@ func (r *Runner) run(ctx context.Context, script codersdk.WorkspaceAgentScript, _, err = r.scriptCompleted(ctx, &proto.WorkspaceAgentScriptCompletedRequest{ Timing: &proto.Timing{ - ScriptId: script.ID[:], - DisplayName: script.DisplayName, - Start: timestamppb.New(start), - End: timestamppb.New(end), - ExitCode: int32(exitCode), - Stage: stage, - TimedOut: errors.Is(err, ErrTimeout), + ScriptId: script.ID[:], + Start: timestamppb.New(start), + End: timestamppb.New(end), + ExitCode: int32(exitCode), + Stage: stage, + TimedOut: errors.Is(err, ErrTimeout), }, }) if err != nil { diff --git a/agent/agentscripts/agentscripts_test.go b/agent/agentscripts/agentscripts_test.go index fa550db11239b..05195bddf1a57 100644 --- a/agent/agentscripts/agentscripts_test.go +++ b/agent/agentscripts/agentscripts_test.go @@ -138,7 +138,6 @@ func TestScriptReportsTiming(t *testing.T) { require.Equal(t, 1, len(timings)) timing := timings[0] - require.Equal(t, "say-hello", timing.DisplayName) require.Equal(t, int32(0), timing.ExitCode) require.GreaterOrEqual(t, timing.End.AsTime(), timing.Start.AsTime()) } diff --git a/agent/proto/agent.pb.go b/agent/proto/agent.pb.go index b0fb99297245e..6fb3fcbab9a34 100644 --- a/agent/proto/agent.pb.go +++ b/agent/proto/agent.pb.go @@ -2170,13 +2170,12 @@ type Timing struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - ScriptId []byte `protobuf:"bytes,1,opt,name=script_id,json=scriptId,proto3" json:"script_id,omitempty"` - DisplayName string `protobuf:"bytes,2,opt,name=display_name,json=displayName,proto3" json:"display_name,omitempty"` - Start *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=start,proto3" json:"start,omitempty"` - End *timestamppb.Timestamp `protobuf:"bytes,4,opt,name=end,proto3" json:"end,omitempty"` - ExitCode int32 `protobuf:"varint,5,opt,name=exit_code,json=exitCode,proto3" json:"exit_code,omitempty"` - Stage Timing_Stage `protobuf:"varint,6,opt,name=stage,proto3,enum=coder.agent.v2.Timing_Stage" json:"stage,omitempty"` - TimedOut bool `protobuf:"varint,7,opt,name=timed_out,json=timedOut,proto3" json:"timed_out,omitempty"` + ScriptId []byte `protobuf:"bytes,1,opt,name=script_id,json=scriptId,proto3" json:"script_id,omitempty"` + Start *timestamppb.Timestamp `protobuf:"bytes,2,opt,name=start,proto3" json:"start,omitempty"` + End *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=end,proto3" json:"end,omitempty"` + ExitCode int32 `protobuf:"varint,4,opt,name=exit_code,json=exitCode,proto3" json:"exit_code,omitempty"` + Stage Timing_Stage `protobuf:"varint,5,opt,name=stage,proto3,enum=coder.agent.v2.Timing_Stage" json:"stage,omitempty"` + TimedOut bool `protobuf:"varint,6,opt,name=timed_out,json=timedOut,proto3" json:"timed_out,omitempty"` } func (x *Timing) Reset() { @@ -2218,13 +2217,6 @@ func (x *Timing) GetScriptId() []byte { return nil } -func (x *Timing) GetDisplayName() string { - if x != nil { - return x.DisplayName - } - return "" -} - func (x *Timing) GetStart() *timestamppb.Timestamp { if x != nil { return x.Start @@ -3024,99 +3016,97 @@ var file_agent_proto_agent_proto_rawDesc = []byte{ 0x6e, 0x67, 0x52, 0x06, 0x74, 0x69, 0x6d, 0x69, 0x6e, 0x67, 0x22, 0x27, 0x0a, 0x25, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0xbe, 0x02, 0x0a, 0x06, 0x54, 0x69, 0x6d, 0x69, 0x6e, 0x67, 0x12, 0x1b, + 0x6e, 0x73, 0x65, 0x22, 0x9b, 0x02, 0x0a, 0x06, 0x54, 0x69, 0x6d, 0x69, 0x6e, 0x67, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x08, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x64, - 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x30, - 0x0a, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, - 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, - 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, - 0x12, 0x2c, 0x0a, 0x03, 0x65, 0x6e, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, - 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, - 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x03, 0x65, 0x6e, 0x64, 0x12, 0x1b, - 0x0a, 0x09, 0x65, 0x78, 0x69, 0x74, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, - 0x05, 0x52, 0x08, 0x65, 0x78, 0x69, 0x74, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x32, 0x0a, 0x05, 0x73, - 0x74, 0x61, 0x67, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1c, 0x2e, 0x63, 0x6f, 0x64, - 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x54, 0x69, 0x6d, 0x69, - 0x6e, 0x67, 0x2e, 0x53, 0x74, 0x61, 0x67, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x67, 0x65, 0x12, - 0x1b, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x64, 0x5f, 0x6f, 0x75, 0x74, 0x18, 0x07, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x08, 0x74, 0x69, 0x6d, 0x65, 0x64, 0x4f, 0x75, 0x74, 0x22, 0x26, 0x0a, 0x05, - 0x53, 0x74, 0x61, 0x67, 0x65, 0x12, 0x09, 0x0a, 0x05, 0x53, 0x54, 0x41, 0x52, 0x54, 0x10, 0x00, - 0x12, 0x08, 0x0a, 0x04, 0x53, 0x54, 0x4f, 0x50, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x43, 0x52, - 0x4f, 0x4e, 0x10, 0x02, 0x2a, 0x63, 0x0a, 0x09, 0x41, 0x70, 0x70, 0x48, 0x65, 0x61, 0x6c, 0x74, - 0x68, 0x12, 0x1a, 0x0a, 0x16, 0x41, 0x50, 0x50, 0x5f, 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, 0x5f, - 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0c, 0x0a, - 0x08, 0x44, 0x49, 0x53, 0x41, 0x42, 0x4c, 0x45, 0x44, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x49, - 0x4e, 0x49, 0x54, 0x49, 0x41, 0x4c, 0x49, 0x5a, 0x49, 0x4e, 0x47, 0x10, 0x02, 0x12, 0x0b, 0x0a, - 0x07, 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, 0x59, 0x10, 0x03, 0x12, 0x0d, 0x0a, 0x09, 0x55, 0x4e, - 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, 0x59, 0x10, 0x04, 0x32, 0xef, 0x07, 0x0a, 0x05, 0x41, 0x67, - 0x65, 0x6e, 0x74, 0x12, 0x4b, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, - 0x73, 0x74, 0x12, 0x22, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, - 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, - 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, - 0x12, 0x5a, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x42, 0x61, - 0x6e, 0x6e, 0x65, 0x72, 0x12, 0x27, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, - 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, - 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x53, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x12, 0x56, 0x0a, 0x0b, - 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x22, 0x2e, 0x63, 0x6f, - 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x70, 0x64, - 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x23, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, - 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x54, 0x0a, 0x0f, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4c, 0x69, - 0x66, 0x65, 0x63, 0x79, 0x63, 0x6c, 0x65, 0x12, 0x26, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, - 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4c, - 0x69, 0x66, 0x65, 0x63, 0x79, 0x63, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x19, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, - 0x2e, 0x4c, 0x69, 0x66, 0x65, 0x63, 0x79, 0x63, 0x6c, 0x65, 0x12, 0x72, 0x0a, 0x15, 0x42, 0x61, - 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x70, 0x70, 0x48, 0x65, 0x61, 0x6c, - 0x74, 0x68, 0x73, 0x12, 0x2b, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, - 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x41, 0x70, 0x70, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x2c, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, + 0x0c, 0x52, 0x08, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x49, 0x64, 0x12, 0x30, 0x0a, 0x05, 0x73, + 0x74, 0x61, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, + 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x12, 0x2c, 0x0a, + 0x03, 0x65, 0x6e, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, + 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x03, 0x65, 0x6e, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x65, + 0x78, 0x69, 0x74, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, + 0x65, 0x78, 0x69, 0x74, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x32, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x67, + 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1c, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, + 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x54, 0x69, 0x6d, 0x69, 0x6e, 0x67, 0x2e, + 0x53, 0x74, 0x61, 0x67, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x67, 0x65, 0x12, 0x1b, 0x0a, 0x09, + 0x74, 0x69, 0x6d, 0x65, 0x64, 0x5f, 0x6f, 0x75, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x08, 0x74, 0x69, 0x6d, 0x65, 0x64, 0x4f, 0x75, 0x74, 0x22, 0x26, 0x0a, 0x05, 0x53, 0x74, 0x61, + 0x67, 0x65, 0x12, 0x09, 0x0a, 0x05, 0x53, 0x54, 0x41, 0x52, 0x54, 0x10, 0x00, 0x12, 0x08, 0x0a, + 0x04, 0x53, 0x54, 0x4f, 0x50, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x43, 0x52, 0x4f, 0x4e, 0x10, + 0x02, 0x2a, 0x63, 0x0a, 0x09, 0x41, 0x70, 0x70, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x12, 0x1a, + 0x0a, 0x16, 0x41, 0x50, 0x50, 0x5f, 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, 0x5f, 0x55, 0x4e, 0x53, + 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x44, 0x49, + 0x53, 0x41, 0x42, 0x4c, 0x45, 0x44, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x49, 0x4e, 0x49, 0x54, + 0x49, 0x41, 0x4c, 0x49, 0x5a, 0x49, 0x4e, 0x47, 0x10, 0x02, 0x12, 0x0b, 0x0a, 0x07, 0x48, 0x45, + 0x41, 0x4c, 0x54, 0x48, 0x59, 0x10, 0x03, 0x12, 0x0d, 0x0a, 0x09, 0x55, 0x4e, 0x48, 0x45, 0x41, + 0x4c, 0x54, 0x48, 0x59, 0x10, 0x04, 0x32, 0xef, 0x07, 0x0a, 0x05, 0x41, 0x67, 0x65, 0x6e, 0x74, + 0x12, 0x4b, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x12, + 0x22, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, + 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, + 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x12, 0x5a, 0x0a, + 0x10, 0x47, 0x65, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x42, 0x61, 0x6e, 0x6e, 0x65, + 0x72, 0x12, 0x27, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, + 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x42, 0x61, 0x6e, + 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x63, 0x6f, 0x64, + 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x12, 0x56, 0x0a, 0x0b, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x22, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, + 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x63, + 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x54, 0x0a, 0x0f, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4c, 0x69, 0x66, 0x65, 0x63, + 0x79, 0x63, 0x6c, 0x65, 0x12, 0x26, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, + 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4c, 0x69, 0x66, 0x65, + 0x63, 0x79, 0x63, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x63, + 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x4c, 0x69, + 0x66, 0x65, 0x63, 0x79, 0x63, 0x6c, 0x65, 0x12, 0x72, 0x0a, 0x15, 0x42, 0x61, 0x74, 0x63, 0x68, + 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x70, 0x70, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x73, + 0x12, 0x2b, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x70, 0x70, - 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4e, - 0x0a, 0x0d, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x12, - 0x24, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, - 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, - 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x12, 0x6e, - 0x0a, 0x13, 0x42, 0x61, 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x74, - 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x2a, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, - 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x2b, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, - 0x76, 0x32, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x65, - 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x62, - 0x0a, 0x0f, 0x42, 0x61, 0x74, 0x63, 0x68, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4c, 0x6f, 0x67, - 0x73, 0x12, 0x26, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, - 0x76, 0x32, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4c, 0x6f, - 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x63, 0x6f, 0x64, 0x65, - 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, - 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x77, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x41, 0x6e, 0x6e, 0x6f, 0x75, 0x6e, 0x63, - 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x73, 0x12, 0x2d, 0x2e, 0x63, - 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, - 0x74, 0x41, 0x6e, 0x6e, 0x6f, 0x75, 0x6e, 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x61, 0x6e, - 0x6e, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x63, 0x6f, - 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, - 0x41, 0x6e, 0x6e, 0x6f, 0x75, 0x6e, 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x61, 0x6e, 0x6e, - 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7e, 0x0a, 0x0f, 0x53, - 0x63, 0x72, 0x69, 0x70, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x12, 0x34, + 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, + 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x42, + 0x61, 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x70, 0x70, 0x48, 0x65, 0x61, + 0x6c, 0x74, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4e, 0x0a, 0x0d, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x12, 0x24, 0x2e, 0x63, + 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, + 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x12, 0x6e, 0x0a, 0x13, 0x42, + 0x61, 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, + 0x74, 0x61, 0x12, 0x2a, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, + 0x2e, 0x76, 0x32, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, - 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x53, 0x63, - 0x72, 0x69, 0x70, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x35, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, - 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x41, - 0x67, 0x65, 0x6e, 0x74, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, - 0x74, 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x27, 0x5a, 0x25, 0x67, - 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2f, - 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2f, 0x76, 0x32, 0x2f, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2f, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x42, 0x61, 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x62, 0x0a, 0x0f, 0x42, + 0x61, 0x74, 0x63, 0x68, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4c, 0x6f, 0x67, 0x73, 0x12, 0x26, + 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, + 0x42, 0x61, 0x74, 0x63, 0x68, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4c, 0x6f, 0x67, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, + 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x43, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x77, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x41, 0x6e, 0x6e, 0x6f, 0x75, 0x6e, 0x63, 0x65, 0x6d, 0x65, + 0x6e, 0x74, 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x73, 0x12, 0x2d, 0x2e, 0x63, 0x6f, 0x64, 0x65, + 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x6e, + 0x6e, 0x6f, 0x75, 0x6e, 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, + 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x6e, 0x6e, + 0x6f, 0x75, 0x6e, 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7e, 0x0a, 0x0f, 0x53, 0x63, 0x72, 0x69, + 0x70, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x12, 0x34, 0x2e, 0x63, 0x6f, + 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x57, 0x6f, 0x72, + 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x53, 0x63, 0x72, 0x69, 0x70, + 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x35, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, + 0x76, 0x32, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x41, 0x67, 0x65, 0x6e, + 0x74, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x27, 0x5a, 0x25, 0x67, 0x69, 0x74, 0x68, + 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2f, 0x63, 0x6f, 0x64, + 0x65, 0x72, 0x2f, 0x76, 0x32, 0x2f, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2f, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/agent/proto/agent.proto b/agent/proto/agent.proto index cab148b96a2ba..cc34201618c9c 100644 --- a/agent/proto/agent.proto +++ b/agent/proto/agent.proto @@ -275,18 +275,17 @@ message WorkspaceAgentScriptCompletedResponse { message Timing { bytes script_id = 1; - string display_name = 2; - google.protobuf.Timestamp start = 3; - google.protobuf.Timestamp end = 4; - int32 exit_code = 5; + google.protobuf.Timestamp start = 2; + google.protobuf.Timestamp end = 3; + int32 exit_code = 4; enum Stage { START = 0; STOP = 1; CRON = 2; } - Stage stage = 6; - bool timed_out = 7; + Stage stage = 5; + bool timed_out = 6; } service Agent { diff --git a/coderd/agentapi/scripts.go b/coderd/agentapi/scripts.go index 116558373ee9f..451f9cd9dce2b 100644 --- a/coderd/agentapi/scripts.go +++ b/coderd/agentapi/scripts.go @@ -8,6 +8,7 @@ import ( agentproto "github.com/coder/coder/v2/agent/proto" "github.com/coder/coder/v2/coderd/database" + "github.com/coder/coder/v2/coderd/database/dbauthz" ) type ScriptsAPI struct { @@ -32,14 +33,15 @@ func (s *ScriptsAPI) ScriptCompleted(ctx context.Context, req *agentproto.Worksp stage = database.WorkspaceAgentScriptTimingStageCron } + //nolint:gocritic // We need permissions to write to the DB here and we are in the context of the agent. + ctx = dbauthz.AsProvisionerd(ctx) err = s.Database.InsertWorkspaceAgentScriptTimings(ctx, database.InsertWorkspaceAgentScriptTimingsParams{ - ScriptID: scriptID, - Stage: stage, - DisplayName: req.Timing.DisplayName, - StartedAt: req.Timing.Start.AsTime(), - EndedAt: req.Timing.End.AsTime(), - ExitCode: req.Timing.ExitCode, - TimedOut: req.Timing.TimedOut, + ScriptID: scriptID, + Stage: stage, + StartedAt: req.Timing.Start.AsTime(), + EndedAt: req.Timing.End.AsTime(), + ExitCode: req.Timing.ExitCode, + TimedOut: req.Timing.TimedOut, }) if err != nil { return nil, xerrors.Errorf("insert workspace agent script timings into database: %w", err) diff --git a/coderd/agentapi/scripts_test.go b/coderd/agentapi/scripts_test.go index 5d2c6b6513004..c925619edae6c 100644 --- a/coderd/agentapi/scripts_test.go +++ b/coderd/agentapi/scripts_test.go @@ -26,56 +26,51 @@ func TestScriptCompleted(t *testing.T) { { scriptID: uuid.New(), timing: &agentproto.Timing{ - Stage: agentproto.Timing_START, - DisplayName: "Start Script", - Start: timestamppb.New(dbtime.Now()), - End: timestamppb.New(dbtime.Now().Add(time.Second)), - TimedOut: false, - ExitCode: 0, + Stage: agentproto.Timing_START, + Start: timestamppb.New(dbtime.Now()), + End: timestamppb.New(dbtime.Now().Add(time.Second)), + TimedOut: false, + ExitCode: 0, }, }, { scriptID: uuid.New(), timing: &agentproto.Timing{ - Stage: agentproto.Timing_STOP, - DisplayName: "Stop Script", - Start: timestamppb.New(dbtime.Now()), - End: timestamppb.New(dbtime.Now().Add(time.Second)), - TimedOut: false, - ExitCode: 0, + Stage: agentproto.Timing_STOP, + Start: timestamppb.New(dbtime.Now()), + End: timestamppb.New(dbtime.Now().Add(time.Second)), + TimedOut: false, + ExitCode: 0, }, }, { scriptID: uuid.New(), timing: &agentproto.Timing{ - Stage: agentproto.Timing_CRON, - DisplayName: "Cron Script", - Start: timestamppb.New(dbtime.Now()), - End: timestamppb.New(dbtime.Now().Add(time.Second)), - TimedOut: false, - ExitCode: 0, + Stage: agentproto.Timing_CRON, + Start: timestamppb.New(dbtime.Now()), + End: timestamppb.New(dbtime.Now().Add(time.Second)), + TimedOut: false, + ExitCode: 0, }, }, { scriptID: uuid.New(), timing: &agentproto.Timing{ - Stage: agentproto.Timing_START, - DisplayName: "Timed Out Script", - Start: timestamppb.New(dbtime.Now()), - End: timestamppb.New(dbtime.Now().Add(time.Second)), - TimedOut: true, - ExitCode: 255, + Stage: agentproto.Timing_START, + Start: timestamppb.New(dbtime.Now()), + End: timestamppb.New(dbtime.Now().Add(time.Second)), + TimedOut: true, + ExitCode: 255, }, }, { scriptID: uuid.New(), timing: &agentproto.Timing{ - Stage: agentproto.Timing_START, - DisplayName: "Failed Script", - Start: timestamppb.New(dbtime.Now()), - End: timestamppb.New(dbtime.Now().Add(time.Second)), - TimedOut: true, - ExitCode: 1, + Stage: agentproto.Timing_START, + Start: timestamppb.New(dbtime.Now()), + End: timestamppb.New(dbtime.Now().Add(time.Second)), + TimedOut: true, + ExitCode: 1, }, }, } @@ -86,13 +81,12 @@ func TestScriptCompleted(t *testing.T) { mDB := dbmock.NewMockStore(gomock.NewController(t)) mDB.EXPECT().InsertWorkspaceAgentScriptTimings(gomock.Any(), database.InsertWorkspaceAgentScriptTimingsParams{ - ScriptID: tt.scriptID, - Stage: protoScriptTimingStageToDatabase(tt.timing.Stage), - DisplayName: tt.timing.DisplayName, - StartedAt: tt.timing.Start.AsTime(), - EndedAt: tt.timing.End.AsTime(), - TimedOut: tt.timing.TimedOut, - ExitCode: tt.timing.ExitCode, + ScriptID: tt.scriptID, + Stage: protoScriptTimingStageToDatabase(tt.timing.Stage), + StartedAt: tt.timing.Start.AsTime(), + EndedAt: tt.timing.End.AsTime(), + TimedOut: tt.timing.TimedOut, + ExitCode: tt.timing.ExitCode, }) api := &agentapi.ScriptsAPI{Database: mDB} diff --git a/coderd/database/dbmem/dbmem.go b/coderd/database/dbmem/dbmem.go index 972748adbaf85..17ef6d4e06823 100644 --- a/coderd/database/dbmem/dbmem.go +++ b/coderd/database/dbmem/dbmem.go @@ -7837,14 +7837,14 @@ func (q *FakeQuerier) InsertWorkspaceAgentScriptTimings(_ context.Context, arg d defer q.mutex.Unlock() q.workspaceAgentScriptTimings = append(q.workspaceAgentScriptTimings, + //nolint:gosimple // Stop the linter complaining about changing the type of `arg`. database.WorkspaceAgentScriptTiming{ - ScriptID: arg.ScriptID, - StartedAt: arg.StartedAt, - EndedAt: arg.EndedAt, - ExitCode: arg.ExitCode, - DisplayName: arg.DisplayName, - Stage: arg.Stage, - TimedOut: arg.TimedOut, + ScriptID: arg.ScriptID, + StartedAt: arg.StartedAt, + EndedAt: arg.EndedAt, + ExitCode: arg.ExitCode, + Stage: arg.Stage, + TimedOut: arg.TimedOut, }, ) diff --git a/coderd/database/dump.sql b/coderd/database/dump.sql index d9fb663b8cdca..88293a554e8d2 100644 --- a/coderd/database/dump.sql +++ b/coderd/database/dump.sql @@ -1363,7 +1363,6 @@ CREATE TABLE workspace_agent_port_share ( CREATE TABLE workspace_agent_script_timings ( script_id uuid NOT NULL, - display_name text NOT NULL, started_at timestamp with time zone NOT NULL, ended_at timestamp with time zone NOT NULL, exit_code integer NOT NULL, @@ -1875,6 +1874,9 @@ ALTER TABLE ONLY workspace_agent_metadata ALTER TABLE ONLY workspace_agent_port_share ADD CONSTRAINT workspace_agent_port_share_pkey PRIMARY KEY (workspace_id, agent_name, port); +ALTER TABLE ONLY workspace_agent_script_timings + ADD CONSTRAINT workspace_agent_script_timings_script_id_started_at_key UNIQUE (script_id, started_at); + ALTER TABLE ONLY workspace_agent_scripts ADD CONSTRAINT workspace_agent_scripts_id_key UNIQUE (id); diff --git a/coderd/database/migrations/000257_workspace_agent_script_timings.up.sql b/coderd/database/migrations/000257_workspace_agent_script_timings.up.sql index cb619b820a62a..7e2f60136160e 100644 --- a/coderd/database/migrations/000257_workspace_agent_script_timings.up.sql +++ b/coderd/database/migrations/000257_workspace_agent_script_timings.up.sql @@ -9,10 +9,11 @@ CREATE TYPE workspace_agent_script_timing_stage AS ENUM ( CREATE TABLE workspace_agent_script_timings ( script_id uuid NOT NULL REFERENCES workspace_agent_scripts (id) ON DELETE CASCADE, - display_name text NOT NULL, started_at timestamp with time zone NOT NULL, ended_at timestamp with time zone NOT NULL, exit_code int NOT NULL, stage workspace_agent_script_timing_stage NOT NULL, timed_out bool NOT NULL ); + +ALTER TABLE workspace_agent_script_timings ADD UNIQUE (script_id, started_at); diff --git a/coderd/database/models.go b/coderd/database/models.go index 9ad25e0b07db4..5282acc154fa0 100644 --- a/coderd/database/models.go +++ b/coderd/database/models.go @@ -2946,13 +2946,12 @@ type WorkspaceAgentScript struct { } type WorkspaceAgentScriptTiming struct { - ScriptID uuid.UUID `db:"script_id" json:"script_id"` - DisplayName string `db:"display_name" json:"display_name"` - StartedAt time.Time `db:"started_at" json:"started_at"` - EndedAt time.Time `db:"ended_at" json:"ended_at"` - ExitCode int32 `db:"exit_code" json:"exit_code"` - Stage WorkspaceAgentScriptTimingStage `db:"stage" json:"stage"` - TimedOut bool `db:"timed_out" json:"timed_out"` + ScriptID uuid.UUID `db:"script_id" json:"script_id"` + StartedAt time.Time `db:"started_at" json:"started_at"` + EndedAt time.Time `db:"ended_at" json:"ended_at"` + ExitCode int32 `db:"exit_code" json:"exit_code"` + Stage WorkspaceAgentScriptTimingStage `db:"stage" json:"stage"` + TimedOut bool `db:"timed_out" json:"timed_out"` } type WorkspaceAgentStat struct { diff --git a/coderd/database/queries.sql.go b/coderd/database/queries.sql.go index 25199e25fbe4f..bc262160edc74 100644 --- a/coderd/database/queries.sql.go +++ b/coderd/database/queries.sql.go @@ -11806,7 +11806,6 @@ const insertWorkspaceAgentScriptTimings = `-- name: InsertWorkspaceAgentScriptTi INSERT INTO workspace_agent_script_timings ( script_id, - display_name, started_at, ended_at, exit_code, @@ -11814,23 +11813,21 @@ INSERT INTO timed_out ) VALUES - ($1, $2, $3, $4, $5, $6, $7) + ($1, $2, $3, $4, $5, $6) ` type InsertWorkspaceAgentScriptTimingsParams struct { - ScriptID uuid.UUID `db:"script_id" json:"script_id"` - DisplayName string `db:"display_name" json:"display_name"` - StartedAt time.Time `db:"started_at" json:"started_at"` - EndedAt time.Time `db:"ended_at" json:"ended_at"` - ExitCode int32 `db:"exit_code" json:"exit_code"` - Stage WorkspaceAgentScriptTimingStage `db:"stage" json:"stage"` - TimedOut bool `db:"timed_out" json:"timed_out"` + ScriptID uuid.UUID `db:"script_id" json:"script_id"` + StartedAt time.Time `db:"started_at" json:"started_at"` + EndedAt time.Time `db:"ended_at" json:"ended_at"` + ExitCode int32 `db:"exit_code" json:"exit_code"` + Stage WorkspaceAgentScriptTimingStage `db:"stage" json:"stage"` + TimedOut bool `db:"timed_out" json:"timed_out"` } func (q *sqlQuerier) InsertWorkspaceAgentScriptTimings(ctx context.Context, arg InsertWorkspaceAgentScriptTimingsParams) error { _, err := q.db.ExecContext(ctx, insertWorkspaceAgentScriptTimings, arg.ScriptID, - arg.DisplayName, arg.StartedAt, arg.EndedAt, arg.ExitCode, diff --git a/coderd/database/queries/workspaceagents.sql b/coderd/database/queries/workspaceagents.sql index 1abbf207c4fc4..1121440999017 100644 --- a/coderd/database/queries/workspaceagents.sql +++ b/coderd/database/queries/workspaceagents.sql @@ -292,7 +292,6 @@ WHERE INSERT INTO workspace_agent_script_timings ( script_id, - display_name, started_at, ended_at, exit_code, @@ -300,4 +299,4 @@ INSERT INTO timed_out ) VALUES - ($1, $2, $3, $4, $5, $6, $7); + ($1, $2, $3, $4, $5, $6); diff --git a/coderd/database/unique_constraint.go b/coderd/database/unique_constraint.go index 1ce55f8fa17d6..f4470c6546698 100644 --- a/coderd/database/unique_constraint.go +++ b/coderd/database/unique_constraint.go @@ -67,6 +67,7 @@ const ( UniqueWorkspaceAgentLogSourcesPkey UniqueConstraint = "workspace_agent_log_sources_pkey" // ALTER TABLE ONLY workspace_agent_log_sources ADD CONSTRAINT workspace_agent_log_sources_pkey PRIMARY KEY (workspace_agent_id, id); UniqueWorkspaceAgentMetadataPkey UniqueConstraint = "workspace_agent_metadata_pkey" // ALTER TABLE ONLY workspace_agent_metadata ADD CONSTRAINT workspace_agent_metadata_pkey PRIMARY KEY (workspace_agent_id, key); UniqueWorkspaceAgentPortSharePkey UniqueConstraint = "workspace_agent_port_share_pkey" // ALTER TABLE ONLY workspace_agent_port_share ADD CONSTRAINT workspace_agent_port_share_pkey PRIMARY KEY (workspace_id, agent_name, port); + UniqueWorkspaceAgentScriptTimingsScriptIDStartedAtKey UniqueConstraint = "workspace_agent_script_timings_script_id_started_at_key" // ALTER TABLE ONLY workspace_agent_script_timings ADD CONSTRAINT workspace_agent_script_timings_script_id_started_at_key UNIQUE (script_id, started_at); UniqueWorkspaceAgentScriptsIDKey UniqueConstraint = "workspace_agent_scripts_id_key" // ALTER TABLE ONLY workspace_agent_scripts ADD CONSTRAINT workspace_agent_scripts_id_key UNIQUE (id); UniqueWorkspaceAgentStartupLogsPkey UniqueConstraint = "workspace_agent_startup_logs_pkey" // ALTER TABLE ONLY workspace_agent_logs ADD CONSTRAINT workspace_agent_startup_logs_pkey PRIMARY KEY (id); UniqueWorkspaceAgentsPkey UniqueConstraint = "workspace_agents_pkey" // ALTER TABLE ONLY workspace_agents ADD CONSTRAINT workspace_agents_pkey PRIMARY KEY (id); From 58462162b37b85b0b00430a34321e41ef505a177 Mon Sep 17 00:00:00 2001 From: Danielle Maywood Date: Fri, 20 Sep 2024 15:44:08 +0000 Subject: [PATCH 48/56] fix: testdata fixture --- .../fixtures/000257_workspace_agent_script_timings.up.sql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/coderd/database/migrations/testdata/fixtures/000257_workspace_agent_script_timings.up.sql b/coderd/database/migrations/testdata/fixtures/000257_workspace_agent_script_timings.up.sql index 4f75ea3abe3a8..c4334b0293768 100644 --- a/coderd/database/migrations/testdata/fixtures/000257_workspace_agent_script_timings.up.sql +++ b/coderd/database/migrations/testdata/fixtures/000257_workspace_agent_script_timings.up.sql @@ -1,3 +1,3 @@ -INSERT INTO workspace_agent_script_timings (script_id, display_name, started_at, ended_at, exit_code, stage, timed_out) +INSERT INTO workspace_agent_script_timings (script_id, started_at, ended_at, exit_code, stage, timed_out) VALUES - ((SELECT id FROM workspace_agent_scripts LIMIT 1), 'Startup Script', NOW() - INTERVAL '1 hour 55 minutes', NOW() - INTERVAL '1 hour 50 minutes', 0, 'start', false); + ((SELECT id FROM workspace_agent_scripts LIMIT 1), NOW() - INTERVAL '1 hour 55 minutes', NOW() - INTERVAL '1 hour 50 minutes', 0, 'start', false); From c43a1433c31fdae07b40431e38a6cacef0b59154 Mon Sep 17 00:00:00 2001 From: Danielle Maywood Date: Mon, 23 Sep 2024 08:14:15 +0000 Subject: [PATCH 49/56] fix: put r.scriptCompleted call in goroutine --- agent/agentscripts/agentscripts.go | 46 ++++++++++++++++-------------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/agent/agentscripts/agentscripts.go b/agent/agentscripts/agentscripts.go index 950abdedfb620..2dd3d0deeeea0 100644 --- a/agent/agentscripts/agentscripts.go +++ b/agent/agentscripts/agentscripts.go @@ -338,29 +338,31 @@ func (r *Runner) run(ctx context.Context, script codersdk.WorkspaceAgentScript, return } - var stage proto.Timing_Stage - switch option { - case ExecuteStartScripts: - stage = proto.Timing_START - case ExecuteStopScripts: - stage = proto.Timing_STOP - case ExecuteCronScripts: - stage = proto.Timing_CRON - } + go func() { + var stage proto.Timing_Stage + switch option { + case ExecuteStartScripts: + stage = proto.Timing_START + case ExecuteStopScripts: + stage = proto.Timing_STOP + case ExecuteCronScripts: + stage = proto.Timing_CRON + } - _, err = r.scriptCompleted(ctx, &proto.WorkspaceAgentScriptCompletedRequest{ - Timing: &proto.Timing{ - ScriptId: script.ID[:], - Start: timestamppb.New(start), - End: timestamppb.New(end), - ExitCode: int32(exitCode), - Stage: stage, - TimedOut: errors.Is(err, ErrTimeout), - }, - }) - if err != nil { - logger.Error(ctx, fmt.Sprintf("reporting script completed: %s", err.Error())) - } + _, err = r.scriptCompleted(ctx, &proto.WorkspaceAgentScriptCompletedRequest{ + Timing: &proto.Timing{ + ScriptId: script.ID[:], + Start: timestamppb.New(start), + End: timestamppb.New(end), + ExitCode: int32(exitCode), + Stage: stage, + TimedOut: errors.Is(err, ErrTimeout), + }, + }) + if err != nil { + logger.Error(ctx, fmt.Sprintf("reporting script completed: %s", err.Error())) + } + }() }() err = cmd.Start() From 13889bf11531b8efbc9f1a4c20cc833866127d64 Mon Sep 17 00:00:00 2001 From: Danielle Maywood Date: Mon, 23 Sep 2024 08:50:03 +0000 Subject: [PATCH 50/56] fix: track goroutine for test + use separate context for reporting --- agent/agentscripts/agentscripts.go | 10 +++++++--- agent/agentscripts/agentscripts_test.go | 4 ++-- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/agent/agentscripts/agentscripts.go b/agent/agentscripts/agentscripts.go index 2dd3d0deeeea0..fd78936acec10 100644 --- a/agent/agentscripts/agentscripts.go +++ b/agent/agentscripts/agentscripts.go @@ -338,7 +338,7 @@ func (r *Runner) run(ctx context.Context, script codersdk.WorkspaceAgentScript, return } - go func() { + r.trackCommandGoroutine(func() { var stage proto.Timing_Stage switch option { case ExecuteStartScripts: @@ -349,7 +349,11 @@ func (r *Runner) run(ctx context.Context, script codersdk.WorkspaceAgentScript, stage = proto.Timing_CRON } - _, err = r.scriptCompleted(ctx, &proto.WorkspaceAgentScriptCompletedRequest{ + reportTimeout := 30 * time.Second + reportCtx, cancel := context.WithTimeout(context.Background(), reportTimeout) + defer cancel() + + _, err = r.scriptCompleted(reportCtx, &proto.WorkspaceAgentScriptCompletedRequest{ Timing: &proto.Timing{ ScriptId: script.ID[:], Start: timestamppb.New(start), @@ -362,7 +366,7 @@ func (r *Runner) run(ctx context.Context, script codersdk.WorkspaceAgentScript, if err != nil { logger.Error(ctx, fmt.Sprintf("reporting script completed: %s", err.Error())) } - }() + }) }() err = cmd.Start() diff --git a/agent/agentscripts/agentscripts_test.go b/agent/agentscripts/agentscripts_test.go index 05195bddf1a57..e47fdbae8f87e 100644 --- a/agent/agentscripts/agentscripts_test.go +++ b/agent/agentscripts/agentscripts_test.go @@ -120,7 +120,6 @@ func TestScriptReportsTiming(t *testing.T) { runner := setup(t, func(uuid2 uuid.UUID) agentscripts.ScriptLogger { return fLogger }) - defer runner.Close() aAPI := agenttest.NewFakeAgentAPI(t, slogtest.Make(t, nil), nil, nil) err := runner.Init([]codersdk.WorkspaceAgentScript{{ @@ -129,7 +128,8 @@ func TestScriptReportsTiming(t *testing.T) { Script: "echo hello", }}, aAPI.ScriptCompleted) require.NoError(t, err) - require.NoError(t, runner.Execute(context.Background(), agentscripts.ExecuteAllScripts)) + require.NoError(t, runner.Execute(ctx, agentscripts.ExecuteAllScripts)) + runner.Close() log := testutil.RequireRecvCtx(ctx, t, fLogger.logs) require.Equal(t, "hello", log.Output) From bf32b89fb97e163e62e4a2f10b629c65e067c46b Mon Sep 17 00:00:00 2001 From: Danielle Maywood Date: Mon, 23 Sep 2024 08:57:25 +0000 Subject: [PATCH 51/56] fix: appease linter, handle trackCommandGoroutine error --- agent/agentscripts/agentscripts.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/agent/agentscripts/agentscripts.go b/agent/agentscripts/agentscripts.go index fd78936acec10..72e2e729a415c 100644 --- a/agent/agentscripts/agentscripts.go +++ b/agent/agentscripts/agentscripts.go @@ -338,7 +338,7 @@ func (r *Runner) run(ctx context.Context, script codersdk.WorkspaceAgentScript, return } - r.trackCommandGoroutine(func() { + err = r.trackCommandGoroutine(func() { var stage proto.Timing_Stage switch option { case ExecuteStartScripts: @@ -367,6 +367,9 @@ func (r *Runner) run(ctx context.Context, script codersdk.WorkspaceAgentScript, logger.Error(ctx, fmt.Sprintf("reporting script completed: %s", err.Error())) } }) + if err != nil { + logger.Error(ctx, fmt.Sprintf("reporting script completed: track command goroutine: %s", err.Error())) + } }() err = cmd.Start() From 7fe6d8c7f1ee79f3ec19709d77be21029579d6f0 Mon Sep 17 00:00:00 2001 From: Danielle Maywood Date: Mon, 23 Sep 2024 09:19:15 +0000 Subject: [PATCH 52/56] fix: resolve race condition --- agent/agentscripts/agentscripts.go | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/agent/agentscripts/agentscripts.go b/agent/agentscripts/agentscripts.go index 72e2e729a415c..367890b849a79 100644 --- a/agent/agentscripts/agentscripts.go +++ b/agent/agentscripts/agentscripts.go @@ -338,6 +338,9 @@ func (r *Runner) run(ctx context.Context, script codersdk.WorkspaceAgentScript, return } + // We want to check this outside of the goroutine to avoid a race condition + timedOut := errors.Is(err, ErrTimeout) + err = r.trackCommandGoroutine(func() { var stage proto.Timing_Stage switch option { @@ -353,14 +356,14 @@ func (r *Runner) run(ctx context.Context, script codersdk.WorkspaceAgentScript, reportCtx, cancel := context.WithTimeout(context.Background(), reportTimeout) defer cancel() - _, err = r.scriptCompleted(reportCtx, &proto.WorkspaceAgentScriptCompletedRequest{ + _, err := r.scriptCompleted(reportCtx, &proto.WorkspaceAgentScriptCompletedRequest{ Timing: &proto.Timing{ ScriptId: script.ID[:], Start: timestamppb.New(start), End: timestamppb.New(end), ExitCode: int32(exitCode), Stage: stage, - TimedOut: errors.Is(err, ErrTimeout), + TimedOut: timedOut, }, }) if err != nil { From d7e86c6ec74120bbd50eaab7a9b01632f2648f86 Mon Sep 17 00:00:00 2001 From: Danielle Maywood Date: Mon, 23 Sep 2024 16:06:02 +0000 Subject: [PATCH 53/56] feat: replace timed_out column with status column --- agent/agentscripts/agentscripts.go | 15 +- agent/proto/agent.pb.go | 418 ++++++++++-------- agent/proto/agent.proto | 9 +- cli/organizationsettings.go | 8 +- coderd/agentapi/scripts.go | 14 +- coderd/agentapi/scripts_test.go | 27 +- coderd/database/dbauthz/dbauthz_test.go | 1 + coderd/database/dbmem/dbmem.go | 2 +- coderd/database/dump.sql | 9 +- ...57_workspace_agent_script_timings.down.sql | 1 + ...0257_workspace_agent_script_timings.up.sql | 19 +- coderd/database/models.go | 76 +++- coderd/database/queries.sql.go | 16 +- coderd/database/queries/workspaceagents.sql | 2 +- 14 files changed, 402 insertions(+), 215 deletions(-) diff --git a/agent/agentscripts/agentscripts.go b/agent/agentscripts/agentscripts.go index 367890b849a79..0051a9b100b38 100644 --- a/agent/agentscripts/agentscripts.go +++ b/agent/agentscripts/agentscripts.go @@ -340,6 +340,7 @@ func (r *Runner) run(ctx context.Context, script codersdk.WorkspaceAgentScript, // We want to check this outside of the goroutine to avoid a race condition timedOut := errors.Is(err, ErrTimeout) + pipesLeftOpen := errors.Is(err, ErrOutputPipesOpen) err = r.trackCommandGoroutine(func() { var stage proto.Timing_Stage @@ -352,6 +353,18 @@ func (r *Runner) run(ctx context.Context, script codersdk.WorkspaceAgentScript, stage = proto.Timing_CRON } + var status proto.Timing_Status + switch { + case !timedOut && !pipesLeftOpen && exitCode == 0: + status = proto.Timing_OK + case !timedOut && !pipesLeftOpen && exitCode != 0: + status = proto.Timing_EXIT_FAILURE + case timedOut: + status = proto.Timing_TIMED_OUT + case pipesLeftOpen: + status = proto.Timing_PIPES_LEFT_OPEN + } + reportTimeout := 30 * time.Second reportCtx, cancel := context.WithTimeout(context.Background(), reportTimeout) defer cancel() @@ -363,7 +376,7 @@ func (r *Runner) run(ctx context.Context, script codersdk.WorkspaceAgentScript, End: timestamppb.New(end), ExitCode: int32(exitCode), Stage: stage, - TimedOut: timedOut, + Status: status, }, }) if err != nil { diff --git a/agent/proto/agent.pb.go b/agent/proto/agent.pb.go index 6fb3fcbab9a34..8063b42f3b622 100644 --- a/agent/proto/agent.pb.go +++ b/agent/proto/agent.pb.go @@ -463,6 +463,58 @@ func (Timing_Stage) EnumDescriptor() ([]byte, []int) { return file_agent_proto_agent_proto_rawDescGZIP(), []int{27, 0} } +type Timing_Status int32 + +const ( + Timing_OK Timing_Status = 0 + Timing_EXIT_FAILURE Timing_Status = 1 + Timing_TIMED_OUT Timing_Status = 2 + Timing_PIPES_LEFT_OPEN Timing_Status = 3 +) + +// Enum value maps for Timing_Status. +var ( + Timing_Status_name = map[int32]string{ + 0: "OK", + 1: "EXIT_FAILURE", + 2: "TIMED_OUT", + 3: "PIPES_LEFT_OPEN", + } + Timing_Status_value = map[string]int32{ + "OK": 0, + "EXIT_FAILURE": 1, + "TIMED_OUT": 2, + "PIPES_LEFT_OPEN": 3, + } +) + +func (x Timing_Status) Enum() *Timing_Status { + p := new(Timing_Status) + *p = x + return p +} + +func (x Timing_Status) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (Timing_Status) Descriptor() protoreflect.EnumDescriptor { + return file_agent_proto_agent_proto_enumTypes[8].Descriptor() +} + +func (Timing_Status) Type() protoreflect.EnumType { + return &file_agent_proto_agent_proto_enumTypes[8] +} + +func (x Timing_Status) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use Timing_Status.Descriptor instead. +func (Timing_Status) EnumDescriptor() ([]byte, []int) { + return file_agent_proto_agent_proto_rawDescGZIP(), []int{27, 1} +} + type WorkspaceApp struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -2175,7 +2227,7 @@ type Timing struct { End *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=end,proto3" json:"end,omitempty"` ExitCode int32 `protobuf:"varint,4,opt,name=exit_code,json=exitCode,proto3" json:"exit_code,omitempty"` Stage Timing_Stage `protobuf:"varint,5,opt,name=stage,proto3,enum=coder.agent.v2.Timing_Stage" json:"stage,omitempty"` - TimedOut bool `protobuf:"varint,6,opt,name=timed_out,json=timedOut,proto3" json:"timed_out,omitempty"` + Status Timing_Status `protobuf:"varint,6,opt,name=status,proto3,enum=coder.agent.v2.Timing_Status" json:"status,omitempty"` } func (x *Timing) Reset() { @@ -2245,11 +2297,11 @@ func (x *Timing) GetStage() Timing_Stage { return Timing_START } -func (x *Timing) GetTimedOut() bool { +func (x *Timing) GetStatus() Timing_Status { if x != nil { - return x.TimedOut + return x.Status } - return false + return Timing_OK } type WorkspaceApp_Healthcheck struct { @@ -3016,7 +3068,7 @@ var file_agent_proto_agent_proto_rawDesc = []byte{ 0x6e, 0x67, 0x52, 0x06, 0x74, 0x69, 0x6d, 0x69, 0x6e, 0x67, 0x22, 0x27, 0x0a, 0x25, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x9b, 0x02, 0x0a, 0x06, 0x54, 0x69, 0x6d, 0x69, 0x6e, 0x67, 0x12, 0x1b, + 0x6e, 0x73, 0x65, 0x22, 0xfd, 0x02, 0x0a, 0x06, 0x54, 0x69, 0x6d, 0x69, 0x6e, 0x67, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x49, 0x64, 0x12, 0x30, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, @@ -3029,84 +3081,90 @@ var file_agent_proto_agent_proto_rawDesc = []byte{ 0x65, 0x78, 0x69, 0x74, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x32, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x67, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1c, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x54, 0x69, 0x6d, 0x69, 0x6e, 0x67, 0x2e, - 0x53, 0x74, 0x61, 0x67, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x67, 0x65, 0x12, 0x1b, 0x0a, 0x09, - 0x74, 0x69, 0x6d, 0x65, 0x64, 0x5f, 0x6f, 0x75, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x08, 0x74, 0x69, 0x6d, 0x65, 0x64, 0x4f, 0x75, 0x74, 0x22, 0x26, 0x0a, 0x05, 0x53, 0x74, 0x61, - 0x67, 0x65, 0x12, 0x09, 0x0a, 0x05, 0x53, 0x54, 0x41, 0x52, 0x54, 0x10, 0x00, 0x12, 0x08, 0x0a, - 0x04, 0x53, 0x54, 0x4f, 0x50, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x43, 0x52, 0x4f, 0x4e, 0x10, - 0x02, 0x2a, 0x63, 0x0a, 0x09, 0x41, 0x70, 0x70, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x12, 0x1a, - 0x0a, 0x16, 0x41, 0x50, 0x50, 0x5f, 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, 0x5f, 0x55, 0x4e, 0x53, - 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x44, 0x49, - 0x53, 0x41, 0x42, 0x4c, 0x45, 0x44, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x49, 0x4e, 0x49, 0x54, - 0x49, 0x41, 0x4c, 0x49, 0x5a, 0x49, 0x4e, 0x47, 0x10, 0x02, 0x12, 0x0b, 0x0a, 0x07, 0x48, 0x45, - 0x41, 0x4c, 0x54, 0x48, 0x59, 0x10, 0x03, 0x12, 0x0d, 0x0a, 0x09, 0x55, 0x4e, 0x48, 0x45, 0x41, - 0x4c, 0x54, 0x48, 0x59, 0x10, 0x04, 0x32, 0xef, 0x07, 0x0a, 0x05, 0x41, 0x67, 0x65, 0x6e, 0x74, - 0x12, 0x4b, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x12, - 0x22, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, - 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, - 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x12, 0x5a, 0x0a, - 0x10, 0x47, 0x65, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x42, 0x61, 0x6e, 0x6e, 0x65, - 0x72, 0x12, 0x27, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, - 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x42, 0x61, 0x6e, - 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x63, 0x6f, 0x64, - 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x12, 0x56, 0x0a, 0x0b, 0x55, 0x70, 0x64, - 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x22, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, - 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x63, - 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x54, 0x0a, 0x0f, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4c, 0x69, 0x66, 0x65, 0x63, - 0x79, 0x63, 0x6c, 0x65, 0x12, 0x26, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, - 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4c, 0x69, 0x66, 0x65, - 0x63, 0x79, 0x63, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x63, - 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x4c, 0x69, - 0x66, 0x65, 0x63, 0x79, 0x63, 0x6c, 0x65, 0x12, 0x72, 0x0a, 0x15, 0x42, 0x61, 0x74, 0x63, 0x68, - 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x70, 0x70, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x73, - 0x12, 0x2b, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, - 0x32, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x70, 0x70, - 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, - 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x42, - 0x61, 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x70, 0x70, 0x48, 0x65, 0x61, - 0x6c, 0x74, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4e, 0x0a, 0x0d, 0x55, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x12, 0x24, 0x2e, 0x63, - 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, - 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x12, 0x6e, 0x0a, 0x13, 0x42, - 0x61, 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, - 0x74, 0x61, 0x12, 0x2a, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, - 0x2e, 0x76, 0x32, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, - 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, + 0x53, 0x74, 0x61, 0x67, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x67, 0x65, 0x12, 0x35, 0x0a, 0x06, + 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1d, 0x2e, 0x63, + 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x54, 0x69, + 0x6d, 0x69, 0x6e, 0x67, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x22, 0x26, 0x0a, 0x05, 0x53, 0x74, 0x61, 0x67, 0x65, 0x12, 0x09, 0x0a, 0x05, + 0x53, 0x54, 0x41, 0x52, 0x54, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x53, 0x54, 0x4f, 0x50, 0x10, + 0x01, 0x12, 0x08, 0x0a, 0x04, 0x43, 0x52, 0x4f, 0x4e, 0x10, 0x02, 0x22, 0x46, 0x0a, 0x06, 0x53, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x06, 0x0a, 0x02, 0x4f, 0x4b, 0x10, 0x00, 0x12, 0x10, 0x0a, + 0x0c, 0x45, 0x58, 0x49, 0x54, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x55, 0x52, 0x45, 0x10, 0x01, 0x12, + 0x0d, 0x0a, 0x09, 0x54, 0x49, 0x4d, 0x45, 0x44, 0x5f, 0x4f, 0x55, 0x54, 0x10, 0x02, 0x12, 0x13, + 0x0a, 0x0f, 0x50, 0x49, 0x50, 0x45, 0x53, 0x5f, 0x4c, 0x45, 0x46, 0x54, 0x5f, 0x4f, 0x50, 0x45, + 0x4e, 0x10, 0x03, 0x2a, 0x63, 0x0a, 0x09, 0x41, 0x70, 0x70, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, + 0x12, 0x1a, 0x0a, 0x16, 0x41, 0x50, 0x50, 0x5f, 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, 0x5f, 0x55, + 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, + 0x44, 0x49, 0x53, 0x41, 0x42, 0x4c, 0x45, 0x44, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x49, 0x4e, + 0x49, 0x54, 0x49, 0x41, 0x4c, 0x49, 0x5a, 0x49, 0x4e, 0x47, 0x10, 0x02, 0x12, 0x0b, 0x0a, 0x07, + 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, 0x59, 0x10, 0x03, 0x12, 0x0d, 0x0a, 0x09, 0x55, 0x4e, 0x48, + 0x45, 0x41, 0x4c, 0x54, 0x48, 0x59, 0x10, 0x04, 0x32, 0xef, 0x07, 0x0a, 0x05, 0x41, 0x67, 0x65, + 0x6e, 0x74, 0x12, 0x4b, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, + 0x74, 0x12, 0x22, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, + 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, + 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x12, + 0x5a, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x42, 0x61, 0x6e, + 0x6e, 0x65, 0x72, 0x12, 0x27, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, + 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x42, + 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x63, + 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x12, 0x56, 0x0a, 0x0b, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x22, 0x2e, 0x63, 0x6f, 0x64, + 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, - 0x42, 0x61, 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, - 0x61, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x62, 0x0a, 0x0f, 0x42, - 0x61, 0x74, 0x63, 0x68, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4c, 0x6f, 0x67, 0x73, 0x12, 0x26, + 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x54, 0x0a, 0x0f, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4c, 0x69, 0x66, + 0x65, 0x63, 0x79, 0x63, 0x6c, 0x65, 0x12, 0x26, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, + 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4c, 0x69, + 0x66, 0x65, 0x63, 0x79, 0x63, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, - 0x42, 0x61, 0x74, 0x63, 0x68, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4c, 0x6f, 0x67, 0x73, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, - 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x43, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x77, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x41, 0x6e, 0x6e, 0x6f, 0x75, 0x6e, 0x63, 0x65, 0x6d, 0x65, - 0x6e, 0x74, 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x73, 0x12, 0x2d, 0x2e, 0x63, 0x6f, 0x64, 0x65, - 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x6e, - 0x6e, 0x6f, 0x75, 0x6e, 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, - 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, - 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x6e, 0x6e, - 0x6f, 0x75, 0x6e, 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x73, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7e, 0x0a, 0x0f, 0x53, 0x63, 0x72, 0x69, - 0x70, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x12, 0x34, 0x2e, 0x63, 0x6f, - 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x57, 0x6f, 0x72, - 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x53, 0x63, 0x72, 0x69, 0x70, - 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x35, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, - 0x76, 0x32, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x41, 0x67, 0x65, 0x6e, - 0x74, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x27, 0x5a, 0x25, 0x67, 0x69, 0x74, 0x68, - 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2f, 0x63, 0x6f, 0x64, - 0x65, 0x72, 0x2f, 0x76, 0x32, 0x2f, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2f, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x4c, 0x69, 0x66, 0x65, 0x63, 0x79, 0x63, 0x6c, 0x65, 0x12, 0x72, 0x0a, 0x15, 0x42, 0x61, 0x74, + 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x70, 0x70, 0x48, 0x65, 0x61, 0x6c, 0x74, + 0x68, 0x73, 0x12, 0x2b, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, + 0x2e, 0x76, 0x32, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, + 0x70, 0x70, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x2c, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, + 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x70, 0x70, 0x48, + 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4e, 0x0a, + 0x0d, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x12, 0x24, + 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, + 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, + 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x12, 0x6e, 0x0a, + 0x13, 0x42, 0x61, 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0x12, 0x2a, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, + 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x2b, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, + 0x32, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x62, 0x0a, + 0x0f, 0x42, 0x61, 0x74, 0x63, 0x68, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4c, 0x6f, 0x67, 0x73, + 0x12, 0x26, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, + 0x32, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4c, 0x6f, 0x67, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, + 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x43, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x77, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x41, 0x6e, 0x6e, 0x6f, 0x75, 0x6e, 0x63, 0x65, + 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x73, 0x12, 0x2d, 0x2e, 0x63, 0x6f, + 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, + 0x41, 0x6e, 0x6e, 0x6f, 0x75, 0x6e, 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x61, 0x6e, 0x6e, + 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x63, 0x6f, 0x64, + 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x41, + 0x6e, 0x6e, 0x6f, 0x75, 0x6e, 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x61, 0x6e, 0x6e, 0x65, + 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7e, 0x0a, 0x0f, 0x53, 0x63, + 0x72, 0x69, 0x70, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x12, 0x34, 0x2e, + 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x57, + 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x53, 0x63, 0x72, + 0x69, 0x70, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x35, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, + 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x41, 0x67, + 0x65, 0x6e, 0x74, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, + 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x27, 0x5a, 0x25, 0x67, 0x69, + 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2f, 0x63, + 0x6f, 0x64, 0x65, 0x72, 0x2f, 0x76, 0x32, 0x2f, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2f, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -3121,7 +3179,7 @@ func file_agent_proto_agent_proto_rawDescGZIP() []byte { return file_agent_proto_agent_proto_rawDescData } -var file_agent_proto_agent_proto_enumTypes = make([]protoimpl.EnumInfo, 8) +var file_agent_proto_agent_proto_enumTypes = make([]protoimpl.EnumInfo, 9) var file_agent_proto_agent_proto_msgTypes = make([]protoimpl.MessageInfo, 36) var file_agent_proto_agent_proto_goTypes = []interface{}{ (AppHealth)(0), // 0: coder.agent.v2.AppHealth @@ -3132,110 +3190,112 @@ var file_agent_proto_agent_proto_goTypes = []interface{}{ (Startup_Subsystem)(0), // 5: coder.agent.v2.Startup.Subsystem (Log_Level)(0), // 6: coder.agent.v2.Log.Level (Timing_Stage)(0), // 7: coder.agent.v2.Timing.Stage - (*WorkspaceApp)(nil), // 8: coder.agent.v2.WorkspaceApp - (*WorkspaceAgentScript)(nil), // 9: coder.agent.v2.WorkspaceAgentScript - (*WorkspaceAgentMetadata)(nil), // 10: coder.agent.v2.WorkspaceAgentMetadata - (*Manifest)(nil), // 11: coder.agent.v2.Manifest - (*GetManifestRequest)(nil), // 12: coder.agent.v2.GetManifestRequest - (*ServiceBanner)(nil), // 13: coder.agent.v2.ServiceBanner - (*GetServiceBannerRequest)(nil), // 14: coder.agent.v2.GetServiceBannerRequest - (*Stats)(nil), // 15: coder.agent.v2.Stats - (*UpdateStatsRequest)(nil), // 16: coder.agent.v2.UpdateStatsRequest - (*UpdateStatsResponse)(nil), // 17: coder.agent.v2.UpdateStatsResponse - (*Lifecycle)(nil), // 18: coder.agent.v2.Lifecycle - (*UpdateLifecycleRequest)(nil), // 19: coder.agent.v2.UpdateLifecycleRequest - (*BatchUpdateAppHealthRequest)(nil), // 20: coder.agent.v2.BatchUpdateAppHealthRequest - (*BatchUpdateAppHealthResponse)(nil), // 21: coder.agent.v2.BatchUpdateAppHealthResponse - (*Startup)(nil), // 22: coder.agent.v2.Startup - (*UpdateStartupRequest)(nil), // 23: coder.agent.v2.UpdateStartupRequest - (*Metadata)(nil), // 24: coder.agent.v2.Metadata - (*BatchUpdateMetadataRequest)(nil), // 25: coder.agent.v2.BatchUpdateMetadataRequest - (*BatchUpdateMetadataResponse)(nil), // 26: coder.agent.v2.BatchUpdateMetadataResponse - (*Log)(nil), // 27: coder.agent.v2.Log - (*BatchCreateLogsRequest)(nil), // 28: coder.agent.v2.BatchCreateLogsRequest - (*BatchCreateLogsResponse)(nil), // 29: coder.agent.v2.BatchCreateLogsResponse - (*GetAnnouncementBannersRequest)(nil), // 30: coder.agent.v2.GetAnnouncementBannersRequest - (*GetAnnouncementBannersResponse)(nil), // 31: coder.agent.v2.GetAnnouncementBannersResponse - (*BannerConfig)(nil), // 32: coder.agent.v2.BannerConfig - (*WorkspaceAgentScriptCompletedRequest)(nil), // 33: coder.agent.v2.WorkspaceAgentScriptCompletedRequest - (*WorkspaceAgentScriptCompletedResponse)(nil), // 34: coder.agent.v2.WorkspaceAgentScriptCompletedResponse - (*Timing)(nil), // 35: coder.agent.v2.Timing - (*WorkspaceApp_Healthcheck)(nil), // 36: coder.agent.v2.WorkspaceApp.Healthcheck - (*WorkspaceAgentMetadata_Result)(nil), // 37: coder.agent.v2.WorkspaceAgentMetadata.Result - (*WorkspaceAgentMetadata_Description)(nil), // 38: coder.agent.v2.WorkspaceAgentMetadata.Description - nil, // 39: coder.agent.v2.Manifest.EnvironmentVariablesEntry - nil, // 40: coder.agent.v2.Stats.ConnectionsByProtoEntry - (*Stats_Metric)(nil), // 41: coder.agent.v2.Stats.Metric - (*Stats_Metric_Label)(nil), // 42: coder.agent.v2.Stats.Metric.Label - (*BatchUpdateAppHealthRequest_HealthUpdate)(nil), // 43: coder.agent.v2.BatchUpdateAppHealthRequest.HealthUpdate - (*durationpb.Duration)(nil), // 44: google.protobuf.Duration - (*proto.DERPMap)(nil), // 45: coder.tailnet.v2.DERPMap - (*timestamppb.Timestamp)(nil), // 46: google.protobuf.Timestamp + (Timing_Status)(0), // 8: coder.agent.v2.Timing.Status + (*WorkspaceApp)(nil), // 9: coder.agent.v2.WorkspaceApp + (*WorkspaceAgentScript)(nil), // 10: coder.agent.v2.WorkspaceAgentScript + (*WorkspaceAgentMetadata)(nil), // 11: coder.agent.v2.WorkspaceAgentMetadata + (*Manifest)(nil), // 12: coder.agent.v2.Manifest + (*GetManifestRequest)(nil), // 13: coder.agent.v2.GetManifestRequest + (*ServiceBanner)(nil), // 14: coder.agent.v2.ServiceBanner + (*GetServiceBannerRequest)(nil), // 15: coder.agent.v2.GetServiceBannerRequest + (*Stats)(nil), // 16: coder.agent.v2.Stats + (*UpdateStatsRequest)(nil), // 17: coder.agent.v2.UpdateStatsRequest + (*UpdateStatsResponse)(nil), // 18: coder.agent.v2.UpdateStatsResponse + (*Lifecycle)(nil), // 19: coder.agent.v2.Lifecycle + (*UpdateLifecycleRequest)(nil), // 20: coder.agent.v2.UpdateLifecycleRequest + (*BatchUpdateAppHealthRequest)(nil), // 21: coder.agent.v2.BatchUpdateAppHealthRequest + (*BatchUpdateAppHealthResponse)(nil), // 22: coder.agent.v2.BatchUpdateAppHealthResponse + (*Startup)(nil), // 23: coder.agent.v2.Startup + (*UpdateStartupRequest)(nil), // 24: coder.agent.v2.UpdateStartupRequest + (*Metadata)(nil), // 25: coder.agent.v2.Metadata + (*BatchUpdateMetadataRequest)(nil), // 26: coder.agent.v2.BatchUpdateMetadataRequest + (*BatchUpdateMetadataResponse)(nil), // 27: coder.agent.v2.BatchUpdateMetadataResponse + (*Log)(nil), // 28: coder.agent.v2.Log + (*BatchCreateLogsRequest)(nil), // 29: coder.agent.v2.BatchCreateLogsRequest + (*BatchCreateLogsResponse)(nil), // 30: coder.agent.v2.BatchCreateLogsResponse + (*GetAnnouncementBannersRequest)(nil), // 31: coder.agent.v2.GetAnnouncementBannersRequest + (*GetAnnouncementBannersResponse)(nil), // 32: coder.agent.v2.GetAnnouncementBannersResponse + (*BannerConfig)(nil), // 33: coder.agent.v2.BannerConfig + (*WorkspaceAgentScriptCompletedRequest)(nil), // 34: coder.agent.v2.WorkspaceAgentScriptCompletedRequest + (*WorkspaceAgentScriptCompletedResponse)(nil), // 35: coder.agent.v2.WorkspaceAgentScriptCompletedResponse + (*Timing)(nil), // 36: coder.agent.v2.Timing + (*WorkspaceApp_Healthcheck)(nil), // 37: coder.agent.v2.WorkspaceApp.Healthcheck + (*WorkspaceAgentMetadata_Result)(nil), // 38: coder.agent.v2.WorkspaceAgentMetadata.Result + (*WorkspaceAgentMetadata_Description)(nil), // 39: coder.agent.v2.WorkspaceAgentMetadata.Description + nil, // 40: coder.agent.v2.Manifest.EnvironmentVariablesEntry + nil, // 41: coder.agent.v2.Stats.ConnectionsByProtoEntry + (*Stats_Metric)(nil), // 42: coder.agent.v2.Stats.Metric + (*Stats_Metric_Label)(nil), // 43: coder.agent.v2.Stats.Metric.Label + (*BatchUpdateAppHealthRequest_HealthUpdate)(nil), // 44: coder.agent.v2.BatchUpdateAppHealthRequest.HealthUpdate + (*durationpb.Duration)(nil), // 45: google.protobuf.Duration + (*proto.DERPMap)(nil), // 46: coder.tailnet.v2.DERPMap + (*timestamppb.Timestamp)(nil), // 47: google.protobuf.Timestamp } var file_agent_proto_agent_proto_depIdxs = []int32{ 1, // 0: coder.agent.v2.WorkspaceApp.sharing_level:type_name -> coder.agent.v2.WorkspaceApp.SharingLevel - 36, // 1: coder.agent.v2.WorkspaceApp.healthcheck:type_name -> coder.agent.v2.WorkspaceApp.Healthcheck + 37, // 1: coder.agent.v2.WorkspaceApp.healthcheck:type_name -> coder.agent.v2.WorkspaceApp.Healthcheck 2, // 2: coder.agent.v2.WorkspaceApp.health:type_name -> coder.agent.v2.WorkspaceApp.Health - 44, // 3: coder.agent.v2.WorkspaceAgentScript.timeout:type_name -> google.protobuf.Duration - 37, // 4: coder.agent.v2.WorkspaceAgentMetadata.result:type_name -> coder.agent.v2.WorkspaceAgentMetadata.Result - 38, // 5: coder.agent.v2.WorkspaceAgentMetadata.description:type_name -> coder.agent.v2.WorkspaceAgentMetadata.Description - 39, // 6: coder.agent.v2.Manifest.environment_variables:type_name -> coder.agent.v2.Manifest.EnvironmentVariablesEntry - 45, // 7: coder.agent.v2.Manifest.derp_map:type_name -> coder.tailnet.v2.DERPMap - 9, // 8: coder.agent.v2.Manifest.scripts:type_name -> coder.agent.v2.WorkspaceAgentScript - 8, // 9: coder.agent.v2.Manifest.apps:type_name -> coder.agent.v2.WorkspaceApp - 38, // 10: coder.agent.v2.Manifest.metadata:type_name -> coder.agent.v2.WorkspaceAgentMetadata.Description - 40, // 11: coder.agent.v2.Stats.connections_by_proto:type_name -> coder.agent.v2.Stats.ConnectionsByProtoEntry - 41, // 12: coder.agent.v2.Stats.metrics:type_name -> coder.agent.v2.Stats.Metric - 15, // 13: coder.agent.v2.UpdateStatsRequest.stats:type_name -> coder.agent.v2.Stats - 44, // 14: coder.agent.v2.UpdateStatsResponse.report_interval:type_name -> google.protobuf.Duration + 45, // 3: coder.agent.v2.WorkspaceAgentScript.timeout:type_name -> google.protobuf.Duration + 38, // 4: coder.agent.v2.WorkspaceAgentMetadata.result:type_name -> coder.agent.v2.WorkspaceAgentMetadata.Result + 39, // 5: coder.agent.v2.WorkspaceAgentMetadata.description:type_name -> coder.agent.v2.WorkspaceAgentMetadata.Description + 40, // 6: coder.agent.v2.Manifest.environment_variables:type_name -> coder.agent.v2.Manifest.EnvironmentVariablesEntry + 46, // 7: coder.agent.v2.Manifest.derp_map:type_name -> coder.tailnet.v2.DERPMap + 10, // 8: coder.agent.v2.Manifest.scripts:type_name -> coder.agent.v2.WorkspaceAgentScript + 9, // 9: coder.agent.v2.Manifest.apps:type_name -> coder.agent.v2.WorkspaceApp + 39, // 10: coder.agent.v2.Manifest.metadata:type_name -> coder.agent.v2.WorkspaceAgentMetadata.Description + 41, // 11: coder.agent.v2.Stats.connections_by_proto:type_name -> coder.agent.v2.Stats.ConnectionsByProtoEntry + 42, // 12: coder.agent.v2.Stats.metrics:type_name -> coder.agent.v2.Stats.Metric + 16, // 13: coder.agent.v2.UpdateStatsRequest.stats:type_name -> coder.agent.v2.Stats + 45, // 14: coder.agent.v2.UpdateStatsResponse.report_interval:type_name -> google.protobuf.Duration 4, // 15: coder.agent.v2.Lifecycle.state:type_name -> coder.agent.v2.Lifecycle.State - 46, // 16: coder.agent.v2.Lifecycle.changed_at:type_name -> google.protobuf.Timestamp - 18, // 17: coder.agent.v2.UpdateLifecycleRequest.lifecycle:type_name -> coder.agent.v2.Lifecycle - 43, // 18: coder.agent.v2.BatchUpdateAppHealthRequest.updates:type_name -> coder.agent.v2.BatchUpdateAppHealthRequest.HealthUpdate + 47, // 16: coder.agent.v2.Lifecycle.changed_at:type_name -> google.protobuf.Timestamp + 19, // 17: coder.agent.v2.UpdateLifecycleRequest.lifecycle:type_name -> coder.agent.v2.Lifecycle + 44, // 18: coder.agent.v2.BatchUpdateAppHealthRequest.updates:type_name -> coder.agent.v2.BatchUpdateAppHealthRequest.HealthUpdate 5, // 19: coder.agent.v2.Startup.subsystems:type_name -> coder.agent.v2.Startup.Subsystem - 22, // 20: coder.agent.v2.UpdateStartupRequest.startup:type_name -> coder.agent.v2.Startup - 37, // 21: coder.agent.v2.Metadata.result:type_name -> coder.agent.v2.WorkspaceAgentMetadata.Result - 24, // 22: coder.agent.v2.BatchUpdateMetadataRequest.metadata:type_name -> coder.agent.v2.Metadata - 46, // 23: coder.agent.v2.Log.created_at:type_name -> google.protobuf.Timestamp + 23, // 20: coder.agent.v2.UpdateStartupRequest.startup:type_name -> coder.agent.v2.Startup + 38, // 21: coder.agent.v2.Metadata.result:type_name -> coder.agent.v2.WorkspaceAgentMetadata.Result + 25, // 22: coder.agent.v2.BatchUpdateMetadataRequest.metadata:type_name -> coder.agent.v2.Metadata + 47, // 23: coder.agent.v2.Log.created_at:type_name -> google.protobuf.Timestamp 6, // 24: coder.agent.v2.Log.level:type_name -> coder.agent.v2.Log.Level - 27, // 25: coder.agent.v2.BatchCreateLogsRequest.logs:type_name -> coder.agent.v2.Log - 32, // 26: coder.agent.v2.GetAnnouncementBannersResponse.announcement_banners:type_name -> coder.agent.v2.BannerConfig - 35, // 27: coder.agent.v2.WorkspaceAgentScriptCompletedRequest.timing:type_name -> coder.agent.v2.Timing - 46, // 28: coder.agent.v2.Timing.start:type_name -> google.protobuf.Timestamp - 46, // 29: coder.agent.v2.Timing.end:type_name -> google.protobuf.Timestamp + 28, // 25: coder.agent.v2.BatchCreateLogsRequest.logs:type_name -> coder.agent.v2.Log + 33, // 26: coder.agent.v2.GetAnnouncementBannersResponse.announcement_banners:type_name -> coder.agent.v2.BannerConfig + 36, // 27: coder.agent.v2.WorkspaceAgentScriptCompletedRequest.timing:type_name -> coder.agent.v2.Timing + 47, // 28: coder.agent.v2.Timing.start:type_name -> google.protobuf.Timestamp + 47, // 29: coder.agent.v2.Timing.end:type_name -> google.protobuf.Timestamp 7, // 30: coder.agent.v2.Timing.stage:type_name -> coder.agent.v2.Timing.Stage - 44, // 31: coder.agent.v2.WorkspaceApp.Healthcheck.interval:type_name -> google.protobuf.Duration - 46, // 32: coder.agent.v2.WorkspaceAgentMetadata.Result.collected_at:type_name -> google.protobuf.Timestamp - 44, // 33: coder.agent.v2.WorkspaceAgentMetadata.Description.interval:type_name -> google.protobuf.Duration - 44, // 34: coder.agent.v2.WorkspaceAgentMetadata.Description.timeout:type_name -> google.protobuf.Duration - 3, // 35: coder.agent.v2.Stats.Metric.type:type_name -> coder.agent.v2.Stats.Metric.Type - 42, // 36: coder.agent.v2.Stats.Metric.labels:type_name -> coder.agent.v2.Stats.Metric.Label - 0, // 37: coder.agent.v2.BatchUpdateAppHealthRequest.HealthUpdate.health:type_name -> coder.agent.v2.AppHealth - 12, // 38: coder.agent.v2.Agent.GetManifest:input_type -> coder.agent.v2.GetManifestRequest - 14, // 39: coder.agent.v2.Agent.GetServiceBanner:input_type -> coder.agent.v2.GetServiceBannerRequest - 16, // 40: coder.agent.v2.Agent.UpdateStats:input_type -> coder.agent.v2.UpdateStatsRequest - 19, // 41: coder.agent.v2.Agent.UpdateLifecycle:input_type -> coder.agent.v2.UpdateLifecycleRequest - 20, // 42: coder.agent.v2.Agent.BatchUpdateAppHealths:input_type -> coder.agent.v2.BatchUpdateAppHealthRequest - 23, // 43: coder.agent.v2.Agent.UpdateStartup:input_type -> coder.agent.v2.UpdateStartupRequest - 25, // 44: coder.agent.v2.Agent.BatchUpdateMetadata:input_type -> coder.agent.v2.BatchUpdateMetadataRequest - 28, // 45: coder.agent.v2.Agent.BatchCreateLogs:input_type -> coder.agent.v2.BatchCreateLogsRequest - 30, // 46: coder.agent.v2.Agent.GetAnnouncementBanners:input_type -> coder.agent.v2.GetAnnouncementBannersRequest - 33, // 47: coder.agent.v2.Agent.ScriptCompleted:input_type -> coder.agent.v2.WorkspaceAgentScriptCompletedRequest - 11, // 48: coder.agent.v2.Agent.GetManifest:output_type -> coder.agent.v2.Manifest - 13, // 49: coder.agent.v2.Agent.GetServiceBanner:output_type -> coder.agent.v2.ServiceBanner - 17, // 50: coder.agent.v2.Agent.UpdateStats:output_type -> coder.agent.v2.UpdateStatsResponse - 18, // 51: coder.agent.v2.Agent.UpdateLifecycle:output_type -> coder.agent.v2.Lifecycle - 21, // 52: coder.agent.v2.Agent.BatchUpdateAppHealths:output_type -> coder.agent.v2.BatchUpdateAppHealthResponse - 22, // 53: coder.agent.v2.Agent.UpdateStartup:output_type -> coder.agent.v2.Startup - 26, // 54: coder.agent.v2.Agent.BatchUpdateMetadata:output_type -> coder.agent.v2.BatchUpdateMetadataResponse - 29, // 55: coder.agent.v2.Agent.BatchCreateLogs:output_type -> coder.agent.v2.BatchCreateLogsResponse - 31, // 56: coder.agent.v2.Agent.GetAnnouncementBanners:output_type -> coder.agent.v2.GetAnnouncementBannersResponse - 34, // 57: coder.agent.v2.Agent.ScriptCompleted:output_type -> coder.agent.v2.WorkspaceAgentScriptCompletedResponse - 48, // [48:58] is the sub-list for method output_type - 38, // [38:48] is the sub-list for method input_type - 38, // [38:38] is the sub-list for extension type_name - 38, // [38:38] is the sub-list for extension extendee - 0, // [0:38] is the sub-list for field type_name + 8, // 31: coder.agent.v2.Timing.status:type_name -> coder.agent.v2.Timing.Status + 45, // 32: coder.agent.v2.WorkspaceApp.Healthcheck.interval:type_name -> google.protobuf.Duration + 47, // 33: coder.agent.v2.WorkspaceAgentMetadata.Result.collected_at:type_name -> google.protobuf.Timestamp + 45, // 34: coder.agent.v2.WorkspaceAgentMetadata.Description.interval:type_name -> google.protobuf.Duration + 45, // 35: coder.agent.v2.WorkspaceAgentMetadata.Description.timeout:type_name -> google.protobuf.Duration + 3, // 36: coder.agent.v2.Stats.Metric.type:type_name -> coder.agent.v2.Stats.Metric.Type + 43, // 37: coder.agent.v2.Stats.Metric.labels:type_name -> coder.agent.v2.Stats.Metric.Label + 0, // 38: coder.agent.v2.BatchUpdateAppHealthRequest.HealthUpdate.health:type_name -> coder.agent.v2.AppHealth + 13, // 39: coder.agent.v2.Agent.GetManifest:input_type -> coder.agent.v2.GetManifestRequest + 15, // 40: coder.agent.v2.Agent.GetServiceBanner:input_type -> coder.agent.v2.GetServiceBannerRequest + 17, // 41: coder.agent.v2.Agent.UpdateStats:input_type -> coder.agent.v2.UpdateStatsRequest + 20, // 42: coder.agent.v2.Agent.UpdateLifecycle:input_type -> coder.agent.v2.UpdateLifecycleRequest + 21, // 43: coder.agent.v2.Agent.BatchUpdateAppHealths:input_type -> coder.agent.v2.BatchUpdateAppHealthRequest + 24, // 44: coder.agent.v2.Agent.UpdateStartup:input_type -> coder.agent.v2.UpdateStartupRequest + 26, // 45: coder.agent.v2.Agent.BatchUpdateMetadata:input_type -> coder.agent.v2.BatchUpdateMetadataRequest + 29, // 46: coder.agent.v2.Agent.BatchCreateLogs:input_type -> coder.agent.v2.BatchCreateLogsRequest + 31, // 47: coder.agent.v2.Agent.GetAnnouncementBanners:input_type -> coder.agent.v2.GetAnnouncementBannersRequest + 34, // 48: coder.agent.v2.Agent.ScriptCompleted:input_type -> coder.agent.v2.WorkspaceAgentScriptCompletedRequest + 12, // 49: coder.agent.v2.Agent.GetManifest:output_type -> coder.agent.v2.Manifest + 14, // 50: coder.agent.v2.Agent.GetServiceBanner:output_type -> coder.agent.v2.ServiceBanner + 18, // 51: coder.agent.v2.Agent.UpdateStats:output_type -> coder.agent.v2.UpdateStatsResponse + 19, // 52: coder.agent.v2.Agent.UpdateLifecycle:output_type -> coder.agent.v2.Lifecycle + 22, // 53: coder.agent.v2.Agent.BatchUpdateAppHealths:output_type -> coder.agent.v2.BatchUpdateAppHealthResponse + 23, // 54: coder.agent.v2.Agent.UpdateStartup:output_type -> coder.agent.v2.Startup + 27, // 55: coder.agent.v2.Agent.BatchUpdateMetadata:output_type -> coder.agent.v2.BatchUpdateMetadataResponse + 30, // 56: coder.agent.v2.Agent.BatchCreateLogs:output_type -> coder.agent.v2.BatchCreateLogsResponse + 32, // 57: coder.agent.v2.Agent.GetAnnouncementBanners:output_type -> coder.agent.v2.GetAnnouncementBannersResponse + 35, // 58: coder.agent.v2.Agent.ScriptCompleted:output_type -> coder.agent.v2.WorkspaceAgentScriptCompletedResponse + 49, // [49:59] is the sub-list for method output_type + 39, // [39:49] is the sub-list for method input_type + 39, // [39:39] is the sub-list for extension type_name + 39, // [39:39] is the sub-list for extension extendee + 0, // [0:39] is the sub-list for field type_name } func init() { file_agent_proto_agent_proto_init() } @@ -3658,7 +3718,7 @@ func file_agent_proto_agent_proto_init() { File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_agent_proto_agent_proto_rawDesc, - NumEnums: 8, + NumEnums: 9, NumMessages: 36, NumExtensions: 0, NumServices: 1, diff --git a/agent/proto/agent.proto b/agent/proto/agent.proto index cc34201618c9c..f307066fcbfdf 100644 --- a/agent/proto/agent.proto +++ b/agent/proto/agent.proto @@ -285,7 +285,14 @@ message Timing { CRON = 2; } Stage stage = 5; - bool timed_out = 6; + + enum Status { + OK = 0; + EXIT_FAILURE = 1; + TIMED_OUT = 2; + PIPES_LEFT_OPEN = 3; + } + Status status = 6; } service Agent { diff --git a/cli/organizationsettings.go b/cli/organizationsettings.go index c4422c8d372c6..2c6b901de10ca 100644 --- a/cli/organizationsettings.go +++ b/cli/organizationsettings.go @@ -125,13 +125,13 @@ func (r *RootCmd) setOrganizationSettings(orgContext *OrganizationContext, setti settingJSON, err := json.Marshal(output) if err != nil { - return fmt.Errorf("failed to marshal organization setting %s: %w", inv.Args[0], err) + return xerrors.Errorf("failed to marshal organization setting %s: %w", inv.Args[0], err) } var dst bytes.Buffer err = json.Indent(&dst, settingJSON, "", "\t") if err != nil { - return fmt.Errorf("failed to indent organization setting as json %s: %w", inv.Args[0], err) + return xerrors.Errorf("failed to indent organization setting as json %s: %w", inv.Args[0], err) } _, err = fmt.Fprintln(inv.Stdout, dst.String()) @@ -190,13 +190,13 @@ func (r *RootCmd) printOrganizationSetting(orgContext *OrganizationContext, sett settingJSON, err := json.Marshal(output) if err != nil { - return fmt.Errorf("failed to marshal organization setting %s: %w", inv.Args[0], err) + return xerrors.Errorf("failed to marshal organization setting %s: %w", inv.Args[0], err) } var dst bytes.Buffer err = json.Indent(&dst, settingJSON, "", "\t") if err != nil { - return fmt.Errorf("failed to indent organization setting as json %s: %w", inv.Args[0], err) + return xerrors.Errorf("failed to indent organization setting as json %s: %w", inv.Args[0], err) } _, err = fmt.Fprintln(inv.Stdout, dst.String()) diff --git a/coderd/agentapi/scripts.go b/coderd/agentapi/scripts.go index 451f9cd9dce2b..3aa085ade8a03 100644 --- a/coderd/agentapi/scripts.go +++ b/coderd/agentapi/scripts.go @@ -33,15 +33,27 @@ func (s *ScriptsAPI) ScriptCompleted(ctx context.Context, req *agentproto.Worksp stage = database.WorkspaceAgentScriptTimingStageCron } + var status database.WorkspaceAgentScriptTimingStatus + switch req.Timing.Status { + case agentproto.Timing_OK: + status = database.WorkspaceAgentScriptTimingStatusOk + case agentproto.Timing_EXIT_FAILURE: + status = database.WorkspaceAgentScriptTimingStatusExitFailure + case agentproto.Timing_TIMED_OUT: + status = database.WorkspaceAgentScriptTimingStatusTimedOut + case agentproto.Timing_PIPES_LEFT_OPEN: + status = database.WorkspaceAgentScriptTimingStatusPipesLeftOpen + } + //nolint:gocritic // We need permissions to write to the DB here and we are in the context of the agent. ctx = dbauthz.AsProvisionerd(ctx) err = s.Database.InsertWorkspaceAgentScriptTimings(ctx, database.InsertWorkspaceAgentScriptTimingsParams{ ScriptID: scriptID, Stage: stage, + Status: status, StartedAt: req.Timing.Start.AsTime(), EndedAt: req.Timing.End.AsTime(), ExitCode: req.Timing.ExitCode, - TimedOut: req.Timing.TimedOut, }) if err != nil { return nil, xerrors.Errorf("insert workspace agent script timings into database: %w", err) diff --git a/coderd/agentapi/scripts_test.go b/coderd/agentapi/scripts_test.go index c925619edae6c..44c1841be3396 100644 --- a/coderd/agentapi/scripts_test.go +++ b/coderd/agentapi/scripts_test.go @@ -29,7 +29,7 @@ func TestScriptCompleted(t *testing.T) { Stage: agentproto.Timing_START, Start: timestamppb.New(dbtime.Now()), End: timestamppb.New(dbtime.Now().Add(time.Second)), - TimedOut: false, + Status: agentproto.Timing_OK, ExitCode: 0, }, }, @@ -39,7 +39,7 @@ func TestScriptCompleted(t *testing.T) { Stage: agentproto.Timing_STOP, Start: timestamppb.New(dbtime.Now()), End: timestamppb.New(dbtime.Now().Add(time.Second)), - TimedOut: false, + Status: agentproto.Timing_OK, ExitCode: 0, }, }, @@ -49,7 +49,7 @@ func TestScriptCompleted(t *testing.T) { Stage: agentproto.Timing_CRON, Start: timestamppb.New(dbtime.Now()), End: timestamppb.New(dbtime.Now().Add(time.Second)), - TimedOut: false, + Status: agentproto.Timing_OK, ExitCode: 0, }, }, @@ -59,7 +59,7 @@ func TestScriptCompleted(t *testing.T) { Stage: agentproto.Timing_START, Start: timestamppb.New(dbtime.Now()), End: timestamppb.New(dbtime.Now().Add(time.Second)), - TimedOut: true, + Status: agentproto.Timing_TIMED_OUT, ExitCode: 255, }, }, @@ -69,7 +69,7 @@ func TestScriptCompleted(t *testing.T) { Stage: agentproto.Timing_START, Start: timestamppb.New(dbtime.Now()), End: timestamppb.New(dbtime.Now().Add(time.Second)), - TimedOut: true, + Status: agentproto.Timing_EXIT_FAILURE, ExitCode: 1, }, }, @@ -83,9 +83,9 @@ func TestScriptCompleted(t *testing.T) { mDB.EXPECT().InsertWorkspaceAgentScriptTimings(gomock.Any(), database.InsertWorkspaceAgentScriptTimingsParams{ ScriptID: tt.scriptID, Stage: protoScriptTimingStageToDatabase(tt.timing.Stage), + Status: protoScriptTimingStatusToDatabase(tt.timing.Status), StartedAt: tt.timing.Start.AsTime(), EndedAt: tt.timing.End.AsTime(), - TimedOut: tt.timing.TimedOut, ExitCode: tt.timing.ExitCode, }) @@ -108,3 +108,18 @@ func protoScriptTimingStageToDatabase(stage agentproto.Timing_Stage) database.Wo } return dbStage } + +func protoScriptTimingStatusToDatabase(stage agentproto.Timing_Status) database.WorkspaceAgentScriptTimingStatus { + var dbStatus database.WorkspaceAgentScriptTimingStatus + switch stage { + case agentproto.Timing_OK: + dbStatus = database.WorkspaceAgentScriptTimingStatusOk + case agentproto.Timing_EXIT_FAILURE: + dbStatus = database.WorkspaceAgentScriptTimingStatusExitFailure + case agentproto.Timing_TIMED_OUT: + dbStatus = database.WorkspaceAgentScriptTimingStatusTimedOut + case agentproto.Timing_PIPES_LEFT_OPEN: + dbStatus = database.WorkspaceAgentScriptTimingStatusPipesLeftOpen + } + return dbStatus +} diff --git a/coderd/database/dbauthz/dbauthz_test.go b/coderd/database/dbauthz/dbauthz_test.go index 266d477c2976e..10d5a32323a5f 100644 --- a/coderd/database/dbauthz/dbauthz_test.go +++ b/coderd/database/dbauthz/dbauthz_test.go @@ -2636,6 +2636,7 @@ func (s *MethodTestSuite) TestSystemFunctions() { check.Args(database.InsertWorkspaceAgentScriptTimingsParams{ ScriptID: uuid.New(), Stage: database.WorkspaceAgentScriptTimingStageStart, + Status: database.WorkspaceAgentScriptTimingStatusOk, }).Asserts(rbac.ResourceSystem, policy.ActionCreate) })) s.Run("InsertWorkspaceAgentScripts", s.Subtest(func(db database.Store, check *expects) { diff --git a/coderd/database/dbmem/dbmem.go b/coderd/database/dbmem/dbmem.go index 17ef6d4e06823..dbf8e5514ea2e 100644 --- a/coderd/database/dbmem/dbmem.go +++ b/coderd/database/dbmem/dbmem.go @@ -7844,7 +7844,7 @@ func (q *FakeQuerier) InsertWorkspaceAgentScriptTimings(_ context.Context, arg d EndedAt: arg.EndedAt, ExitCode: arg.ExitCode, Stage: arg.Stage, - TimedOut: arg.TimedOut, + Status: arg.Status, }, ) diff --git a/coderd/database/dump.sql b/coderd/database/dump.sql index 88293a554e8d2..a3b9f38bc197d 100644 --- a/coderd/database/dump.sql +++ b/coderd/database/dump.sql @@ -222,6 +222,13 @@ CREATE TYPE workspace_agent_script_timing_stage AS ENUM ( 'cron' ); +CREATE TYPE workspace_agent_script_timing_status AS ENUM ( + 'ok', + 'exit_failure', + 'timed_out', + 'pipes_left_open' +); + CREATE TYPE workspace_agent_subsystem AS ENUM ( 'envbuilder', 'envbox', @@ -1367,7 +1374,7 @@ CREATE TABLE workspace_agent_script_timings ( ended_at timestamp with time zone NOT NULL, exit_code integer NOT NULL, stage workspace_agent_script_timing_stage NOT NULL, - timed_out boolean NOT NULL + status workspace_agent_script_timing_status NOT NULL ); CREATE TABLE workspace_agent_scripts ( diff --git a/coderd/database/migrations/000257_workspace_agent_script_timings.down.sql b/coderd/database/migrations/000257_workspace_agent_script_timings.down.sql index 32c1980a08379..2d31e89383ca6 100644 --- a/coderd/database/migrations/000257_workspace_agent_script_timings.down.sql +++ b/coderd/database/migrations/000257_workspace_agent_script_timings.down.sql @@ -1,3 +1,4 @@ +DROP TYPE IF EXISTS workspace_agent_script_timing_status CASCADE; DROP TYPE IF EXISTS workspace_agent_script_timing_stage CASCADE; DROP TABLE IF EXISTS workspace_agent_script_timings; diff --git a/coderd/database/migrations/000257_workspace_agent_script_timings.up.sql b/coderd/database/migrations/000257_workspace_agent_script_timings.up.sql index 7e2f60136160e..3d9599dc7b374 100644 --- a/coderd/database/migrations/000257_workspace_agent_script_timings.up.sql +++ b/coderd/database/migrations/000257_workspace_agent_script_timings.up.sql @@ -6,14 +6,21 @@ CREATE TYPE workspace_agent_script_timing_stage AS ENUM ( 'cron' ); +CREATE TYPE workspace_agent_script_timing_status AS ENUM ( + 'ok', + 'exit_failure', + 'timed_out', + 'pipes_left_open' + ); + CREATE TABLE workspace_agent_script_timings ( - script_id uuid NOT NULL REFERENCES workspace_agent_scripts (id) ON DELETE CASCADE, - started_at timestamp with time zone NOT NULL, - ended_at timestamp with time zone NOT NULL, - exit_code int NOT NULL, - stage workspace_agent_script_timing_stage NOT NULL, - timed_out bool NOT NULL + script_id uuid NOT NULL REFERENCES workspace_agent_scripts (id) ON DELETE CASCADE, + started_at timestamp with time zone NOT NULL, + ended_at timestamp with time zone NOT NULL, + exit_code int NOT NULL, + stage workspace_agent_script_timing_stage NOT NULL, + status workspace_agent_script_timing_status NOT NULL ); ALTER TABLE workspace_agent_script_timings ADD UNIQUE (script_id, started_at); diff --git a/coderd/database/models.go b/coderd/database/models.go index 5282acc154fa0..499822bd8a727 100644 --- a/coderd/database/models.go +++ b/coderd/database/models.go @@ -1942,6 +1942,70 @@ func AllWorkspaceAgentScriptTimingStageValues() []WorkspaceAgentScriptTimingStag } } +type WorkspaceAgentScriptTimingStatus string + +const ( + WorkspaceAgentScriptTimingStatusOk WorkspaceAgentScriptTimingStatus = "ok" + WorkspaceAgentScriptTimingStatusExitFailure WorkspaceAgentScriptTimingStatus = "exit_failure" + WorkspaceAgentScriptTimingStatusTimedOut WorkspaceAgentScriptTimingStatus = "timed_out" + WorkspaceAgentScriptTimingStatusPipesLeftOpen WorkspaceAgentScriptTimingStatus = "pipes_left_open" +) + +func (e *WorkspaceAgentScriptTimingStatus) Scan(src interface{}) error { + switch s := src.(type) { + case []byte: + *e = WorkspaceAgentScriptTimingStatus(s) + case string: + *e = WorkspaceAgentScriptTimingStatus(s) + default: + return fmt.Errorf("unsupported scan type for WorkspaceAgentScriptTimingStatus: %T", src) + } + return nil +} + +type NullWorkspaceAgentScriptTimingStatus struct { + WorkspaceAgentScriptTimingStatus WorkspaceAgentScriptTimingStatus `json:"workspace_agent_script_timing_status"` + Valid bool `json:"valid"` // Valid is true if WorkspaceAgentScriptTimingStatus is not NULL +} + +// Scan implements the Scanner interface. +func (ns *NullWorkspaceAgentScriptTimingStatus) Scan(value interface{}) error { + if value == nil { + ns.WorkspaceAgentScriptTimingStatus, ns.Valid = "", false + return nil + } + ns.Valid = true + return ns.WorkspaceAgentScriptTimingStatus.Scan(value) +} + +// Value implements the driver Valuer interface. +func (ns NullWorkspaceAgentScriptTimingStatus) Value() (driver.Value, error) { + if !ns.Valid { + return nil, nil + } + return string(ns.WorkspaceAgentScriptTimingStatus), nil +} + +func (e WorkspaceAgentScriptTimingStatus) Valid() bool { + switch e { + case WorkspaceAgentScriptTimingStatusOk, + WorkspaceAgentScriptTimingStatusExitFailure, + WorkspaceAgentScriptTimingStatusTimedOut, + WorkspaceAgentScriptTimingStatusPipesLeftOpen: + return true + } + return false +} + +func AllWorkspaceAgentScriptTimingStatusValues() []WorkspaceAgentScriptTimingStatus { + return []WorkspaceAgentScriptTimingStatus{ + WorkspaceAgentScriptTimingStatusOk, + WorkspaceAgentScriptTimingStatusExitFailure, + WorkspaceAgentScriptTimingStatusTimedOut, + WorkspaceAgentScriptTimingStatusPipesLeftOpen, + } +} + type WorkspaceAgentSubsystem string const ( @@ -2946,12 +3010,12 @@ type WorkspaceAgentScript struct { } type WorkspaceAgentScriptTiming struct { - ScriptID uuid.UUID `db:"script_id" json:"script_id"` - StartedAt time.Time `db:"started_at" json:"started_at"` - EndedAt time.Time `db:"ended_at" json:"ended_at"` - ExitCode int32 `db:"exit_code" json:"exit_code"` - Stage WorkspaceAgentScriptTimingStage `db:"stage" json:"stage"` - TimedOut bool `db:"timed_out" json:"timed_out"` + ScriptID uuid.UUID `db:"script_id" json:"script_id"` + StartedAt time.Time `db:"started_at" json:"started_at"` + EndedAt time.Time `db:"ended_at" json:"ended_at"` + ExitCode int32 `db:"exit_code" json:"exit_code"` + Stage WorkspaceAgentScriptTimingStage `db:"stage" json:"stage"` + Status WorkspaceAgentScriptTimingStatus `db:"status" json:"status"` } type WorkspaceAgentStat struct { diff --git a/coderd/database/queries.sql.go b/coderd/database/queries.sql.go index bc262160edc74..a8ea40a395cf1 100644 --- a/coderd/database/queries.sql.go +++ b/coderd/database/queries.sql.go @@ -11810,19 +11810,19 @@ INSERT INTO ended_at, exit_code, stage, - timed_out + status ) VALUES ($1, $2, $3, $4, $5, $6) ` type InsertWorkspaceAgentScriptTimingsParams struct { - ScriptID uuid.UUID `db:"script_id" json:"script_id"` - StartedAt time.Time `db:"started_at" json:"started_at"` - EndedAt time.Time `db:"ended_at" json:"ended_at"` - ExitCode int32 `db:"exit_code" json:"exit_code"` - Stage WorkspaceAgentScriptTimingStage `db:"stage" json:"stage"` - TimedOut bool `db:"timed_out" json:"timed_out"` + ScriptID uuid.UUID `db:"script_id" json:"script_id"` + StartedAt time.Time `db:"started_at" json:"started_at"` + EndedAt time.Time `db:"ended_at" json:"ended_at"` + ExitCode int32 `db:"exit_code" json:"exit_code"` + Stage WorkspaceAgentScriptTimingStage `db:"stage" json:"stage"` + Status WorkspaceAgentScriptTimingStatus `db:"status" json:"status"` } func (q *sqlQuerier) InsertWorkspaceAgentScriptTimings(ctx context.Context, arg InsertWorkspaceAgentScriptTimingsParams) error { @@ -11832,7 +11832,7 @@ func (q *sqlQuerier) InsertWorkspaceAgentScriptTimings(ctx context.Context, arg arg.EndedAt, arg.ExitCode, arg.Stage, - arg.TimedOut, + arg.Status, ) return err } diff --git a/coderd/database/queries/workspaceagents.sql b/coderd/database/queries/workspaceagents.sql index 1121440999017..1020aba219920 100644 --- a/coderd/database/queries/workspaceagents.sql +++ b/coderd/database/queries/workspaceagents.sql @@ -296,7 +296,7 @@ INSERT INTO ended_at, exit_code, stage, - timed_out + status ) VALUES ($1, $2, $3, $4, $5, $6); From 6e338f280e9b67c7cee8a37da1607f32d941caa9 Mon Sep 17 00:00:00 2001 From: Danielle Maywood Date: Mon, 23 Sep 2024 16:12:34 +0000 Subject: [PATCH 54/56] test: update testdata fixture --- .../fixtures/000257_workspace_agent_script_timings.up.sql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/coderd/database/migrations/testdata/fixtures/000257_workspace_agent_script_timings.up.sql b/coderd/database/migrations/testdata/fixtures/000257_workspace_agent_script_timings.up.sql index c4334b0293768..d38b7e8c5d4ed 100644 --- a/coderd/database/migrations/testdata/fixtures/000257_workspace_agent_script_timings.up.sql +++ b/coderd/database/migrations/testdata/fixtures/000257_workspace_agent_script_timings.up.sql @@ -1,3 +1,3 @@ -INSERT INTO workspace_agent_script_timings (script_id, started_at, ended_at, exit_code, stage, timed_out) +INSERT INTO workspace_agent_script_timings (script_id, started_at, ended_at, exit_code, stage, status) VALUES - ((SELECT id FROM workspace_agent_scripts LIMIT 1), NOW() - INTERVAL '1 hour 55 minutes', NOW() - INTERVAL '1 hour 50 minutes', 0, 'start', false); + ((SELECT id FROM workspace_agent_scripts LIMIT 1), NOW() - INTERVAL '1 hour 55 minutes', NOW() - INTERVAL '1 hour 50 minutes', 0, 'start', 'ok'); From 79a620b43e1527d143a33a2a1699eaef2ad4f56b Mon Sep 17 00:00:00 2001 From: Danielle Maywood Date: Tue, 24 Sep 2024 09:37:39 +0000 Subject: [PATCH 55/56] fix: apply suggestions from review --- agent/agentscripts/agentscripts.go | 8 ++++---- coderd/database/dump.sql | 4 ++++ .../000257_workspace_agent_script_timings.up.sql | 13 +++++++++---- coderd/database/models.go | 2 ++ 4 files changed, 19 insertions(+), 8 deletions(-) diff --git a/agent/agentscripts/agentscripts.go b/agent/agentscripts/agentscripts.go index 0051a9b100b38..b4def315fab50 100644 --- a/agent/agentscripts/agentscripts.go +++ b/agent/agentscripts/agentscripts.go @@ -355,14 +355,14 @@ func (r *Runner) run(ctx context.Context, script codersdk.WorkspaceAgentScript, var status proto.Timing_Status switch { - case !timedOut && !pipesLeftOpen && exitCode == 0: - status = proto.Timing_OK - case !timedOut && !pipesLeftOpen && exitCode != 0: - status = proto.Timing_EXIT_FAILURE case timedOut: status = proto.Timing_TIMED_OUT case pipesLeftOpen: status = proto.Timing_PIPES_LEFT_OPEN + case exitCode != 0: + status = proto.Timing_EXIT_FAILURE + default: + status = proto.Timing_OK } reportTimeout := 30 * time.Second diff --git a/coderd/database/dump.sql b/coderd/database/dump.sql index a3b9f38bc197d..27c384e794239 100644 --- a/coderd/database/dump.sql +++ b/coderd/database/dump.sql @@ -222,6 +222,8 @@ CREATE TYPE workspace_agent_script_timing_stage AS ENUM ( 'cron' ); +COMMENT ON TYPE workspace_agent_script_timing_stage IS 'What stage the script was ran in.'; + CREATE TYPE workspace_agent_script_timing_status AS ENUM ( 'ok', 'exit_failure', @@ -229,6 +231,8 @@ CREATE TYPE workspace_agent_script_timing_status AS ENUM ( 'pipes_left_open' ); +COMMENT ON TYPE workspace_agent_script_timing_status IS 'What the exit status of the script is.'; + CREATE TYPE workspace_agent_subsystem AS ENUM ( 'envbuilder', 'envbox', diff --git a/coderd/database/migrations/000257_workspace_agent_script_timings.up.sql b/coderd/database/migrations/000257_workspace_agent_script_timings.up.sql index 3d9599dc7b374..1eb28f99b5d87 100644 --- a/coderd/database/migrations/000257_workspace_agent_script_timings.up.sql +++ b/coderd/database/migrations/000257_workspace_agent_script_timings.up.sql @@ -4,14 +4,18 @@ CREATE TYPE workspace_agent_script_timing_stage AS ENUM ( 'start', 'stop', 'cron' - ); +); + +COMMENT ON TYPE workspace_agent_script_timing_stage IS 'What stage the script was ran in.'; CREATE TYPE workspace_agent_script_timing_status AS ENUM ( 'ok', 'exit_failure', 'timed_out', 'pipes_left_open' - ); +); + +COMMENT ON TYPE workspace_agent_script_timing_status IS 'What the exit status of the script is.'; CREATE TABLE workspace_agent_script_timings ( @@ -20,7 +24,8 @@ CREATE TABLE workspace_agent_script_timings ended_at timestamp with time zone NOT NULL, exit_code int NOT NULL, stage workspace_agent_script_timing_stage NOT NULL, - status workspace_agent_script_timing_status NOT NULL + status workspace_agent_script_timing_status NOT NULL, + UNIQUE (script_id, started_at) ); -ALTER TABLE workspace_agent_script_timings ADD UNIQUE (script_id, started_at); +COMMENT ON TYPE workspace_agent_script_timings IS 'Timing and execution information about a script run.'; diff --git a/coderd/database/models.go b/coderd/database/models.go index 499822bd8a727..87ef020e8be5e 100644 --- a/coderd/database/models.go +++ b/coderd/database/models.go @@ -1881,6 +1881,7 @@ func AllWorkspaceAgentLifecycleStateValues() []WorkspaceAgentLifecycleState { } } +// What stage the script was ran in. type WorkspaceAgentScriptTimingStage string const ( @@ -1942,6 +1943,7 @@ func AllWorkspaceAgentScriptTimingStageValues() []WorkspaceAgentScriptTimingStag } } +// What the exit status of the script is. type WorkspaceAgentScriptTimingStatus string const ( From 180307fa45820d0b003aba9cadf4decebd192118 Mon Sep 17 00:00:00 2001 From: Danielle Maywood Date: Tue, 24 Sep 2024 09:40:07 +0000 Subject: [PATCH 56/56] revert: linter changes --- cli/organizationsettings.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cli/organizationsettings.go b/cli/organizationsettings.go index 2c6b901de10ca..c4422c8d372c6 100644 --- a/cli/organizationsettings.go +++ b/cli/organizationsettings.go @@ -125,13 +125,13 @@ func (r *RootCmd) setOrganizationSettings(orgContext *OrganizationContext, setti settingJSON, err := json.Marshal(output) if err != nil { - return xerrors.Errorf("failed to marshal organization setting %s: %w", inv.Args[0], err) + return fmt.Errorf("failed to marshal organization setting %s: %w", inv.Args[0], err) } var dst bytes.Buffer err = json.Indent(&dst, settingJSON, "", "\t") if err != nil { - return xerrors.Errorf("failed to indent organization setting as json %s: %w", inv.Args[0], err) + return fmt.Errorf("failed to indent organization setting as json %s: %w", inv.Args[0], err) } _, err = fmt.Fprintln(inv.Stdout, dst.String()) @@ -190,13 +190,13 @@ func (r *RootCmd) printOrganizationSetting(orgContext *OrganizationContext, sett settingJSON, err := json.Marshal(output) if err != nil { - return xerrors.Errorf("failed to marshal organization setting %s: %w", inv.Args[0], err) + return fmt.Errorf("failed to marshal organization setting %s: %w", inv.Args[0], err) } var dst bytes.Buffer err = json.Indent(&dst, settingJSON, "", "\t") if err != nil { - return xerrors.Errorf("failed to indent organization setting as json %s: %w", inv.Args[0], err) + return fmt.Errorf("failed to indent organization setting as json %s: %w", inv.Args[0], err) } _, err = fmt.Fprintln(inv.Stdout, dst.String())