From 4c8638c072b3f1cc5be116ebcf1f538c174ef395 Mon Sep 17 00:00:00 2001 From: "Cornelius A. Ludmann" Date: Fri, 22 Oct 2021 13:37:25 +0000 Subject: [PATCH 1/7] [registry-facade] Add desktop_ide_ref --- .../registry-facade-api/go/imagespec.pb.go | 69 +++++++++++-------- .../registry-facade-api/go/provider.pb.go | 4 +- .../registry-facade-api/imagespec.proto | 2 + .../pkg/registry/layersource.go | 12 ++++ .../registry-facade/pkg/registry/registry.go | 9 +++ 5 files changed, 65 insertions(+), 31 deletions(-) diff --git a/components/registry-facade-api/go/imagespec.pb.go b/components/registry-facade-api/go/imagespec.pb.go index be45e4d54c09f8..337e6558db6fb9 100644 --- a/components/registry-facade-api/go/imagespec.pb.go +++ b/components/registry-facade-api/go/imagespec.pb.go @@ -4,8 +4,8 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.26.0 -// protoc v3.15.5 +// protoc-gen-go v1.27.1 +// protoc v3.17.3 // source: imagespec.proto package api @@ -36,6 +36,8 @@ type ImageSpec struct { IdeRef string `protobuf:"bytes,2,opt,name=ide_ref,json=ideRef,proto3" json:"ide_ref,omitempty"` // content_layer describe the last few layers which provide the workspace's content ContentLayer []*ContentLayer `protobuf:"bytes,3,rep,name=content_layer,json=contentLayer,proto3" json:"content_layer,omitempty"` + // desktop_ide_ref point to an image denotign the desktop IDE to use + DesktopIdeRef string `protobuf:"bytes,4,opt,name=desktop_ide_ref,json=desktopIdeRef,proto3" json:"desktop_ide_ref,omitempty"` } func (x *ImageSpec) Reset() { @@ -91,6 +93,13 @@ func (x *ImageSpec) GetContentLayer() []*ContentLayer { return nil } +func (x *ImageSpec) GetDesktopIdeRef() string { + if x != nil { + return x.DesktopIdeRef + } + return "" +} + // ContentLayer is a layer that provides a workspace's content type ContentLayer struct { state protoimpl.MessageState @@ -318,7 +327,7 @@ var File_imagespec_proto protoreflect.FileDescriptor var file_imagespec_proto_rawDesc = []byte{ 0x0a, 0x0f, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x73, 0x70, 0x65, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0e, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x66, 0x61, 0x63, 0x61, 0x64, - 0x65, 0x22, 0x82, 0x01, 0x0a, 0x09, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x53, 0x70, 0x65, 0x63, 0x12, + 0x65, 0x22, 0xaa, 0x01, 0x0a, 0x09, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x53, 0x70, 0x65, 0x63, 0x12, 0x19, 0x0a, 0x08, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x72, 0x65, 0x66, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x62, 0x61, 0x73, 0x65, 0x52, 0x65, 0x66, 0x12, 0x17, 0x0a, 0x07, 0x69, 0x64, 0x65, 0x5f, 0x72, 0x65, 0x66, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x69, 0x64, 0x65, @@ -326,32 +335,34 @@ var file_imagespec_proto_rawDesc = []byte{ 0x61, 0x79, 0x65, 0x72, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x66, 0x61, 0x63, 0x61, 0x64, 0x65, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x52, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, - 0x74, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x22, 0x92, 0x01, 0x0a, 0x0c, 0x43, 0x6f, 0x6e, 0x74, 0x65, - 0x6e, 0x74, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x12, 0x3c, 0x0a, 0x06, 0x72, 0x65, 0x6d, 0x6f, 0x74, - 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, - 0x72, 0x79, 0x66, 0x61, 0x63, 0x61, 0x64, 0x65, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x43, - 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x48, 0x00, 0x52, 0x06, 0x72, - 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x12, 0x3c, 0x0a, 0x06, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, - 0x66, 0x61, 0x63, 0x61, 0x64, 0x65, 0x2e, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x43, 0x6f, 0x6e, - 0x74, 0x65, 0x6e, 0x74, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x48, 0x00, 0x52, 0x06, 0x64, 0x69, 0x72, - 0x65, 0x63, 0x74, 0x42, 0x06, 0x0a, 0x04, 0x73, 0x70, 0x65, 0x63, 0x22, 0x8a, 0x01, 0x0a, 0x12, - 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x4c, 0x61, 0x79, - 0x65, 0x72, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x03, 0x75, 0x72, 0x6c, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x12, 0x17, 0x0a, 0x07, - 0x64, 0x69, 0x66, 0x66, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, - 0x69, 0x66, 0x66, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x5f, 0x74, - 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6d, 0x65, 0x64, 0x69, 0x61, - 0x54, 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x05, 0x20, 0x01, - 0x28, 0x03, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x22, 0x2e, 0x0a, 0x12, 0x44, 0x69, 0x72, 0x65, - 0x63, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x12, 0x18, - 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x42, 0x31, 0x5a, 0x2f, 0x67, 0x69, 0x74, 0x68, - 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x69, 0x74, 0x70, 0x6f, 0x64, 0x2d, 0x69, 0x6f, - 0x2f, 0x67, 0x69, 0x74, 0x70, 0x6f, 0x64, 0x2f, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, - 0x2d, 0x66, 0x61, 0x63, 0x61, 0x64, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x62, 0x06, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x33, + 0x74, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x12, 0x26, 0x0a, 0x0f, 0x64, 0x65, 0x73, 0x6b, 0x74, 0x6f, + 0x70, 0x5f, 0x69, 0x64, 0x65, 0x5f, 0x72, 0x65, 0x66, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0d, 0x64, 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x49, 0x64, 0x65, 0x52, 0x65, 0x66, 0x22, 0x92, + 0x01, 0x0a, 0x0c, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x12, + 0x3c, 0x0a, 0x06, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x22, 0x2e, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x66, 0x61, 0x63, 0x61, 0x64, 0x65, + 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x4c, 0x61, + 0x79, 0x65, 0x72, 0x48, 0x00, 0x52, 0x06, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x12, 0x3c, 0x0a, + 0x06, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, + 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x66, 0x61, 0x63, 0x61, 0x64, 0x65, 0x2e, 0x44, + 0x69, 0x72, 0x65, 0x63, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x4c, 0x61, 0x79, 0x65, + 0x72, 0x48, 0x00, 0x52, 0x06, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x42, 0x06, 0x0a, 0x04, 0x73, + 0x70, 0x65, 0x63, 0x22, 0x8a, 0x01, 0x0a, 0x12, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x43, 0x6f, + 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, + 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x12, 0x16, 0x0a, 0x06, + 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, 0x69, + 0x67, 0x65, 0x73, 0x74, 0x12, 0x17, 0x0a, 0x07, 0x64, 0x69, 0x66, 0x66, 0x5f, 0x69, 0x64, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, 0x69, 0x66, 0x66, 0x49, 0x64, 0x12, 0x1d, 0x0a, + 0x0a, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x09, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x54, 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, + 0x73, 0x69, 0x7a, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, + 0x22, 0x2e, 0x0a, 0x12, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, + 0x74, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, + 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, + 0x42, 0x31, 0x5a, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, + 0x69, 0x74, 0x70, 0x6f, 0x64, 0x2d, 0x69, 0x6f, 0x2f, 0x67, 0x69, 0x74, 0x70, 0x6f, 0x64, 0x2f, + 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2d, 0x66, 0x61, 0x63, 0x61, 0x64, 0x65, 0x2f, + 0x61, 0x70, 0x69, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/components/registry-facade-api/go/provider.pb.go b/components/registry-facade-api/go/provider.pb.go index b592c1ee5b9a85..b6e6e0abadd06f 100644 --- a/components/registry-facade-api/go/provider.pb.go +++ b/components/registry-facade-api/go/provider.pb.go @@ -4,8 +4,8 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.26.0 -// protoc v3.15.5 +// protoc-gen-go v1.27.1 +// protoc v3.17.3 // source: provider.proto package api diff --git a/components/registry-facade-api/imagespec.proto b/components/registry-facade-api/imagespec.proto index 6915179b1c6543..74fd67d3ef19fc 100644 --- a/components/registry-facade-api/imagespec.proto +++ b/components/registry-facade-api/imagespec.proto @@ -12,6 +12,8 @@ message ImageSpec { string ide_ref = 2; // content_layer describe the last few layers which provide the workspace's content repeated ContentLayer content_layer = 3; + // desktop_ide_ref point to an image denotign the desktop IDE to use + string desktop_ide_ref = 4; } // ContentLayer is a layer that provides a workspace's content diff --git a/components/registry-facade/pkg/registry/layersource.go b/components/registry-facade/pkg/registry/layersource.go index 29834d83156139..2ed98400d1ccc4 100644 --- a/components/registry-facade/pkg/registry/layersource.go +++ b/components/registry-facade/pkg/registry/layersource.go @@ -394,6 +394,9 @@ func (src *SpecMappedImagedSource) Envs(ctx context.Context, spec *api.ImageSpec if err != nil { return nil, err } + if lsrc == nil { + return []EnvModifier{}, nil + } return lsrc.Envs(ctx, spec) } @@ -403,6 +406,9 @@ func (src *SpecMappedImagedSource) GetLayer(ctx context.Context, spec *api.Image if err != nil { return nil, err } + if lsrc == nil { + return []AddonLayer{}, nil + } return lsrc.GetLayer(ctx, spec) } @@ -412,6 +418,9 @@ func (src *SpecMappedImagedSource) HasBlob(ctx context.Context, spec *api.ImageS if err != nil { return false } + if lsrc == nil { + return false + } return lsrc.HasBlob(ctx, spec, dgst) } @@ -431,6 +440,9 @@ func (src *SpecMappedImagedSource) getDelegate(ctx context.Context, spec *api.Im if err != nil { return nil, err } + if ref == "" { + return nil, nil + } if s, ok := src.cache.Get(ref); ok { return s.(LayerSource), nil diff --git a/components/registry-facade/pkg/registry/registry.go b/components/registry-facade/pkg/registry/registry.go index 7fae9ba6ee3ac6..5e16d6abe91457 100644 --- a/components/registry-facade/pkg/registry/registry.go +++ b/components/registry-facade/pkg/registry/registry.go @@ -105,6 +105,15 @@ func NewRegistry(cfg config.Config, newResolver ResolverProvider, reg prometheus } layerSources = append(layerSources, ideLayerSource) + desktopIdeRefSource := func(s *api.ImageSpec) (ref string, err error) { + return s.DesktopIdeRef, nil + } + desktopIdeLayerSource, err := NewSpecMappedImageSource(newResolver, desktopIdeRefSource) + if err != nil { + return nil, err + } + layerSources = append(layerSources, desktopIdeLayerSource) + log.Info("preparing static layer") staticLayer := NewRevisioningLayerSource(CompositeLayerSource{}) layerSources = append(layerSources, staticLayer) From 1398e92647f194f7c236392739a07efaebb0011f Mon Sep 17 00:00:00 2001 From: "Cornelius A. Ludmann" Date: Fri, 22 Oct 2021 14:39:43 +0000 Subject: [PATCH 2/7] [ws-manager] Add destkop_ide_image --- components/ws-manager-api/core.proto | 6 + components/ws-manager-api/go/core.pb.go | 452 +++++++++--------- .../typescript/src/core_pb.d.ts | 6 + .../ws-manager-api/typescript/src/core_pb.js | 64 ++- components/ws-manager/pkg/manager/create.go | 5 +- components/ws-manager/pkg/manager/status.go | 21 +- 6 files changed, 327 insertions(+), 227 deletions(-) diff --git a/components/ws-manager-api/core.proto b/components/ws-manager-api/core.proto index a4ae74413ff630..20ed851262df33 100644 --- a/components/ws-manager-api/core.proto +++ b/components/ws-manager-api/core.proto @@ -290,6 +290,9 @@ message WorkspaceSpec { // The intervals in which a heartbeat must be received for the workspace not to time out string timeout = 7; + + // desktop_ide_image is the name of the Docker image used as desktop IDE + string desktop_ide_image = 8; } // PortSpec describes a networking port exposed on a workspace @@ -472,6 +475,9 @@ message StartWorkspaceSpec { // admission controlls who can access the workspace and its ports. AdmissionLevel admission = 11; + + // desktop_ide_image is the Docker image name of the desktop IDE image + string desktop_ide_image = 12; } // WorkspaceFeatureFlag enable non-standard behaviour in workspaces diff --git a/components/ws-manager-api/go/core.pb.go b/components/ws-manager-api/go/core.pb.go index 91a1f25a1f2bcd..99a21c4e32378f 100644 --- a/components/ws-manager-api/go/core.pb.go +++ b/components/ws-manager-api/go/core.pb.go @@ -1792,6 +1792,8 @@ type WorkspaceSpec struct { Type WorkspaceType `protobuf:"varint,6,opt,name=type,proto3,enum=wsman.WorkspaceType" json:"type,omitempty"` // The intervals in which a heartbeat must be received for the workspace not to time out Timeout string `protobuf:"bytes,7,opt,name=timeout,proto3" json:"timeout,omitempty"` + // desktop_ide_image is the name of the Docker image used as desktop IDE + DesktopIdeImage string `protobuf:"bytes,8,opt,name=desktop_ide_image,json=desktopIdeImage,proto3" json:"desktop_ide_image,omitempty"` } func (x *WorkspaceSpec) Reset() { @@ -1875,6 +1877,13 @@ func (x *WorkspaceSpec) GetTimeout() string { return "" } +func (x *WorkspaceSpec) GetDesktopIdeImage() string { + if x != nil { + return x.DesktopIdeImage + } + return "" +} + // PortSpec describes a networking port exposed on a workspace type PortSpec struct { state protoimpl.MessageState @@ -2325,6 +2334,8 @@ type StartWorkspaceSpec struct { Timeout string `protobuf:"bytes,10,opt,name=timeout,proto3" json:"timeout,omitempty"` // admission controlls who can access the workspace and its ports. Admission AdmissionLevel `protobuf:"varint,11,opt,name=admission,proto3,enum=wsman.AdmissionLevel" json:"admission,omitempty"` + // desktop_ide_image is the Docker image name of the desktop IDE image + DesktopIdeImage string `protobuf:"bytes,12,opt,name=desktop_ide_image,json=desktopIdeImage,proto3" json:"desktop_ide_image,omitempty"` } func (x *StartWorkspaceSpec) Reset() { @@ -2436,6 +2447,13 @@ func (x *StartWorkspaceSpec) GetAdmission() AdmissionLevel { return AdmissionLevel_ADMIT_OWNER_ONLY } +func (x *StartWorkspaceSpec) GetDesktopIdeImage() string { + if x != nil { + return x.DesktopIdeImage + } + return "" +} + // GitSpec configures the Git available within the workspace type GitSpec struct { state protoimpl.MessageState @@ -2698,7 +2716,7 @@ var file_core_proto_rawDesc = []byte{ 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x32, 0x0a, 0x04, 0x61, 0x75, 0x74, 0x68, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x77, 0x73, 0x6d, 0x61, 0x6e, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x04, 0x61, 0x75, 0x74, 0x68, 0x22, 0xfd, 0x01, 0x0a, 0x0d, 0x57, + 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x04, 0x61, 0x75, 0x74, 0x68, 0x22, 0xa9, 0x02, 0x0a, 0x0d, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x70, 0x65, 0x63, 0x12, 0x27, 0x0a, 0x0f, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, @@ -2714,221 +2732,227 @@ var file_core_proto_rawDesc = []byte{ 0x20, 0x01, 0x28, 0x0e, 0x32, 0x14, 0x2e, 0x77, 0x73, 0x6d, 0x61, 0x6e, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x22, 0x7f, 0x0a, 0x08, 0x50, 0x6f, - 0x72, 0x74, 0x53, 0x70, 0x65, 0x63, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x61, - 0x72, 0x67, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, - 0x65, 0x74, 0x12, 0x35, 0x0a, 0x0a, 0x76, 0x69, 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x77, 0x73, 0x6d, 0x61, 0x6e, 0x2e, 0x50, - 0x6f, 0x72, 0x74, 0x56, 0x69, 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x52, 0x0a, 0x76, - 0x69, 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x22, 0x93, 0x05, 0x0a, 0x13, - 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x06, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x74, - 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x74, 0x69, - 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x12, 0x44, 0x0a, 0x0e, 0x70, 0x75, 0x6c, 0x6c, 0x69, 0x6e, 0x67, - 0x5f, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1d, 0x2e, - 0x77, 0x73, 0x6d, 0x61, 0x6e, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x43, - 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x6f, 0x6f, 0x6c, 0x52, 0x0d, 0x70, 0x75, - 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x73, 0x12, 0x44, 0x0a, 0x0e, 0x73, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x65, 0x78, 0x69, 0x73, 0x74, 0x73, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x0e, 0x32, 0x1d, 0x2e, 0x77, 0x73, 0x6d, 0x61, 0x6e, 0x2e, 0x57, 0x6f, 0x72, 0x6b, - 0x73, 0x70, 0x61, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x6f, - 0x6f, 0x6c, 0x52, 0x0d, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x45, 0x78, 0x69, 0x73, 0x74, - 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x18, 0x05, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x08, 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x12, 0x51, 0x0a, - 0x15, 0x66, 0x69, 0x6e, 0x61, 0x6c, 0x5f, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x5f, 0x63, 0x6f, - 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1d, 0x2e, 0x77, - 0x73, 0x6d, 0x61, 0x6e, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x43, 0x6f, - 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x6f, 0x6f, 0x6c, 0x52, 0x13, 0x66, 0x69, 0x6e, - 0x61, 0x6c, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, - 0x12, 0x39, 0x0a, 0x08, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x65, 0x64, 0x18, 0x07, 0x20, 0x01, + 0x09, 0x52, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x12, 0x2a, 0x0a, 0x11, 0x64, 0x65, + 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x5f, 0x69, 0x64, 0x65, 0x5f, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x18, + 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x64, 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x49, 0x64, + 0x65, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x22, 0x7f, 0x0a, 0x08, 0x50, 0x6f, 0x72, 0x74, 0x53, 0x70, + 0x65, 0x63, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, + 0x52, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x35, + 0x0a, 0x0a, 0x76, 0x69, 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x77, 0x73, 0x6d, 0x61, 0x6e, 0x2e, 0x50, 0x6f, 0x72, 0x74, 0x56, + 0x69, 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x52, 0x0a, 0x76, 0x69, 0x73, 0x69, 0x62, + 0x69, 0x6c, 0x69, 0x74, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x22, 0x93, 0x05, 0x0a, 0x13, 0x57, 0x6f, 0x72, 0x6b, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, + 0x16, 0x0a, 0x06, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x06, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, + 0x75, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, + 0x74, 0x12, 0x44, 0x0a, 0x0e, 0x70, 0x75, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x5f, 0x69, 0x6d, 0x61, + 0x67, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1d, 0x2e, 0x77, 0x73, 0x6d, 0x61, + 0x6e, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x64, 0x69, + 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x6f, 0x6f, 0x6c, 0x52, 0x0d, 0x70, 0x75, 0x6c, 0x6c, 0x69, 0x6e, + 0x67, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x73, 0x12, 0x44, 0x0a, 0x0e, 0x73, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x5f, 0x65, 0x78, 0x69, 0x73, 0x74, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, + 0x1d, 0x2e, 0x77, 0x73, 0x6d, 0x61, 0x6e, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x6f, 0x6f, 0x6c, 0x52, 0x0d, + 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x45, 0x78, 0x69, 0x73, 0x74, 0x73, 0x12, 0x1a, 0x0a, + 0x08, 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x08, 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x12, 0x51, 0x0a, 0x15, 0x66, 0x69, 0x6e, + 0x61, 0x6c, 0x5f, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, + 0x74, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1d, 0x2e, 0x77, 0x73, 0x6d, 0x61, 0x6e, + 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x42, 0x6f, 0x6f, 0x6c, 0x52, 0x13, 0x66, 0x69, 0x6e, 0x61, 0x6c, 0x42, 0x61, + 0x63, 0x6b, 0x75, 0x70, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x39, 0x0a, 0x08, + 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x65, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1d, + 0x2e, 0x77, 0x73, 0x6d, 0x61, 0x6e, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, + 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x6f, 0x6f, 0x6c, 0x52, 0x08, 0x64, + 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x65, 0x64, 0x12, 0x49, 0x0a, 0x11, 0x6e, 0x65, 0x74, 0x77, 0x6f, + 0x72, 0x6b, 0x5f, 0x6e, 0x6f, 0x74, 0x5f, 0x72, 0x65, 0x61, 0x64, 0x79, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1d, 0x2e, 0x77, 0x73, 0x6d, 0x61, 0x6e, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x6f, 0x6f, - 0x6c, 0x52, 0x08, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x65, 0x64, 0x12, 0x49, 0x0a, 0x11, 0x6e, - 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x5f, 0x6e, 0x6f, 0x74, 0x5f, 0x72, 0x65, 0x61, 0x64, 0x79, - 0x18, 0x08, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1d, 0x2e, 0x77, 0x73, 0x6d, 0x61, 0x6e, 0x2e, 0x57, - 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, - 0x6e, 0x42, 0x6f, 0x6f, 0x6c, 0x52, 0x0f, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x4e, 0x6f, - 0x74, 0x52, 0x65, 0x61, 0x64, 0x79, 0x12, 0x4a, 0x0a, 0x13, 0x66, 0x69, 0x72, 0x73, 0x74, 0x5f, - 0x75, 0x73, 0x65, 0x72, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x18, 0x09, 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, - 0x11, 0x66, 0x69, 0x72, 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, - 0x74, 0x79, 0x12, 0x30, 0x0a, 0x14, 0x68, 0x65, 0x61, 0x64, 0x6c, 0x65, 0x73, 0x73, 0x5f, 0x74, - 0x61, 0x73, 0x6b, 0x5f, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x12, 0x68, 0x65, 0x61, 0x64, 0x6c, 0x65, 0x73, 0x73, 0x54, 0x61, 0x73, 0x6b, 0x46, 0x61, - 0x69, 0x6c, 0x65, 0x64, 0x12, 0x4b, 0x0a, 0x12, 0x73, 0x74, 0x6f, 0x70, 0x70, 0x65, 0x64, 0x5f, - 0x62, 0x79, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0e, - 0x32, 0x1d, 0x2e, 0x77, 0x73, 0x6d, 0x61, 0x6e, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, - 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x6f, 0x6f, 0x6c, 0x52, - 0x10, 0x73, 0x74, 0x6f, 0x70, 0x70, 0x65, 0x64, 0x42, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x22, 0x8a, 0x02, 0x0a, 0x11, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x4d, - 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x14, 0x0a, 0x05, 0x6f, 0x77, 0x6e, 0x65, 0x72, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x12, 0x17, 0x0a, - 0x07, 0x6d, 0x65, 0x74, 0x61, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, - 0x6d, 0x65, 0x74, 0x61, 0x49, 0x64, 0x12, 0x39, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x72, 0x74, 0x65, - 0x64, 0x5f, 0x61, 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, 0x73, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x41, - 0x74, 0x12, 0x4b, 0x0a, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x77, 0x73, 0x6d, 0x61, 0x6e, 0x2e, 0x57, - 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, - 0x2e, 0x41, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, - 0x79, 0x52, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0x3e, - 0x0a, 0x10, 0x41, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 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, 0x67, - 0x0a, 0x14, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x75, 0x6e, 0x74, 0x69, - 0x6d, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1b, 0x0a, 0x09, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x6e, - 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6e, 0x6f, 0x64, 0x65, 0x4e, - 0x61, 0x6d, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x70, 0x6f, 0x64, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x6f, 0x64, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x17, - 0x0a, 0x07, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x69, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x06, 0x6e, 0x6f, 0x64, 0x65, 0x49, 0x70, 0x22, 0x6f, 0x0a, 0x17, 0x57, 0x6f, 0x72, 0x6b, 0x73, - 0x70, 0x61, 0x63, 0x65, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x12, 0x33, 0x0a, 0x09, 0x61, 0x64, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x77, 0x73, 0x6d, 0x61, 0x6e, 0x2e, 0x41, 0x64, - 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x52, 0x09, 0x61, 0x64, - 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1f, 0x0a, 0x0b, 0x6f, 0x77, 0x6e, 0x65, 0x72, - 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6f, 0x77, - 0x6e, 0x65, 0x72, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x8e, 0x04, 0x0a, 0x12, 0x53, 0x74, 0x61, - 0x72, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x70, 0x65, 0x63, 0x12, - 0x27, 0x0a, 0x0f, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x69, 0x6d, 0x61, - 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, - 0x61, 0x63, 0x65, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x69, 0x64, 0x65, 0x5f, - 0x69, 0x6d, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x69, 0x64, 0x65, - 0x49, 0x6d, 0x61, 0x67, 0x65, 0x12, 0x40, 0x0a, 0x0d, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, - 0x5f, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x1b, 0x2e, 0x77, - 0x73, 0x6d, 0x61, 0x6e, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x46, 0x65, - 0x61, 0x74, 0x75, 0x72, 0x65, 0x46, 0x6c, 0x61, 0x67, 0x52, 0x0c, 0x66, 0x65, 0x61, 0x74, 0x75, - 0x72, 0x65, 0x46, 0x6c, 0x61, 0x67, 0x73, 0x12, 0x46, 0x0a, 0x0b, 0x69, 0x6e, 0x69, 0x74, 0x69, - 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x63, - 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x57, 0x6f, - 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x49, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x69, 0x7a, - 0x65, 0x72, 0x52, 0x0b, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x72, 0x12, - 0x25, 0x0a, 0x05, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0f, - 0x2e, 0x77, 0x73, 0x6d, 0x61, 0x6e, 0x2e, 0x50, 0x6f, 0x72, 0x74, 0x53, 0x70, 0x65, 0x63, 0x52, - 0x05, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x12, 0x34, 0x0a, 0x07, 0x65, 0x6e, 0x76, 0x76, 0x61, 0x72, - 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x77, 0x73, 0x6d, 0x61, 0x6e, 0x2e, - 0x45, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x56, 0x61, 0x72, 0x69, 0x61, - 0x62, 0x6c, 0x65, 0x52, 0x07, 0x65, 0x6e, 0x76, 0x76, 0x61, 0x72, 0x73, 0x12, 0x2b, 0x0a, 0x11, - 0x63, 0x68, 0x65, 0x63, 0x6b, 0x6f, 0x75, 0x74, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x6f, 0x75, - 0x74, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2d, 0x0a, 0x12, 0x77, 0x6f, 0x72, - 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, - 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, - 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x20, 0x0a, 0x03, 0x67, 0x69, 0x74, 0x18, - 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x77, 0x73, 0x6d, 0x61, 0x6e, 0x2e, 0x47, 0x69, - 0x74, 0x53, 0x70, 0x65, 0x63, 0x52, 0x03, 0x67, 0x69, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x74, 0x69, - 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x74, 0x69, 0x6d, - 0x65, 0x6f, 0x75, 0x74, 0x12, 0x33, 0x0a, 0x09, 0x61, 0x64, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, - 0x6e, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x77, 0x73, 0x6d, 0x61, 0x6e, 0x2e, - 0x41, 0x64, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x52, 0x09, - 0x61, 0x64, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x3b, 0x0a, 0x07, 0x47, 0x69, 0x74, - 0x53, 0x70, 0x65, 0x63, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, - 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x22, 0x3f, 0x0a, 0x13, 0x45, 0x6e, 0x76, 0x69, 0x72, 0x6f, - 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 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, 0x2a, 0x34, 0x0a, 0x13, 0x53, 0x74, 0x6f, 0x70, 0x57, - 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x0c, - 0x0a, 0x08, 0x4e, 0x4f, 0x52, 0x4d, 0x41, 0x4c, 0x4c, 0x59, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, - 0x49, 0x4d, 0x4d, 0x45, 0x44, 0x49, 0x41, 0x54, 0x45, 0x4c, 0x59, 0x10, 0x01, 0x2a, 0x3a, 0x0a, - 0x0e, 0x41, 0x64, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x12, - 0x14, 0x0a, 0x10, 0x41, 0x44, 0x4d, 0x49, 0x54, 0x5f, 0x4f, 0x57, 0x4e, 0x45, 0x52, 0x5f, 0x4f, - 0x4e, 0x4c, 0x59, 0x10, 0x00, 0x12, 0x12, 0x0a, 0x0e, 0x41, 0x44, 0x4d, 0x49, 0x54, 0x5f, 0x45, - 0x56, 0x45, 0x52, 0x59, 0x4f, 0x4e, 0x45, 0x10, 0x01, 0x2a, 0x49, 0x0a, 0x0e, 0x50, 0x6f, 0x72, - 0x74, 0x56, 0x69, 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x12, 0x1b, 0x0a, 0x17, 0x50, - 0x4f, 0x52, 0x54, 0x5f, 0x56, 0x49, 0x53, 0x49, 0x42, 0x49, 0x4c, 0x49, 0x54, 0x59, 0x5f, 0x50, - 0x52, 0x49, 0x56, 0x41, 0x54, 0x45, 0x10, 0x00, 0x12, 0x1a, 0x0a, 0x16, 0x50, 0x4f, 0x52, 0x54, - 0x5f, 0x56, 0x49, 0x53, 0x49, 0x42, 0x49, 0x4c, 0x49, 0x54, 0x59, 0x5f, 0x50, 0x55, 0x42, 0x4c, - 0x49, 0x43, 0x10, 0x01, 0x2a, 0x38, 0x0a, 0x16, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, - 0x65, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x6f, 0x6f, 0x6c, 0x12, 0x09, - 0x0a, 0x05, 0x46, 0x41, 0x4c, 0x53, 0x45, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x54, 0x52, 0x55, - 0x45, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x45, 0x4d, 0x50, 0x54, 0x59, 0x10, 0x02, 0x2a, 0x83, - 0x01, 0x0a, 0x0e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x50, 0x68, 0x61, 0x73, - 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x0b, - 0x0a, 0x07, 0x50, 0x45, 0x4e, 0x44, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x0c, 0x0a, 0x08, 0x43, - 0x52, 0x45, 0x41, 0x54, 0x49, 0x4e, 0x47, 0x10, 0x02, 0x12, 0x10, 0x0a, 0x0c, 0x49, 0x4e, 0x49, - 0x54, 0x49, 0x41, 0x4c, 0x49, 0x5a, 0x49, 0x4e, 0x47, 0x10, 0x03, 0x12, 0x0b, 0x0a, 0x07, 0x52, - 0x55, 0x4e, 0x4e, 0x49, 0x4e, 0x47, 0x10, 0x04, 0x12, 0x0f, 0x0a, 0x0b, 0x49, 0x4e, 0x54, 0x45, - 0x52, 0x52, 0x55, 0x50, 0x54, 0x45, 0x44, 0x10, 0x07, 0x12, 0x0c, 0x0a, 0x08, 0x53, 0x54, 0x4f, - 0x50, 0x50, 0x49, 0x4e, 0x47, 0x10, 0x05, 0x12, 0x0b, 0x0a, 0x07, 0x53, 0x54, 0x4f, 0x50, 0x50, - 0x45, 0x44, 0x10, 0x06, 0x2a, 0x68, 0x0a, 0x14, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, - 0x65, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x46, 0x6c, 0x61, 0x67, 0x12, 0x08, 0x0a, 0x04, - 0x4e, 0x4f, 0x4f, 0x50, 0x10, 0x00, 0x12, 0x19, 0x0a, 0x15, 0x46, 0x55, 0x4c, 0x4c, 0x5f, 0x57, - 0x4f, 0x52, 0x4b, 0x53, 0x50, 0x41, 0x43, 0x45, 0x5f, 0x42, 0x41, 0x43, 0x4b, 0x55, 0x50, 0x10, - 0x04, 0x12, 0x13, 0x0a, 0x0f, 0x46, 0x49, 0x58, 0x45, 0x44, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, - 0x52, 0x43, 0x45, 0x53, 0x10, 0x05, 0x22, 0x04, 0x08, 0x01, 0x10, 0x01, 0x22, 0x04, 0x08, 0x02, - 0x10, 0x02, 0x22, 0x04, 0x08, 0x03, 0x10, 0x03, 0x22, 0x04, 0x08, 0x06, 0x10, 0x06, 0x2a, 0x50, - 0x0a, 0x0d, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, - 0x0b, 0x0a, 0x07, 0x52, 0x45, 0x47, 0x55, 0x4c, 0x41, 0x52, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, - 0x50, 0x52, 0x45, 0x42, 0x55, 0x49, 0x4c, 0x44, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x50, 0x52, - 0x4f, 0x42, 0x45, 0x10, 0x02, 0x12, 0x09, 0x0a, 0x05, 0x47, 0x48, 0x4f, 0x53, 0x54, 0x10, 0x03, - 0x12, 0x0e, 0x0a, 0x0a, 0x49, 0x4d, 0x41, 0x47, 0x45, 0x42, 0x55, 0x49, 0x4c, 0x44, 0x10, 0x04, - 0x32, 0xe5, 0x06, 0x0a, 0x10, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x4d, 0x61, - 0x6e, 0x61, 0x67, 0x65, 0x72, 0x12, 0x4c, 0x0a, 0x0d, 0x47, 0x65, 0x74, 0x57, 0x6f, 0x72, 0x6b, - 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x12, 0x1b, 0x2e, 0x77, 0x73, 0x6d, 0x61, 0x6e, 0x2e, 0x47, - 0x65, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x77, 0x73, 0x6d, 0x61, 0x6e, 0x2e, 0x47, 0x65, 0x74, 0x57, - 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x00, 0x12, 0x4f, 0x0a, 0x0e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x57, 0x6f, 0x72, 0x6b, - 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x1c, 0x2e, 0x77, 0x73, 0x6d, 0x61, 0x6e, 0x2e, 0x53, 0x74, - 0x61, 0x72, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x77, 0x73, 0x6d, 0x61, 0x6e, 0x2e, 0x53, 0x74, 0x61, 0x72, - 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x00, 0x12, 0x4c, 0x0a, 0x0d, 0x53, 0x74, 0x6f, 0x70, 0x57, 0x6f, 0x72, 0x6b, - 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x1b, 0x2e, 0x77, 0x73, 0x6d, 0x61, 0x6e, 0x2e, 0x53, 0x74, - 0x6f, 0x70, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x77, 0x73, 0x6d, 0x61, 0x6e, 0x2e, 0x53, 0x74, 0x6f, 0x70, 0x57, - 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x00, 0x12, 0x58, 0x0a, 0x11, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x57, 0x6f, - 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x1f, 0x2e, 0x77, 0x73, 0x6d, 0x61, 0x6e, 0x2e, - 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, - 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x77, 0x73, 0x6d, 0x61, 0x6e, - 0x2e, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, - 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x52, 0x0a, 0x0f, - 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, - 0x1d, 0x2e, 0x77, 0x73, 0x6d, 0x61, 0x6e, 0x2e, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x57, 0x6f, - 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, - 0x2e, 0x77, 0x73, 0x6d, 0x61, 0x6e, 0x2e, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x57, 0x6f, 0x72, - 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, - 0x12, 0x42, 0x0a, 0x09, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x12, 0x17, 0x2e, - 0x77, 0x73, 0x6d, 0x61, 0x6e, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x77, 0x73, 0x6d, 0x61, 0x6e, 0x2e, 0x53, - 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x00, 0x30, 0x01, 0x12, 0x43, 0x0a, 0x0a, 0x4d, 0x61, 0x72, 0x6b, 0x41, 0x63, 0x74, 0x69, - 0x76, 0x65, 0x12, 0x18, 0x2e, 0x77, 0x73, 0x6d, 0x61, 0x6e, 0x2e, 0x4d, 0x61, 0x72, 0x6b, 0x41, - 0x63, 0x74, 0x69, 0x76, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x77, - 0x73, 0x6d, 0x61, 0x6e, 0x2e, 0x4d, 0x61, 0x72, 0x6b, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x43, 0x0a, 0x0a, 0x53, 0x65, 0x74, - 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x12, 0x18, 0x2e, 0x77, 0x73, 0x6d, 0x61, 0x6e, 0x2e, - 0x53, 0x65, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x19, 0x2e, 0x77, 0x73, 0x6d, 0x61, 0x6e, 0x2e, 0x53, 0x65, 0x74, 0x54, 0x69, 0x6d, - 0x65, 0x6f, 0x75, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x46, - 0x0a, 0x0b, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x19, 0x2e, - 0x77, 0x73, 0x6d, 0x61, 0x6e, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x50, 0x6f, 0x72, - 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x77, 0x73, 0x6d, 0x61, 0x6e, - 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x50, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x49, 0x0a, 0x0c, 0x54, 0x61, 0x6b, 0x65, 0x53, 0x6e, - 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x12, 0x1a, 0x2e, 0x77, 0x73, 0x6d, 0x61, 0x6e, 0x2e, 0x54, - 0x61, 0x6b, 0x65, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x77, 0x73, 0x6d, 0x61, 0x6e, 0x2e, 0x54, 0x61, 0x6b, 0x65, 0x53, - 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x00, 0x12, 0x55, 0x0a, 0x10, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x41, 0x64, 0x6d, 0x69, - 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1e, 0x2e, 0x77, 0x73, 0x6d, 0x61, 0x6e, 0x2e, 0x43, 0x6f, - 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x41, 0x64, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x77, 0x73, 0x6d, 0x61, 0x6e, 0x2e, 0x43, 0x6f, - 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x41, 0x64, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x2c, 0x5a, 0x2a, 0x67, 0x69, 0x74, 0x68, - 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x69, 0x74, 0x70, 0x6f, 0x64, 0x2d, 0x69, 0x6f, - 0x2f, 0x67, 0x69, 0x74, 0x70, 0x6f, 0x64, 0x2f, 0x77, 0x73, 0x2d, 0x6d, 0x61, 0x6e, 0x61, 0x67, - 0x65, 0x72, 0x2f, 0x61, 0x70, 0x69, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x6c, 0x52, 0x0f, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x4e, 0x6f, 0x74, 0x52, 0x65, 0x61, + 0x64, 0x79, 0x12, 0x4a, 0x0a, 0x13, 0x66, 0x69, 0x72, 0x73, 0x74, 0x5f, 0x75, 0x73, 0x65, 0x72, + 0x5f, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x18, 0x09, 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, 0x11, 0x66, 0x69, 0x72, + 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x12, 0x30, + 0x0a, 0x14, 0x68, 0x65, 0x61, 0x64, 0x6c, 0x65, 0x73, 0x73, 0x5f, 0x74, 0x61, 0x73, 0x6b, 0x5f, + 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x68, 0x65, + 0x61, 0x64, 0x6c, 0x65, 0x73, 0x73, 0x54, 0x61, 0x73, 0x6b, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, + 0x12, 0x4b, 0x0a, 0x12, 0x73, 0x74, 0x6f, 0x70, 0x70, 0x65, 0x64, 0x5f, 0x62, 0x79, 0x5f, 0x72, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1d, 0x2e, 0x77, + 0x73, 0x6d, 0x61, 0x6e, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x43, 0x6f, + 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x6f, 0x6f, 0x6c, 0x52, 0x10, 0x73, 0x74, 0x6f, + 0x70, 0x70, 0x65, 0x64, 0x42, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x8a, 0x02, + 0x0a, 0x11, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x12, 0x14, 0x0a, 0x05, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x05, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x12, 0x17, 0x0a, 0x07, 0x6d, 0x65, 0x74, + 0x61, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6d, 0x65, 0x74, 0x61, + 0x49, 0x64, 0x12, 0x39, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x5f, 0x61, 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, 0x73, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x4b, 0x0a, + 0x0b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x77, 0x73, 0x6d, 0x61, 0x6e, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, + 0x70, 0x61, 0x63, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x41, 0x6e, 0x6e, + 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0b, 0x61, + 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0x3e, 0x0a, 0x10, 0x41, 0x6e, + 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 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, 0x67, 0x0a, 0x14, 0x57, 0x6f, + 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x49, 0x6e, + 0x66, 0x6f, 0x12, 0x1b, 0x0a, 0x09, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6e, 0x6f, 0x64, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, + 0x19, 0x0a, 0x08, 0x70, 0x6f, 0x64, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x07, 0x70, 0x6f, 0x64, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x6e, 0x6f, + 0x64, 0x65, 0x5f, 0x69, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6e, 0x6f, 0x64, + 0x65, 0x49, 0x70, 0x22, 0x6f, 0x0a, 0x17, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, + 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x33, + 0x0a, 0x09, 0x61, 0x64, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0e, 0x32, 0x15, 0x2e, 0x77, 0x73, 0x6d, 0x61, 0x6e, 0x2e, 0x41, 0x64, 0x6d, 0x69, 0x73, 0x73, + 0x69, 0x6f, 0x6e, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x52, 0x09, 0x61, 0x64, 0x6d, 0x69, 0x73, 0x73, + 0x69, 0x6f, 0x6e, 0x12, 0x1f, 0x0a, 0x0b, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x5f, 0x74, 0x6f, 0x6b, + 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x54, + 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0xba, 0x04, 0x0a, 0x12, 0x53, 0x74, 0x61, 0x72, 0x74, 0x57, 0x6f, + 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x70, 0x65, 0x63, 0x12, 0x27, 0x0a, 0x0f, 0x77, + 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x49, + 0x6d, 0x61, 0x67, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x69, 0x64, 0x65, 0x5f, 0x69, 0x6d, 0x61, 0x67, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x69, 0x64, 0x65, 0x49, 0x6d, 0x61, 0x67, + 0x65, 0x12, 0x40, 0x0a, 0x0d, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x66, 0x6c, 0x61, + 0x67, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x1b, 0x2e, 0x77, 0x73, 0x6d, 0x61, 0x6e, + 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, + 0x65, 0x46, 0x6c, 0x61, 0x67, 0x52, 0x0c, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x46, 0x6c, + 0x61, 0x67, 0x73, 0x12, 0x46, 0x0a, 0x0b, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x69, 0x7a, + 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, + 0x6e, 0x74, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, + 0x61, 0x63, 0x65, 0x49, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x72, 0x52, 0x0b, + 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x72, 0x12, 0x25, 0x0a, 0x05, 0x70, + 0x6f, 0x72, 0x74, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x77, 0x73, 0x6d, + 0x61, 0x6e, 0x2e, 0x50, 0x6f, 0x72, 0x74, 0x53, 0x70, 0x65, 0x63, 0x52, 0x05, 0x70, 0x6f, 0x72, + 0x74, 0x73, 0x12, 0x34, 0x0a, 0x07, 0x65, 0x6e, 0x76, 0x76, 0x61, 0x72, 0x73, 0x18, 0x06, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x77, 0x73, 0x6d, 0x61, 0x6e, 0x2e, 0x45, 0x6e, 0x76, 0x69, + 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x52, + 0x07, 0x65, 0x6e, 0x76, 0x76, 0x61, 0x72, 0x73, 0x12, 0x2b, 0x0a, 0x11, 0x63, 0x68, 0x65, 0x63, + 0x6b, 0x6f, 0x75, 0x74, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x07, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x10, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x6f, 0x75, 0x74, 0x4c, 0x6f, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2d, 0x0a, 0x12, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x08, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x11, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x4c, 0x6f, 0x63, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x20, 0x0a, 0x03, 0x67, 0x69, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x0e, 0x2e, 0x77, 0x73, 0x6d, 0x61, 0x6e, 0x2e, 0x47, 0x69, 0x74, 0x53, 0x70, 0x65, + 0x63, 0x52, 0x03, 0x67, 0x69, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, + 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, + 0x12, 0x33, 0x0a, 0x09, 0x61, 0x64, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x0b, 0x20, + 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x77, 0x73, 0x6d, 0x61, 0x6e, 0x2e, 0x41, 0x64, 0x6d, 0x69, + 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x52, 0x09, 0x61, 0x64, 0x6d, 0x69, + 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x2a, 0x0a, 0x11, 0x64, 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, + 0x5f, 0x69, 0x64, 0x65, 0x5f, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0f, 0x64, 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x49, 0x64, 0x65, 0x49, 0x6d, 0x61, 0x67, + 0x65, 0x22, 0x3b, 0x0a, 0x07, 0x47, 0x69, 0x74, 0x53, 0x70, 0x65, 0x63, 0x12, 0x1a, 0x0a, 0x08, + 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, + 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, + 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x22, 0x3f, + 0x0a, 0x13, 0x45, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x56, 0x61, 0x72, + 0x69, 0x61, 0x62, 0x6c, 0x65, 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, 0x2a, + 0x34, 0x0a, 0x13, 0x53, 0x74, 0x6f, 0x70, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, + 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x0c, 0x0a, 0x08, 0x4e, 0x4f, 0x52, 0x4d, 0x41, 0x4c, + 0x4c, 0x59, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x49, 0x4d, 0x4d, 0x45, 0x44, 0x49, 0x41, 0x54, + 0x45, 0x4c, 0x59, 0x10, 0x01, 0x2a, 0x3a, 0x0a, 0x0e, 0x41, 0x64, 0x6d, 0x69, 0x73, 0x73, 0x69, + 0x6f, 0x6e, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x14, 0x0a, 0x10, 0x41, 0x44, 0x4d, 0x49, 0x54, + 0x5f, 0x4f, 0x57, 0x4e, 0x45, 0x52, 0x5f, 0x4f, 0x4e, 0x4c, 0x59, 0x10, 0x00, 0x12, 0x12, 0x0a, + 0x0e, 0x41, 0x44, 0x4d, 0x49, 0x54, 0x5f, 0x45, 0x56, 0x45, 0x52, 0x59, 0x4f, 0x4e, 0x45, 0x10, + 0x01, 0x2a, 0x49, 0x0a, 0x0e, 0x50, 0x6f, 0x72, 0x74, 0x56, 0x69, 0x73, 0x69, 0x62, 0x69, 0x6c, + 0x69, 0x74, 0x79, 0x12, 0x1b, 0x0a, 0x17, 0x50, 0x4f, 0x52, 0x54, 0x5f, 0x56, 0x49, 0x53, 0x49, + 0x42, 0x49, 0x4c, 0x49, 0x54, 0x59, 0x5f, 0x50, 0x52, 0x49, 0x56, 0x41, 0x54, 0x45, 0x10, 0x00, + 0x12, 0x1a, 0x0a, 0x16, 0x50, 0x4f, 0x52, 0x54, 0x5f, 0x56, 0x49, 0x53, 0x49, 0x42, 0x49, 0x4c, + 0x49, 0x54, 0x59, 0x5f, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x10, 0x01, 0x2a, 0x38, 0x0a, 0x16, + 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, + 0x6f, 0x6e, 0x42, 0x6f, 0x6f, 0x6c, 0x12, 0x09, 0x0a, 0x05, 0x46, 0x41, 0x4c, 0x53, 0x45, 0x10, + 0x00, 0x12, 0x08, 0x0a, 0x04, 0x54, 0x52, 0x55, 0x45, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x45, + 0x4d, 0x50, 0x54, 0x59, 0x10, 0x02, 0x2a, 0x83, 0x01, 0x0a, 0x0e, 0x57, 0x6f, 0x72, 0x6b, 0x73, + 0x70, 0x61, 0x63, 0x65, 0x50, 0x68, 0x61, 0x73, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, + 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x50, 0x45, 0x4e, 0x44, 0x49, 0x4e, + 0x47, 0x10, 0x01, 0x12, 0x0c, 0x0a, 0x08, 0x43, 0x52, 0x45, 0x41, 0x54, 0x49, 0x4e, 0x47, 0x10, + 0x02, 0x12, 0x10, 0x0a, 0x0c, 0x49, 0x4e, 0x49, 0x54, 0x49, 0x41, 0x4c, 0x49, 0x5a, 0x49, 0x4e, + 0x47, 0x10, 0x03, 0x12, 0x0b, 0x0a, 0x07, 0x52, 0x55, 0x4e, 0x4e, 0x49, 0x4e, 0x47, 0x10, 0x04, + 0x12, 0x0f, 0x0a, 0x0b, 0x49, 0x4e, 0x54, 0x45, 0x52, 0x52, 0x55, 0x50, 0x54, 0x45, 0x44, 0x10, + 0x07, 0x12, 0x0c, 0x0a, 0x08, 0x53, 0x54, 0x4f, 0x50, 0x50, 0x49, 0x4e, 0x47, 0x10, 0x05, 0x12, + 0x0b, 0x0a, 0x07, 0x53, 0x54, 0x4f, 0x50, 0x50, 0x45, 0x44, 0x10, 0x06, 0x2a, 0x68, 0x0a, 0x14, + 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, + 0x46, 0x6c, 0x61, 0x67, 0x12, 0x08, 0x0a, 0x04, 0x4e, 0x4f, 0x4f, 0x50, 0x10, 0x00, 0x12, 0x19, + 0x0a, 0x15, 0x46, 0x55, 0x4c, 0x4c, 0x5f, 0x57, 0x4f, 0x52, 0x4b, 0x53, 0x50, 0x41, 0x43, 0x45, + 0x5f, 0x42, 0x41, 0x43, 0x4b, 0x55, 0x50, 0x10, 0x04, 0x12, 0x13, 0x0a, 0x0f, 0x46, 0x49, 0x58, + 0x45, 0x44, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x53, 0x10, 0x05, 0x22, 0x04, + 0x08, 0x01, 0x10, 0x01, 0x22, 0x04, 0x08, 0x02, 0x10, 0x02, 0x22, 0x04, 0x08, 0x03, 0x10, 0x03, + 0x22, 0x04, 0x08, 0x06, 0x10, 0x06, 0x2a, 0x50, 0x0a, 0x0d, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, + 0x61, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x52, 0x45, 0x47, 0x55, 0x4c, + 0x41, 0x52, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x50, 0x52, 0x45, 0x42, 0x55, 0x49, 0x4c, 0x44, + 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x50, 0x52, 0x4f, 0x42, 0x45, 0x10, 0x02, 0x12, 0x09, 0x0a, + 0x05, 0x47, 0x48, 0x4f, 0x53, 0x54, 0x10, 0x03, 0x12, 0x0e, 0x0a, 0x0a, 0x49, 0x4d, 0x41, 0x47, + 0x45, 0x42, 0x55, 0x49, 0x4c, 0x44, 0x10, 0x04, 0x32, 0xe5, 0x06, 0x0a, 0x10, 0x57, 0x6f, 0x72, + 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x12, 0x4c, 0x0a, + 0x0d, 0x47, 0x65, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x12, 0x1b, + 0x2e, 0x77, 0x73, 0x6d, 0x61, 0x6e, 0x2e, 0x47, 0x65, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, + 0x61, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x77, 0x73, + 0x6d, 0x61, 0x6e, 0x2e, 0x47, 0x65, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4f, 0x0a, 0x0e, 0x53, + 0x74, 0x61, 0x72, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x1c, 0x2e, + 0x77, 0x73, 0x6d, 0x61, 0x6e, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x73, + 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x77, 0x73, + 0x6d, 0x61, 0x6e, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4c, 0x0a, 0x0d, + 0x53, 0x74, 0x6f, 0x70, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x1b, 0x2e, + 0x77, 0x73, 0x6d, 0x61, 0x6e, 0x2e, 0x53, 0x74, 0x6f, 0x70, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, + 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x77, 0x73, 0x6d, + 0x61, 0x6e, 0x2e, 0x53, 0x74, 0x6f, 0x70, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x58, 0x0a, 0x11, 0x44, 0x65, + 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, + 0x1f, 0x2e, 0x77, 0x73, 0x6d, 0x61, 0x6e, 0x2e, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, + 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x20, 0x2e, 0x77, 0x73, 0x6d, 0x61, 0x6e, 0x2e, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x62, + 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x00, 0x12, 0x52, 0x0a, 0x0f, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x57, 0x6f, + 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x1d, 0x2e, 0x77, 0x73, 0x6d, 0x61, 0x6e, 0x2e, + 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x77, 0x73, 0x6d, 0x61, 0x6e, 0x2e, 0x42, + 0x61, 0x63, 0x6b, 0x75, 0x70, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x42, 0x0a, 0x09, 0x53, 0x75, 0x62, 0x73, + 0x63, 0x72, 0x69, 0x62, 0x65, 0x12, 0x17, 0x2e, 0x77, 0x73, 0x6d, 0x61, 0x6e, 0x2e, 0x53, 0x75, + 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, + 0x2e, 0x77, 0x73, 0x6d, 0x61, 0x6e, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x43, 0x0a, 0x0a, + 0x4d, 0x61, 0x72, 0x6b, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x12, 0x18, 0x2e, 0x77, 0x73, 0x6d, + 0x61, 0x6e, 0x2e, 0x4d, 0x61, 0x72, 0x6b, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x77, 0x73, 0x6d, 0x61, 0x6e, 0x2e, 0x4d, 0x61, 0x72, + 0x6b, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x00, 0x12, 0x43, 0x0a, 0x0a, 0x53, 0x65, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x12, + 0x18, 0x2e, 0x77, 0x73, 0x6d, 0x61, 0x6e, 0x2e, 0x53, 0x65, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x6f, + 0x75, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x77, 0x73, 0x6d, 0x61, + 0x6e, 0x2e, 0x53, 0x65, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x46, 0x0a, 0x0b, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, + 0x6c, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x19, 0x2e, 0x77, 0x73, 0x6d, 0x61, 0x6e, 0x2e, 0x43, 0x6f, + 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x50, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x1a, 0x2e, 0x77, 0x73, 0x6d, 0x61, 0x6e, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, + 0x50, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x49, + 0x0a, 0x0c, 0x54, 0x61, 0x6b, 0x65, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x12, 0x1a, + 0x2e, 0x77, 0x73, 0x6d, 0x61, 0x6e, 0x2e, 0x54, 0x61, 0x6b, 0x65, 0x53, 0x6e, 0x61, 0x70, 0x73, + 0x68, 0x6f, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x77, 0x73, 0x6d, + 0x61, 0x6e, 0x2e, 0x54, 0x61, 0x6b, 0x65, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x55, 0x0a, 0x10, 0x43, 0x6f, 0x6e, + 0x74, 0x72, 0x6f, 0x6c, 0x41, 0x64, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1e, 0x2e, + 0x77, 0x73, 0x6d, 0x61, 0x6e, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x41, 0x64, 0x6d, + 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, + 0x77, 0x73, 0x6d, 0x61, 0x6e, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x41, 0x64, 0x6d, + 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, + 0x42, 0x2c, 0x5a, 0x2a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, + 0x69, 0x74, 0x70, 0x6f, 0x64, 0x2d, 0x69, 0x6f, 0x2f, 0x67, 0x69, 0x74, 0x70, 0x6f, 0x64, 0x2f, + 0x77, 0x73, 0x2d, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2f, 0x61, 0x70, 0x69, 0x62, 0x06, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/components/ws-manager-api/typescript/src/core_pb.d.ts b/components/ws-manager-api/typescript/src/core_pb.d.ts index ef1ed925f93061..2d7e8e185f38bc 100644 --- a/components/ws-manager-api/typescript/src/core_pb.d.ts +++ b/components/ws-manager-api/typescript/src/core_pb.d.ts @@ -613,6 +613,8 @@ export class WorkspaceSpec extends jspb.Message { setType(value: WorkspaceType): WorkspaceSpec; getTimeout(): string; setTimeout(value: string): WorkspaceSpec; + getDesktopIdeImage(): string; + setDesktopIdeImage(value: string): WorkspaceSpec; serializeBinary(): Uint8Array; toObject(includeInstance?: boolean): WorkspaceSpec.AsObject; @@ -633,6 +635,7 @@ export namespace WorkspaceSpec { exposedPortsList: Array, type: WorkspaceType, timeout: string, + desktopIdeImage: string, } } @@ -836,6 +839,8 @@ export class StartWorkspaceSpec extends jspb.Message { setTimeout(value: string): StartWorkspaceSpec; getAdmission(): AdmissionLevel; setAdmission(value: AdmissionLevel): StartWorkspaceSpec; + getDesktopIdeImage(): string; + setDesktopIdeImage(value: string): StartWorkspaceSpec; serializeBinary(): Uint8Array; toObject(includeInstance?: boolean): StartWorkspaceSpec.AsObject; @@ -860,6 +865,7 @@ export namespace StartWorkspaceSpec { git?: GitSpec.AsObject, timeout: string, admission: AdmissionLevel, + desktopIdeImage: string, } } diff --git a/components/ws-manager-api/typescript/src/core_pb.js b/components/ws-manager-api/typescript/src/core_pb.js index ebc8f5c6075081..c27948b55d10fc 100644 --- a/components/ws-manager-api/typescript/src/core_pb.js +++ b/components/ws-manager-api/typescript/src/core_pb.js @@ -4808,7 +4808,8 @@ proto.wsman.WorkspaceSpec.toObject = function(includeInstance, msg) { exposedPortsList: jspb.Message.toObjectList(msg.getExposedPortsList(), proto.wsman.PortSpec.toObject, includeInstance), type: jspb.Message.getFieldWithDefault(msg, 6, 0), - timeout: jspb.Message.getFieldWithDefault(msg, 7, "") + timeout: jspb.Message.getFieldWithDefault(msg, 7, ""), + desktopIdeImage: jspb.Message.getFieldWithDefault(msg, 8, "") }; if (includeInstance) { @@ -4874,6 +4875,10 @@ proto.wsman.WorkspaceSpec.deserializeBinaryFromReader = function(msg, reader) { var value = /** @type {string} */ (reader.readString()); msg.setTimeout(value); break; + case 8: + var value = /** @type {string} */ (reader.readString()); + msg.setDesktopIdeImage(value); + break; default: reader.skipField(); break; @@ -4953,6 +4958,13 @@ proto.wsman.WorkspaceSpec.serializeBinaryToWriter = function(message, writer) { f ); } + f = message.getDesktopIdeImage(); + if (f.length > 0) { + writer.writeString( + 8, + f + ); + } }; @@ -5102,6 +5114,24 @@ proto.wsman.WorkspaceSpec.prototype.setTimeout = function(value) { }; +/** + * optional string desktop_ide_image = 8; + * @return {string} + */ +proto.wsman.WorkspaceSpec.prototype.getDesktopIdeImage = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 8, "")); +}; + + +/** + * @param {string} value + * @return {!proto.wsman.WorkspaceSpec} returns this + */ +proto.wsman.WorkspaceSpec.prototype.setDesktopIdeImage = function(value) { + return jspb.Message.setProto3StringField(this, 8, value); +}; + + @@ -6418,7 +6448,8 @@ proto.wsman.StartWorkspaceSpec.toObject = function(includeInstance, msg) { workspaceLocation: jspb.Message.getFieldWithDefault(msg, 8, ""), git: (f = msg.getGit()) && proto.wsman.GitSpec.toObject(includeInstance, f), timeout: jspb.Message.getFieldWithDefault(msg, 10, ""), - admission: jspb.Message.getFieldWithDefault(msg, 11, 0) + admission: jspb.Message.getFieldWithDefault(msg, 11, 0), + desktopIdeImage: jspb.Message.getFieldWithDefault(msg, 12, "") }; if (includeInstance) { @@ -6505,6 +6536,10 @@ proto.wsman.StartWorkspaceSpec.deserializeBinaryFromReader = function(msg, reade var value = /** @type {!proto.wsman.AdmissionLevel} */ (reader.readEnum()); msg.setAdmission(value); break; + case 12: + var value = /** @type {string} */ (reader.readString()); + msg.setDesktopIdeImage(value); + break; default: reader.skipField(); break; @@ -6615,6 +6650,13 @@ proto.wsman.StartWorkspaceSpec.serializeBinaryToWriter = function(message, write f ); } + f = message.getDesktopIdeImage(); + if (f.length > 0) { + writer.writeString( + 12, + f + ); + } }; @@ -6913,6 +6955,24 @@ proto.wsman.StartWorkspaceSpec.prototype.setAdmission = function(value) { }; +/** + * optional string desktop_ide_image = 12; + * @return {string} + */ +proto.wsman.StartWorkspaceSpec.prototype.getDesktopIdeImage = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 12, "")); +}; + + +/** + * @param {string} value + * @return {!proto.wsman.StartWorkspaceSpec} returns this + */ +proto.wsman.StartWorkspaceSpec.prototype.setDesktopIdeImage = function(value) { + return jspb.Message.setProto3StringField(this, 12, value); +}; + + diff --git a/components/ws-manager/pkg/manager/create.go b/components/ws-manager/pkg/manager/create.go index 7482ca6224ae69..1372e312ebb077 100644 --- a/components/ws-manager/pkg/manager/create.go +++ b/components/ws-manager/pkg/manager/create.go @@ -237,8 +237,9 @@ func (m *Manager) createDefiniteWorkspacePod(startContext *startWorkspaceContext } spec := regapi.ImageSpec{ - BaseRef: startContext.Request.Spec.WorkspaceImage, - IdeRef: startContext.Request.Spec.IdeImage, + BaseRef: startContext.Request.Spec.WorkspaceImage, + IdeRef: startContext.Request.Spec.IdeImage, + DesktopIdeRef: startContext.Request.Spec.DesktopIdeImage, } imageSpec, err := spec.ToBase64() if err != nil { diff --git a/components/ws-manager/pkg/manager/status.go b/components/ws-manager/pkg/manager/status.go index 19ee07fdce1cf8..ff0db78f009241 100644 --- a/components/ws-manager/pkg/manager/status.go +++ b/components/ws-manager/pkg/manager/status.go @@ -241,16 +241,18 @@ func (m *Manager) getWorkspaceStatus(wso workspaceObjects) (*api.WorkspaceStatus } var ( - wsImage = workspaceContainer.Image - ideImage string + wsImage = workspaceContainer.Image + ideImage string + desktopIdeImage string ) if ispec, ok := wso.Pod.Annotations[workspaceImageSpecAnnotation]; ok { spec, err := regapi.ImageSpecFromBase64(ispec) if err != nil { - return nil, xerrors.Errorf("invalid iamge spec: %w", err) + return nil, xerrors.Errorf("invalid image spec: %w", err) } wsImage = spec.BaseRef ideImage = spec.IdeRef + desktopIdeImage = spec.DesktopIdeRef } ownerToken, ok := wso.Pod.Annotations[ownerTokenAnnotation] @@ -267,12 +269,13 @@ func (m *Manager) getWorkspaceStatus(wso workspaceObjects) (*api.WorkspaceStatus StatusVersion: m.clock.Tick(), Metadata: getWorkspaceMetadata(wso.Pod), Spec: &api.WorkspaceSpec{ - Headless: wso.IsWorkspaceHeadless(), - WorkspaceImage: wsImage, - IdeImage: ideImage, - Url: wsurl, - Type: tpe, - Timeout: timeout, + Headless: wso.IsWorkspaceHeadless(), + WorkspaceImage: wsImage, + IdeImage: ideImage, + DesktopIdeImage: desktopIdeImage, + Url: wsurl, + Type: tpe, + Timeout: timeout, }, Conditions: &api.WorkspaceConditions{ Snapshot: wso.Pod.Annotations[workspaceSnapshotAnnotation], From 60d510e581a897469e622b3e33e6d1ecf2072a11 Mon Sep 17 00:00:00 2001 From: "Cornelius A. Ludmann" Date: Fri, 22 Oct 2021 15:01:50 +0000 Subject: [PATCH 3/7] [supervisor] Add desktop IDE backend support /werft with-clean-slate-deployment --- components/supervisor-api/go/status.pb.go | 537 +++++---- components/supervisor-api/java/.project | 2 +- .../java/io/gitpod/supervisor/api/Status.java | 1061 ++++++++++++++++- components/supervisor-api/status.proto | 7 + .../supervisor/pkg/supervisor/config.go | 53 +- .../supervisor/pkg/supervisor/services.go | 55 +- .../supervisor/pkg/supervisor/supervisor.go | 239 ++-- components/supervisor/supervisor-config.json | 1 + 8 files changed, 1564 insertions(+), 391 deletions(-) diff --git a/components/supervisor-api/go/status.pb.go b/components/supervisor-api/go/status.pb.go index fa6b3fec06e854..b9bbfdc5e20233 100644 --- a/components/supervisor-api/go/status.pb.go +++ b/components/supervisor-api/go/status.pb.go @@ -412,7 +412,8 @@ type IDEStatusResponse struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Ok bool `protobuf:"varint,1,opt,name=ok,proto3" json:"ok,omitempty"` + Ok bool `protobuf:"varint,1,opt,name=ok,proto3" json:"ok,omitempty"` + Desktop *IDEStatusResponse_DesktopStatus `protobuf:"bytes,2,opt,name=desktop,proto3" json:"desktop,omitempty"` } func (x *IDEStatusResponse) Reset() { @@ -454,6 +455,13 @@ func (x *IDEStatusResponse) GetOk() bool { return false } +func (x *IDEStatusResponse) GetDesktop() *IDEStatusResponse_DesktopStatus { + if x != nil { + return x.Desktop + } + return nil +} + type ContentStatusRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1202,6 +1210,61 @@ func (x *TaskPresentation) GetOpenMode() string { return "" } +type IDEStatusResponse_DesktopStatus struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Link string `protobuf:"bytes,1,opt,name=link,proto3" json:"link,omitempty"` + Label string `protobuf:"bytes,2,opt,name=label,proto3" json:"label,omitempty"` +} + +func (x *IDEStatusResponse_DesktopStatus) Reset() { + *x = IDEStatusResponse_DesktopStatus{} + if protoimpl.UnsafeEnabled { + mi := &file_status_proto_msgTypes[17] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *IDEStatusResponse_DesktopStatus) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*IDEStatusResponse_DesktopStatus) ProtoMessage() {} + +func (x *IDEStatusResponse_DesktopStatus) ProtoReflect() protoreflect.Message { + mi := &file_status_proto_msgTypes[17] + 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 IDEStatusResponse_DesktopStatus.ProtoReflect.Descriptor instead. +func (*IDEStatusResponse_DesktopStatus) Descriptor() ([]byte, []int) { + return file_status_proto_rawDescGZIP(), []int{3, 0} +} + +func (x *IDEStatusResponse_DesktopStatus) GetLink() string { + if x != nil { + return x.Link + } + return "" +} + +func (x *IDEStatusResponse_DesktopStatus) GetLabel() string { + if x != nil { + return x.Label + } + return "" +} + var File_status_proto protoreflect.FileDescriptor var file_status_proto_rawDesc = []byte{ @@ -1216,175 +1279,185 @@ var file_status_proto_rawDesc = []byte{ 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x02, 0x6f, 0x6b, 0x22, 0x26, 0x0a, 0x10, 0x49, 0x44, 0x45, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x77, 0x61, 0x69, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, 0x77, - 0x61, 0x69, 0x74, 0x22, 0x23, 0x0a, 0x11, 0x49, 0x44, 0x45, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x6f, 0x6b, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x02, 0x6f, 0x6b, 0x22, 0x2a, 0x0a, 0x14, 0x43, 0x6f, 0x6e, 0x74, - 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x12, 0x0a, 0x04, 0x77, 0x61, 0x69, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, - 0x77, 0x61, 0x69, 0x74, 0x22, 0x68, 0x0a, 0x15, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x53, - 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1c, 0x0a, - 0x09, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x09, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x31, 0x0a, 0x06, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x19, 0x2e, 0x73, 0x75, - 0x70, 0x65, 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, - 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x22, 0x15, - 0x0a, 0x13, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x41, 0x0a, 0x14, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x53, - 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x29, 0x0a, - 0x10, 0x63, 0x61, 0x6e, 0x61, 0x72, 0x79, 0x5f, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, - 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x63, 0x61, 0x6e, 0x61, 0x72, 0x79, 0x41, - 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x22, 0x2e, 0x0a, 0x12, 0x50, 0x6f, 0x72, 0x74, - 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, - 0x0a, 0x07, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x07, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x22, 0x44, 0x0a, 0x13, 0x50, 0x6f, 0x72, 0x74, - 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x2d, 0x0a, 0x05, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, - 0x2e, 0x73, 0x75, 0x70, 0x65, 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x2e, 0x50, 0x6f, 0x72, 0x74, - 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x05, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x22, 0x9f, - 0x01, 0x0a, 0x0f, 0x45, 0x78, 0x70, 0x6f, 0x73, 0x65, 0x64, 0x50, 0x6f, 0x72, 0x74, 0x49, 0x6e, - 0x66, 0x6f, 0x12, 0x3a, 0x0a, 0x0a, 0x76, 0x69, 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x73, 0x75, 0x70, 0x65, 0x72, 0x76, 0x69, - 0x73, 0x6f, 0x72, 0x2e, 0x50, 0x6f, 0x72, 0x74, 0x56, 0x69, 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69, - 0x74, 0x79, 0x52, 0x0a, 0x76, 0x69, 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x12, 0x10, - 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, - 0x12, 0x3e, 0x0a, 0x0a, 0x6f, 0x6e, 0x5f, 0x65, 0x78, 0x70, 0x6f, 0x73, 0x65, 0x64, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1f, 0x2e, 0x73, 0x75, 0x70, 0x65, 0x72, 0x76, 0x69, 0x73, 0x6f, - 0x72, 0x2e, 0x4f, 0x6e, 0x50, 0x6f, 0x72, 0x74, 0x45, 0x78, 0x70, 0x6f, 0x73, 0x65, 0x64, 0x41, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x09, 0x6f, 0x6e, 0x45, 0x78, 0x70, 0x6f, 0x73, 0x65, 0x64, - 0x22, 0xf1, 0x01, 0x0a, 0x10, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x65, 0x64, 0x50, 0x6f, 0x72, - 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, - 0x70, 0x6f, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x74, 0x61, 0x72, 0x67, - 0x65, 0x74, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x3b, 0x0a, 0x0a, 0x76, 0x69, 0x73, 0x69, 0x62, 0x69, - 0x6c, 0x69, 0x74, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1b, 0x2e, 0x73, 0x75, 0x70, - 0x65, 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x2e, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x56, 0x69, - 0x73, 0x69, 0x62, 0x6c, 0x69, 0x74, 0x79, 0x52, 0x0a, 0x76, 0x69, 0x73, 0x69, 0x62, 0x69, 0x6c, - 0x69, 0x74, 0x79, 0x12, 0x43, 0x0a, 0x07, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x03, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x73, 0x75, 0x70, 0x65, 0x72, 0x76, 0x69, 0x73, 0x6f, - 0x72, 0x2e, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x65, 0x64, 0x50, 0x6f, 0x72, 0x74, 0x49, 0x6e, - 0x66, 0x6f, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, - 0x07, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x73, 0x1a, 0x3a, 0x0a, 0x0c, 0x43, 0x6c, 0x69, 0x65, - 0x6e, 0x74, 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, 0x0d, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x3a, 0x02, 0x38, 0x01, 0x22, 0x99, 0x02, 0x0a, 0x0b, 0x50, 0x6f, 0x72, 0x74, 0x73, 0x53, 0x74, - 0x61, 0x74, 0x75, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x70, 0x6f, - 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x50, - 0x6f, 0x72, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x70, 0x6f, - 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, - 0x50, 0x6f, 0x72, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x12, 0x35, 0x0a, 0x07, - 0x65, 0x78, 0x70, 0x6f, 0x73, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, - 0x73, 0x75, 0x70, 0x65, 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x2e, 0x45, 0x78, 0x70, 0x6f, 0x73, - 0x65, 0x64, 0x50, 0x6f, 0x72, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x07, 0x65, 0x78, 0x70, 0x6f, - 0x73, 0x65, 0x64, 0x12, 0x41, 0x0a, 0x0d, 0x61, 0x75, 0x74, 0x6f, 0x5f, 0x65, 0x78, 0x70, 0x6f, - 0x73, 0x75, 0x72, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1c, 0x2e, 0x73, 0x75, 0x70, - 0x65, 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x2e, 0x50, 0x6f, 0x72, 0x74, 0x41, 0x75, 0x74, 0x6f, - 0x45, 0x78, 0x70, 0x6f, 0x73, 0x75, 0x72, 0x65, 0x52, 0x0c, 0x61, 0x75, 0x74, 0x6f, 0x45, 0x78, - 0x70, 0x6f, 0x73, 0x75, 0x72, 0x65, 0x12, 0x38, 0x0a, 0x08, 0x74, 0x75, 0x6e, 0x6e, 0x65, 0x6c, - 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x73, 0x75, 0x70, 0x65, 0x72, - 0x76, 0x69, 0x73, 0x6f, 0x72, 0x2e, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x65, 0x64, 0x50, 0x6f, - 0x72, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x08, 0x74, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x65, 0x64, - 0x22, 0x2e, 0x0a, 0x12, 0x54, 0x61, 0x73, 0x6b, 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, - 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, - 0x22, 0x43, 0x0a, 0x13, 0x54, 0x61, 0x73, 0x6b, 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2c, 0x0a, 0x05, 0x74, 0x61, 0x73, 0x6b, 0x73, - 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x73, 0x75, 0x70, 0x65, 0x72, 0x76, 0x69, - 0x73, 0x6f, 0x72, 0x2e, 0x54, 0x61, 0x73, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x05, - 0x74, 0x61, 0x73, 0x6b, 0x73, 0x22, 0xa7, 0x01, 0x0a, 0x0a, 0x54, 0x61, 0x73, 0x6b, 0x53, 0x74, - 0x61, 0x74, 0x75, 0x73, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x02, 0x69, 0x64, 0x12, 0x2b, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x73, 0x75, 0x70, 0x65, 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, - 0x2e, 0x54, 0x61, 0x73, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, - 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x6c, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x6c, 0x12, 0x40, 0x0a, - 0x0c, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x73, 0x75, 0x70, 0x65, 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, - 0x2e, 0x54, 0x61, 0x73, 0x6b, 0x50, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x52, 0x0c, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, - 0x5c, 0x0a, 0x10, 0x54, 0x61, 0x73, 0x6b, 0x50, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x6f, 0x70, 0x65, 0x6e, 0x5f, - 0x69, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6f, 0x70, 0x65, 0x6e, 0x49, 0x6e, - 0x12, 0x1b, 0x0a, 0x09, 0x6f, 0x70, 0x65, 0x6e, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x08, 0x6f, 0x70, 0x65, 0x6e, 0x4d, 0x6f, 0x64, 0x65, 0x2a, 0x43, 0x0a, - 0x0d, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x0e, - 0x0a, 0x0a, 0x66, 0x72, 0x6f, 0x6d, 0x5f, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x10, 0x00, 0x12, 0x0f, - 0x0a, 0x0b, 0x66, 0x72, 0x6f, 0x6d, 0x5f, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x10, 0x01, 0x12, - 0x11, 0x0a, 0x0d, 0x66, 0x72, 0x6f, 0x6d, 0x5f, 0x70, 0x72, 0x65, 0x62, 0x75, 0x69, 0x6c, 0x64, - 0x10, 0x02, 0x2a, 0x29, 0x0a, 0x0e, 0x50, 0x6f, 0x72, 0x74, 0x56, 0x69, 0x73, 0x69, 0x62, 0x69, - 0x6c, 0x69, 0x74, 0x79, 0x12, 0x0b, 0x0a, 0x07, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x10, - 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x10, 0x01, 0x2a, 0x65, 0x0a, - 0x13, 0x4f, 0x6e, 0x50, 0x6f, 0x72, 0x74, 0x45, 0x78, 0x70, 0x6f, 0x73, 0x65, 0x64, 0x41, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x0a, 0x0a, 0x06, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x10, 0x00, - 0x12, 0x10, 0x0a, 0x0c, 0x6f, 0x70, 0x65, 0x6e, 0x5f, 0x62, 0x72, 0x6f, 0x77, 0x73, 0x65, 0x72, - 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x6f, 0x70, 0x65, 0x6e, 0x5f, 0x70, 0x72, 0x65, 0x76, 0x69, - 0x65, 0x77, 0x10, 0x02, 0x12, 0x0a, 0x0a, 0x06, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x10, 0x03, - 0x12, 0x12, 0x0a, 0x0e, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x5f, 0x70, 0x72, 0x69, 0x76, 0x61, - 0x74, 0x65, 0x10, 0x04, 0x2a, 0x39, 0x0a, 0x10, 0x50, 0x6f, 0x72, 0x74, 0x41, 0x75, 0x74, 0x6f, - 0x45, 0x78, 0x70, 0x6f, 0x73, 0x75, 0x72, 0x65, 0x12, 0x0a, 0x0a, 0x06, 0x74, 0x72, 0x79, 0x69, - 0x6e, 0x67, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x73, 0x75, 0x63, 0x63, 0x65, 0x65, 0x64, 0x65, - 0x64, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x10, 0x02, 0x2a, - 0x31, 0x0a, 0x09, 0x54, 0x61, 0x73, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x0b, 0x0a, 0x07, - 0x6f, 0x70, 0x65, 0x6e, 0x69, 0x6e, 0x67, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x72, 0x75, 0x6e, - 0x6e, 0x69, 0x6e, 0x67, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x64, - 0x10, 0x02, 0x32, 0xcb, 0x06, 0x0a, 0x0d, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x53, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x12, 0x7c, 0x0a, 0x10, 0x53, 0x75, 0x70, 0x65, 0x72, 0x76, 0x69, 0x73, - 0x6f, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x23, 0x2e, 0x73, 0x75, 0x70, 0x65, 0x72, - 0x76, 0x69, 0x73, 0x6f, 0x72, 0x2e, 0x53, 0x75, 0x70, 0x65, 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, - 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, - 0x73, 0x75, 0x70, 0x65, 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x2e, 0x53, 0x75, 0x70, 0x65, 0x72, - 0x76, 0x69, 0x73, 0x6f, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x1d, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x17, 0x12, 0x15, 0x2f, 0x76, 0x31, - 0x2f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2f, 0x73, 0x75, 0x70, 0x65, 0x72, 0x76, 0x69, 0x73, - 0x6f, 0x72, 0x12, 0x83, 0x01, 0x0a, 0x09, 0x49, 0x44, 0x45, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x12, 0x1c, 0x2e, 0x73, 0x75, 0x70, 0x65, 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x2e, 0x49, 0x44, - 0x45, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, - 0x2e, 0x73, 0x75, 0x70, 0x65, 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x2e, 0x49, 0x44, 0x45, 0x53, - 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x39, 0x82, - 0xd3, 0xe4, 0x93, 0x02, 0x33, 0x12, 0x0e, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x75, - 0x73, 0x2f, 0x69, 0x64, 0x65, 0x5a, 0x21, 0x12, 0x1f, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x2f, 0x69, 0x64, 0x65, 0x2f, 0x77, 0x61, 0x69, 0x74, 0x2f, 0x7b, 0x77, 0x61, - 0x69, 0x74, 0x3d, 0x74, 0x72, 0x75, 0x65, 0x7d, 0x12, 0x97, 0x01, 0x0a, 0x0d, 0x43, 0x6f, 0x6e, - 0x74, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x20, 0x2e, 0x73, 0x75, 0x70, - 0x65, 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x53, - 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x73, - 0x75, 0x70, 0x65, 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, - 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x41, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x3b, 0x12, 0x12, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x5a, 0x25, 0x12, 0x23, 0x2f, - 0x76, 0x31, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, - 0x74, 0x2f, 0x77, 0x61, 0x69, 0x74, 0x2f, 0x7b, 0x77, 0x61, 0x69, 0x74, 0x3d, 0x74, 0x72, 0x75, - 0x65, 0x7d, 0x12, 0x6c, 0x0a, 0x0c, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x53, 0x74, 0x61, 0x74, - 0x75, 0x73, 0x12, 0x1f, 0x2e, 0x73, 0x75, 0x70, 0x65, 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x2e, - 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x73, 0x75, 0x70, 0x65, 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, - 0x2e, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x19, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x13, 0x12, 0x11, 0x2f, - 0x76, 0x31, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2f, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, - 0x12, 0x95, 0x01, 0x0a, 0x0b, 0x50, 0x6f, 0x72, 0x74, 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x12, 0x1e, 0x2e, 0x73, 0x75, 0x70, 0x65, 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x2e, 0x50, 0x6f, - 0x72, 0x74, 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x1f, 0x2e, 0x73, 0x75, 0x70, 0x65, 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x2e, 0x50, 0x6f, - 0x72, 0x74, 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x43, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x3d, 0x12, 0x10, 0x2f, 0x76, 0x31, 0x2f, 0x73, - 0x74, 0x61, 0x74, 0x75, 0x73, 0x2f, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x5a, 0x29, 0x12, 0x27, 0x2f, - 0x76, 0x31, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2f, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2f, - 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x2f, 0x7b, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, - 0x3d, 0x74, 0x72, 0x75, 0x65, 0x7d, 0x30, 0x01, 0x12, 0x95, 0x01, 0x0a, 0x0b, 0x54, 0x61, 0x73, - 0x6b, 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1e, 0x2e, 0x73, 0x75, 0x70, 0x65, 0x72, - 0x76, 0x69, 0x73, 0x6f, 0x72, 0x2e, 0x54, 0x61, 0x73, 0x6b, 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, - 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x73, 0x75, 0x70, 0x65, 0x72, - 0x76, 0x69, 0x73, 0x6f, 0x72, 0x2e, 0x54, 0x61, 0x73, 0x6b, 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, - 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x43, 0x82, 0xd3, 0xe4, 0x93, 0x02, - 0x3d, 0x12, 0x10, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2f, 0x74, 0x61, - 0x73, 0x6b, 0x73, 0x5a, 0x29, 0x12, 0x27, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x75, - 0x73, 0x2f, 0x74, 0x61, 0x73, 0x6b, 0x73, 0x2f, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x2f, - 0x7b, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x3d, 0x74, 0x72, 0x75, 0x65, 0x7d, 0x30, 0x01, - 0x42, 0x2c, 0x5a, 0x2a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, - 0x69, 0x74, 0x70, 0x6f, 0x64, 0x2d, 0x69, 0x6f, 0x2f, 0x67, 0x69, 0x74, 0x70, 0x6f, 0x64, 0x2f, - 0x73, 0x75, 0x70, 0x65, 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x2f, 0x61, 0x70, 0x69, 0x62, 0x06, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x61, 0x69, 0x74, 0x22, 0xa5, 0x01, 0x0a, 0x11, 0x49, 0x44, 0x45, 0x53, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x6f, 0x6b, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x02, 0x6f, 0x6b, 0x12, 0x45, 0x0a, 0x07, 0x64, 0x65, 0x73, + 0x6b, 0x74, 0x6f, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x73, 0x75, 0x70, + 0x65, 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x2e, 0x49, 0x44, 0x45, 0x53, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x44, 0x65, 0x73, 0x6b, 0x74, 0x6f, + 0x70, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x07, 0x64, 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, + 0x1a, 0x39, 0x0a, 0x0d, 0x44, 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x53, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x22, 0x2a, 0x0a, 0x14, 0x43, + 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x77, 0x61, 0x69, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x04, 0x77, 0x61, 0x69, 0x74, 0x22, 0x68, 0x0a, 0x15, 0x43, 0x6f, 0x6e, 0x74, 0x65, + 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x09, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x31, + 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x19, + 0x2e, 0x73, 0x75, 0x70, 0x65, 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x2e, 0x43, 0x6f, 0x6e, 0x74, + 0x65, 0x6e, 0x74, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x22, 0x15, 0x0a, 0x13, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x53, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x41, 0x0a, 0x14, 0x42, 0x61, 0x63, 0x6b, + 0x75, 0x70, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x29, 0x0a, 0x10, 0x63, 0x61, 0x6e, 0x61, 0x72, 0x79, 0x5f, 0x61, 0x76, 0x61, 0x69, 0x6c, + 0x61, 0x62, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x63, 0x61, 0x6e, 0x61, + 0x72, 0x79, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x22, 0x2e, 0x0a, 0x12, 0x50, + 0x6f, 0x72, 0x74, 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x18, 0x0a, 0x07, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x07, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x22, 0x44, 0x0a, 0x13, 0x50, + 0x6f, 0x72, 0x74, 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x2d, 0x0a, 0x05, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x17, 0x2e, 0x73, 0x75, 0x70, 0x65, 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x2e, 0x50, + 0x6f, 0x72, 0x74, 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x05, 0x70, 0x6f, 0x72, 0x74, + 0x73, 0x22, 0x9f, 0x01, 0x0a, 0x0f, 0x45, 0x78, 0x70, 0x6f, 0x73, 0x65, 0x64, 0x50, 0x6f, 0x72, + 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x3a, 0x0a, 0x0a, 0x76, 0x69, 0x73, 0x69, 0x62, 0x69, 0x6c, + 0x69, 0x74, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x73, 0x75, 0x70, 0x65, + 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x2e, 0x50, 0x6f, 0x72, 0x74, 0x56, 0x69, 0x73, 0x69, 0x62, + 0x69, 0x6c, 0x69, 0x74, 0x79, 0x52, 0x0a, 0x76, 0x69, 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, + 0x79, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, + 0x75, 0x72, 0x6c, 0x12, 0x3e, 0x0a, 0x0a, 0x6f, 0x6e, 0x5f, 0x65, 0x78, 0x70, 0x6f, 0x73, 0x65, + 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1f, 0x2e, 0x73, 0x75, 0x70, 0x65, 0x72, 0x76, + 0x69, 0x73, 0x6f, 0x72, 0x2e, 0x4f, 0x6e, 0x50, 0x6f, 0x72, 0x74, 0x45, 0x78, 0x70, 0x6f, 0x73, + 0x65, 0x64, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x09, 0x6f, 0x6e, 0x45, 0x78, 0x70, 0x6f, + 0x73, 0x65, 0x64, 0x22, 0xf1, 0x01, 0x0a, 0x10, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x65, 0x64, + 0x50, 0x6f, 0x72, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x61, 0x72, 0x67, + 0x65, 0x74, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x74, + 0x61, 0x72, 0x67, 0x65, 0x74, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x3b, 0x0a, 0x0a, 0x76, 0x69, 0x73, + 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1b, 0x2e, + 0x73, 0x75, 0x70, 0x65, 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x2e, 0x54, 0x75, 0x6e, 0x6e, 0x65, + 0x6c, 0x56, 0x69, 0x73, 0x69, 0x62, 0x6c, 0x69, 0x74, 0x79, 0x52, 0x0a, 0x76, 0x69, 0x73, 0x69, + 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x12, 0x43, 0x0a, 0x07, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, + 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x73, 0x75, 0x70, 0x65, 0x72, 0x76, + 0x69, 0x73, 0x6f, 0x72, 0x2e, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x65, 0x64, 0x50, 0x6f, 0x72, + 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x73, 0x45, 0x6e, 0x74, + 0x72, 0x79, 0x52, 0x07, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x73, 0x1a, 0x3a, 0x0a, 0x0c, 0x43, + 0x6c, 0x69, 0x65, 0x6e, 0x74, 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, 0x0d, 0x52, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x99, 0x02, 0x0a, 0x0b, 0x50, 0x6f, 0x72, 0x74, + 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x6c, 0x6f, 0x63, + 0x61, 0x6c, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, + 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x67, 0x6c, 0x6f, + 0x62, 0x61, 0x6c, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x65, 0x72, 0x76, 0x65, + 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x12, + 0x35, 0x0a, 0x07, 0x65, 0x78, 0x70, 0x6f, 0x73, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1b, 0x2e, 0x73, 0x75, 0x70, 0x65, 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x2e, 0x45, 0x78, + 0x70, 0x6f, 0x73, 0x65, 0x64, 0x50, 0x6f, 0x72, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x07, 0x65, + 0x78, 0x70, 0x6f, 0x73, 0x65, 0x64, 0x12, 0x41, 0x0a, 0x0d, 0x61, 0x75, 0x74, 0x6f, 0x5f, 0x65, + 0x78, 0x70, 0x6f, 0x73, 0x75, 0x72, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1c, 0x2e, + 0x73, 0x75, 0x70, 0x65, 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x2e, 0x50, 0x6f, 0x72, 0x74, 0x41, + 0x75, 0x74, 0x6f, 0x45, 0x78, 0x70, 0x6f, 0x73, 0x75, 0x72, 0x65, 0x52, 0x0c, 0x61, 0x75, 0x74, + 0x6f, 0x45, 0x78, 0x70, 0x6f, 0x73, 0x75, 0x72, 0x65, 0x12, 0x38, 0x0a, 0x08, 0x74, 0x75, 0x6e, + 0x6e, 0x65, 0x6c, 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x73, 0x75, + 0x70, 0x65, 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x2e, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x65, + 0x64, 0x50, 0x6f, 0x72, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x08, 0x74, 0x75, 0x6e, 0x6e, 0x65, + 0x6c, 0x65, 0x64, 0x22, 0x2e, 0x0a, 0x12, 0x54, 0x61, 0x73, 0x6b, 0x73, 0x53, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x6f, 0x62, 0x73, + 0x65, 0x72, 0x76, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x6f, 0x62, 0x73, 0x65, + 0x72, 0x76, 0x65, 0x22, 0x43, 0x0a, 0x13, 0x54, 0x61, 0x73, 0x6b, 0x73, 0x53, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2c, 0x0a, 0x05, 0x74, 0x61, + 0x73, 0x6b, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x73, 0x75, 0x70, 0x65, + 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x2e, 0x54, 0x61, 0x73, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x52, 0x05, 0x74, 0x61, 0x73, 0x6b, 0x73, 0x22, 0xa7, 0x01, 0x0a, 0x0a, 0x54, 0x61, 0x73, + 0x6b, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x2b, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x73, 0x75, 0x70, 0x65, 0x72, 0x76, 0x69, + 0x73, 0x6f, 0x72, 0x2e, 0x54, 0x61, 0x73, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x73, + 0x74, 0x61, 0x74, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x6c, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x6c, + 0x12, 0x40, 0x0a, 0x0c, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x73, 0x75, 0x70, 0x65, 0x72, 0x76, 0x69, + 0x73, 0x6f, 0x72, 0x2e, 0x54, 0x61, 0x73, 0x6b, 0x50, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0c, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x22, 0x5c, 0x0a, 0x10, 0x54, 0x61, 0x73, 0x6b, 0x50, 0x72, 0x65, 0x73, 0x65, 0x6e, + 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x6f, 0x70, + 0x65, 0x6e, 0x5f, 0x69, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6f, 0x70, 0x65, + 0x6e, 0x49, 0x6e, 0x12, 0x1b, 0x0a, 0x09, 0x6f, 0x70, 0x65, 0x6e, 0x5f, 0x6d, 0x6f, 0x64, 0x65, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6f, 0x70, 0x65, 0x6e, 0x4d, 0x6f, 0x64, 0x65, + 0x2a, 0x43, 0x0a, 0x0d, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x53, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x12, 0x0e, 0x0a, 0x0a, 0x66, 0x72, 0x6f, 0x6d, 0x5f, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x10, + 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x66, 0x72, 0x6f, 0x6d, 0x5f, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, + 0x10, 0x01, 0x12, 0x11, 0x0a, 0x0d, 0x66, 0x72, 0x6f, 0x6d, 0x5f, 0x70, 0x72, 0x65, 0x62, 0x75, + 0x69, 0x6c, 0x64, 0x10, 0x02, 0x2a, 0x29, 0x0a, 0x0e, 0x50, 0x6f, 0x72, 0x74, 0x56, 0x69, 0x73, + 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x12, 0x0b, 0x0a, 0x07, 0x70, 0x72, 0x69, 0x76, 0x61, + 0x74, 0x65, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x10, 0x01, + 0x2a, 0x65, 0x0a, 0x13, 0x4f, 0x6e, 0x50, 0x6f, 0x72, 0x74, 0x45, 0x78, 0x70, 0x6f, 0x73, 0x65, + 0x64, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x0a, 0x0a, 0x06, 0x69, 0x67, 0x6e, 0x6f, 0x72, + 0x65, 0x10, 0x00, 0x12, 0x10, 0x0a, 0x0c, 0x6f, 0x70, 0x65, 0x6e, 0x5f, 0x62, 0x72, 0x6f, 0x77, + 0x73, 0x65, 0x72, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x6f, 0x70, 0x65, 0x6e, 0x5f, 0x70, 0x72, + 0x65, 0x76, 0x69, 0x65, 0x77, 0x10, 0x02, 0x12, 0x0a, 0x0a, 0x06, 0x6e, 0x6f, 0x74, 0x69, 0x66, + 0x79, 0x10, 0x03, 0x12, 0x12, 0x0a, 0x0e, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x5f, 0x70, 0x72, + 0x69, 0x76, 0x61, 0x74, 0x65, 0x10, 0x04, 0x2a, 0x39, 0x0a, 0x10, 0x50, 0x6f, 0x72, 0x74, 0x41, + 0x75, 0x74, 0x6f, 0x45, 0x78, 0x70, 0x6f, 0x73, 0x75, 0x72, 0x65, 0x12, 0x0a, 0x0a, 0x06, 0x74, + 0x72, 0x79, 0x69, 0x6e, 0x67, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x73, 0x75, 0x63, 0x63, 0x65, + 0x65, 0x64, 0x65, 0x64, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, + 0x10, 0x02, 0x2a, 0x31, 0x0a, 0x09, 0x54, 0x61, 0x73, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, + 0x0b, 0x0a, 0x07, 0x6f, 0x70, 0x65, 0x6e, 0x69, 0x6e, 0x67, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, + 0x72, 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x63, 0x6c, 0x6f, + 0x73, 0x65, 0x64, 0x10, 0x02, 0x32, 0xcb, 0x06, 0x0a, 0x0d, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x7c, 0x0a, 0x10, 0x53, 0x75, 0x70, 0x65, 0x72, + 0x76, 0x69, 0x73, 0x6f, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x23, 0x2e, 0x73, 0x75, + 0x70, 0x65, 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x2e, 0x53, 0x75, 0x70, 0x65, 0x72, 0x76, 0x69, + 0x73, 0x6f, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x24, 0x2e, 0x73, 0x75, 0x70, 0x65, 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x2e, 0x53, 0x75, + 0x70, 0x65, 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1d, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x17, 0x12, 0x15, + 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2f, 0x73, 0x75, 0x70, 0x65, 0x72, + 0x76, 0x69, 0x73, 0x6f, 0x72, 0x12, 0x83, 0x01, 0x0a, 0x09, 0x49, 0x44, 0x45, 0x53, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x12, 0x1c, 0x2e, 0x73, 0x75, 0x70, 0x65, 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, + 0x2e, 0x49, 0x44, 0x45, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x1d, 0x2e, 0x73, 0x75, 0x70, 0x65, 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x2e, 0x49, + 0x44, 0x45, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x39, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x33, 0x12, 0x0e, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x2f, 0x69, 0x64, 0x65, 0x5a, 0x21, 0x12, 0x1f, 0x2f, 0x76, 0x31, 0x2f, + 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2f, 0x69, 0x64, 0x65, 0x2f, 0x77, 0x61, 0x69, 0x74, 0x2f, + 0x7b, 0x77, 0x61, 0x69, 0x74, 0x3d, 0x74, 0x72, 0x75, 0x65, 0x7d, 0x12, 0x97, 0x01, 0x0a, 0x0d, + 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x20, 0x2e, + 0x73, 0x75, 0x70, 0x65, 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x65, + 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x21, 0x2e, 0x73, 0x75, 0x70, 0x65, 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x2e, 0x43, 0x6f, 0x6e, + 0x74, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x41, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x3b, 0x12, 0x12, 0x2f, 0x76, 0x31, 0x2f, + 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x5a, 0x25, + 0x12, 0x23, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2f, 0x63, 0x6f, 0x6e, + 0x74, 0x65, 0x6e, 0x74, 0x2f, 0x77, 0x61, 0x69, 0x74, 0x2f, 0x7b, 0x77, 0x61, 0x69, 0x74, 0x3d, + 0x74, 0x72, 0x75, 0x65, 0x7d, 0x12, 0x6c, 0x0a, 0x0c, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x53, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1f, 0x2e, 0x73, 0x75, 0x70, 0x65, 0x72, 0x76, 0x69, 0x73, + 0x6f, 0x72, 0x2e, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x73, 0x75, 0x70, 0x65, 0x72, 0x76, 0x69, + 0x73, 0x6f, 0x72, 0x2e, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x19, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x13, + 0x12, 0x11, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2f, 0x62, 0x61, 0x63, + 0x6b, 0x75, 0x70, 0x12, 0x95, 0x01, 0x0a, 0x0b, 0x50, 0x6f, 0x72, 0x74, 0x73, 0x53, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x12, 0x1e, 0x2e, 0x73, 0x75, 0x70, 0x65, 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, + 0x2e, 0x50, 0x6f, 0x72, 0x74, 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x73, 0x75, 0x70, 0x65, 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, + 0x2e, 0x50, 0x6f, 0x72, 0x74, 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x43, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x3d, 0x12, 0x10, 0x2f, 0x76, + 0x31, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2f, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x5a, 0x29, + 0x12, 0x27, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2f, 0x70, 0x6f, 0x72, + 0x74, 0x73, 0x2f, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x2f, 0x7b, 0x6f, 0x62, 0x73, 0x65, + 0x72, 0x76, 0x65, 0x3d, 0x74, 0x72, 0x75, 0x65, 0x7d, 0x30, 0x01, 0x12, 0x95, 0x01, 0x0a, 0x0b, + 0x54, 0x61, 0x73, 0x6b, 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1e, 0x2e, 0x73, 0x75, + 0x70, 0x65, 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x2e, 0x54, 0x61, 0x73, 0x6b, 0x73, 0x53, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x73, 0x75, + 0x70, 0x65, 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x2e, 0x54, 0x61, 0x73, 0x6b, 0x73, 0x53, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x43, 0x82, 0xd3, + 0xe4, 0x93, 0x02, 0x3d, 0x12, 0x10, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x2f, 0x74, 0x61, 0x73, 0x6b, 0x73, 0x5a, 0x29, 0x12, 0x27, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x2f, 0x74, 0x61, 0x73, 0x6b, 0x73, 0x2f, 0x6f, 0x62, 0x73, 0x65, 0x72, + 0x76, 0x65, 0x2f, 0x7b, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x3d, 0x74, 0x72, 0x75, 0x65, + 0x7d, 0x30, 0x01, 0x42, 0x46, 0x0a, 0x18, 0x69, 0x6f, 0x2e, 0x67, 0x69, 0x74, 0x70, 0x6f, 0x64, + 0x2e, 0x73, 0x75, 0x70, 0x65, 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x5a, + 0x2a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x69, 0x74, 0x70, + 0x6f, 0x64, 0x2d, 0x69, 0x6f, 0x2f, 0x67, 0x69, 0x74, 0x70, 0x6f, 0x64, 0x2f, 0x73, 0x75, 0x70, + 0x65, 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x2f, 0x61, 0x70, 0x69, 0x62, 0x06, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x33, } var ( @@ -1400,63 +1473,65 @@ func file_status_proto_rawDescGZIP() []byte { } var file_status_proto_enumTypes = make([]protoimpl.EnumInfo, 5) -var file_status_proto_msgTypes = make([]protoimpl.MessageInfo, 18) +var file_status_proto_msgTypes = make([]protoimpl.MessageInfo, 19) var file_status_proto_goTypes = []interface{}{ - (ContentSource)(0), // 0: supervisor.ContentSource - (PortVisibility)(0), // 1: supervisor.PortVisibility - (OnPortExposedAction)(0), // 2: supervisor.OnPortExposedAction - (PortAutoExposure)(0), // 3: supervisor.PortAutoExposure - (TaskState)(0), // 4: supervisor.TaskState - (*SupervisorStatusRequest)(nil), // 5: supervisor.SupervisorStatusRequest - (*SupervisorStatusResponse)(nil), // 6: supervisor.SupervisorStatusResponse - (*IDEStatusRequest)(nil), // 7: supervisor.IDEStatusRequest - (*IDEStatusResponse)(nil), // 8: supervisor.IDEStatusResponse - (*ContentStatusRequest)(nil), // 9: supervisor.ContentStatusRequest - (*ContentStatusResponse)(nil), // 10: supervisor.ContentStatusResponse - (*BackupStatusRequest)(nil), // 11: supervisor.BackupStatusRequest - (*BackupStatusResponse)(nil), // 12: supervisor.BackupStatusResponse - (*PortsStatusRequest)(nil), // 13: supervisor.PortsStatusRequest - (*PortsStatusResponse)(nil), // 14: supervisor.PortsStatusResponse - (*ExposedPortInfo)(nil), // 15: supervisor.ExposedPortInfo - (*TunneledPortInfo)(nil), // 16: supervisor.TunneledPortInfo - (*PortsStatus)(nil), // 17: supervisor.PortsStatus - (*TasksStatusRequest)(nil), // 18: supervisor.TasksStatusRequest - (*TasksStatusResponse)(nil), // 19: supervisor.TasksStatusResponse - (*TaskStatus)(nil), // 20: supervisor.TaskStatus - (*TaskPresentation)(nil), // 21: supervisor.TaskPresentation - nil, // 22: supervisor.TunneledPortInfo.ClientsEntry - (TunnelVisiblity)(0), // 23: supervisor.TunnelVisiblity + (ContentSource)(0), // 0: supervisor.ContentSource + (PortVisibility)(0), // 1: supervisor.PortVisibility + (OnPortExposedAction)(0), // 2: supervisor.OnPortExposedAction + (PortAutoExposure)(0), // 3: supervisor.PortAutoExposure + (TaskState)(0), // 4: supervisor.TaskState + (*SupervisorStatusRequest)(nil), // 5: supervisor.SupervisorStatusRequest + (*SupervisorStatusResponse)(nil), // 6: supervisor.SupervisorStatusResponse + (*IDEStatusRequest)(nil), // 7: supervisor.IDEStatusRequest + (*IDEStatusResponse)(nil), // 8: supervisor.IDEStatusResponse + (*ContentStatusRequest)(nil), // 9: supervisor.ContentStatusRequest + (*ContentStatusResponse)(nil), // 10: supervisor.ContentStatusResponse + (*BackupStatusRequest)(nil), // 11: supervisor.BackupStatusRequest + (*BackupStatusResponse)(nil), // 12: supervisor.BackupStatusResponse + (*PortsStatusRequest)(nil), // 13: supervisor.PortsStatusRequest + (*PortsStatusResponse)(nil), // 14: supervisor.PortsStatusResponse + (*ExposedPortInfo)(nil), // 15: supervisor.ExposedPortInfo + (*TunneledPortInfo)(nil), // 16: supervisor.TunneledPortInfo + (*PortsStatus)(nil), // 17: supervisor.PortsStatus + (*TasksStatusRequest)(nil), // 18: supervisor.TasksStatusRequest + (*TasksStatusResponse)(nil), // 19: supervisor.TasksStatusResponse + (*TaskStatus)(nil), // 20: supervisor.TaskStatus + (*TaskPresentation)(nil), // 21: supervisor.TaskPresentation + (*IDEStatusResponse_DesktopStatus)(nil), // 22: supervisor.IDEStatusResponse.DesktopStatus + nil, // 23: supervisor.TunneledPortInfo.ClientsEntry + (TunnelVisiblity)(0), // 24: supervisor.TunnelVisiblity } var file_status_proto_depIdxs = []int32{ - 0, // 0: supervisor.ContentStatusResponse.source:type_name -> supervisor.ContentSource - 17, // 1: supervisor.PortsStatusResponse.ports:type_name -> supervisor.PortsStatus - 1, // 2: supervisor.ExposedPortInfo.visibility:type_name -> supervisor.PortVisibility - 2, // 3: supervisor.ExposedPortInfo.on_exposed:type_name -> supervisor.OnPortExposedAction - 23, // 4: supervisor.TunneledPortInfo.visibility:type_name -> supervisor.TunnelVisiblity - 22, // 5: supervisor.TunneledPortInfo.clients:type_name -> supervisor.TunneledPortInfo.ClientsEntry - 15, // 6: supervisor.PortsStatus.exposed:type_name -> supervisor.ExposedPortInfo - 3, // 7: supervisor.PortsStatus.auto_exposure:type_name -> supervisor.PortAutoExposure - 16, // 8: supervisor.PortsStatus.tunneled:type_name -> supervisor.TunneledPortInfo - 20, // 9: supervisor.TasksStatusResponse.tasks:type_name -> supervisor.TaskStatus - 4, // 10: supervisor.TaskStatus.state:type_name -> supervisor.TaskState - 21, // 11: supervisor.TaskStatus.presentation:type_name -> supervisor.TaskPresentation - 5, // 12: supervisor.StatusService.SupervisorStatus:input_type -> supervisor.SupervisorStatusRequest - 7, // 13: supervisor.StatusService.IDEStatus:input_type -> supervisor.IDEStatusRequest - 9, // 14: supervisor.StatusService.ContentStatus:input_type -> supervisor.ContentStatusRequest - 11, // 15: supervisor.StatusService.BackupStatus:input_type -> supervisor.BackupStatusRequest - 13, // 16: supervisor.StatusService.PortsStatus:input_type -> supervisor.PortsStatusRequest - 18, // 17: supervisor.StatusService.TasksStatus:input_type -> supervisor.TasksStatusRequest - 6, // 18: supervisor.StatusService.SupervisorStatus:output_type -> supervisor.SupervisorStatusResponse - 8, // 19: supervisor.StatusService.IDEStatus:output_type -> supervisor.IDEStatusResponse - 10, // 20: supervisor.StatusService.ContentStatus:output_type -> supervisor.ContentStatusResponse - 12, // 21: supervisor.StatusService.BackupStatus:output_type -> supervisor.BackupStatusResponse - 14, // 22: supervisor.StatusService.PortsStatus:output_type -> supervisor.PortsStatusResponse - 19, // 23: supervisor.StatusService.TasksStatus:output_type -> supervisor.TasksStatusResponse - 18, // [18:24] is the sub-list for method output_type - 12, // [12:18] is the sub-list for method input_type - 12, // [12:12] is the sub-list for extension type_name - 12, // [12:12] is the sub-list for extension extendee - 0, // [0:12] is the sub-list for field type_name + 22, // 0: supervisor.IDEStatusResponse.desktop:type_name -> supervisor.IDEStatusResponse.DesktopStatus + 0, // 1: supervisor.ContentStatusResponse.source:type_name -> supervisor.ContentSource + 17, // 2: supervisor.PortsStatusResponse.ports:type_name -> supervisor.PortsStatus + 1, // 3: supervisor.ExposedPortInfo.visibility:type_name -> supervisor.PortVisibility + 2, // 4: supervisor.ExposedPortInfo.on_exposed:type_name -> supervisor.OnPortExposedAction + 24, // 5: supervisor.TunneledPortInfo.visibility:type_name -> supervisor.TunnelVisiblity + 23, // 6: supervisor.TunneledPortInfo.clients:type_name -> supervisor.TunneledPortInfo.ClientsEntry + 15, // 7: supervisor.PortsStatus.exposed:type_name -> supervisor.ExposedPortInfo + 3, // 8: supervisor.PortsStatus.auto_exposure:type_name -> supervisor.PortAutoExposure + 16, // 9: supervisor.PortsStatus.tunneled:type_name -> supervisor.TunneledPortInfo + 20, // 10: supervisor.TasksStatusResponse.tasks:type_name -> supervisor.TaskStatus + 4, // 11: supervisor.TaskStatus.state:type_name -> supervisor.TaskState + 21, // 12: supervisor.TaskStatus.presentation:type_name -> supervisor.TaskPresentation + 5, // 13: supervisor.StatusService.SupervisorStatus:input_type -> supervisor.SupervisorStatusRequest + 7, // 14: supervisor.StatusService.IDEStatus:input_type -> supervisor.IDEStatusRequest + 9, // 15: supervisor.StatusService.ContentStatus:input_type -> supervisor.ContentStatusRequest + 11, // 16: supervisor.StatusService.BackupStatus:input_type -> supervisor.BackupStatusRequest + 13, // 17: supervisor.StatusService.PortsStatus:input_type -> supervisor.PortsStatusRequest + 18, // 18: supervisor.StatusService.TasksStatus:input_type -> supervisor.TasksStatusRequest + 6, // 19: supervisor.StatusService.SupervisorStatus:output_type -> supervisor.SupervisorStatusResponse + 8, // 20: supervisor.StatusService.IDEStatus:output_type -> supervisor.IDEStatusResponse + 10, // 21: supervisor.StatusService.ContentStatus:output_type -> supervisor.ContentStatusResponse + 12, // 22: supervisor.StatusService.BackupStatus:output_type -> supervisor.BackupStatusResponse + 14, // 23: supervisor.StatusService.PortsStatus:output_type -> supervisor.PortsStatusResponse + 19, // 24: supervisor.StatusService.TasksStatus:output_type -> supervisor.TasksStatusResponse + 19, // [19:25] is the sub-list for method output_type + 13, // [13:19] is the sub-list for method input_type + 13, // [13:13] is the sub-list for extension type_name + 13, // [13:13] is the sub-list for extension extendee + 0, // [0:13] is the sub-list for field type_name } func init() { file_status_proto_init() } @@ -1670,6 +1745,18 @@ func file_status_proto_init() { return nil } } + file_status_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*IDEStatusResponse_DesktopStatus); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } type x struct{} out := protoimpl.TypeBuilder{ @@ -1677,7 +1764,7 @@ func file_status_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_status_proto_rawDesc, NumEnums: 5, - NumMessages: 18, + NumMessages: 19, NumExtensions: 0, NumServices: 1, }, diff --git a/components/supervisor-api/java/.project b/components/supervisor-api/java/.project index c8065e0eacef38..1f4ae4332fce96 100644 --- a/components/supervisor-api/java/.project +++ b/components/supervisor-api/java/.project @@ -22,7 +22,7 @@ - 1631534388556 + 0 30 diff --git a/components/supervisor-api/java/src/main/java/io/gitpod/supervisor/api/Status.java b/components/supervisor-api/java/src/main/java/io/gitpod/supervisor/api/Status.java index 88e076759ab311..6f7df1fdd041a6 100644 --- a/components/supervisor-api/java/src/main/java/io/gitpod/supervisor/api/Status.java +++ b/components/supervisor-api/java/src/main/java/io/gitpod/supervisor/api/Status.java @@ -2042,6 +2042,21 @@ public interface IDEStatusResponseOrBuilder extends * @return The ok. */ boolean getOk(); + + /** + * .supervisor.IDEStatusResponse.DesktopStatus desktop = 2; + * @return Whether the desktop field is set. + */ + boolean hasDesktop(); + /** + * .supervisor.IDEStatusResponse.DesktopStatus desktop = 2; + * @return The desktop. + */ + io.gitpod.supervisor.api.Status.IDEStatusResponse.DesktopStatus getDesktop(); + /** + * .supervisor.IDEStatusResponse.DesktopStatus desktop = 2; + */ + io.gitpod.supervisor.api.Status.IDEStatusResponse.DesktopStatusOrBuilder getDesktopOrBuilder(); } /** * Protobuf type {@code supervisor.IDEStatusResponse} @@ -2093,6 +2108,19 @@ private IDEStatusResponse( ok_ = input.readBool(); break; } + case 18: { + io.gitpod.supervisor.api.Status.IDEStatusResponse.DesktopStatus.Builder subBuilder = null; + if (desktop_ != null) { + subBuilder = desktop_.toBuilder(); + } + desktop_ = input.readMessage(io.gitpod.supervisor.api.Status.IDEStatusResponse.DesktopStatus.parser(), extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(desktop_); + desktop_ = subBuilder.buildPartial(); + } + + break; + } default: { if (!parseUnknownField( input, unknownFields, extensionRegistry, tag)) { @@ -2125,6 +2153,724 @@ private IDEStatusResponse( io.gitpod.supervisor.api.Status.IDEStatusResponse.class, io.gitpod.supervisor.api.Status.IDEStatusResponse.Builder.class); } + public interface DesktopStatusOrBuilder extends + // @@protoc_insertion_point(interface_extends:supervisor.IDEStatusResponse.DesktopStatus) + com.google.protobuf.MessageOrBuilder { + + /** + * string link = 1; + * @return The link. + */ + java.lang.String getLink(); + /** + * string link = 1; + * @return The bytes for link. + */ + com.google.protobuf.ByteString + getLinkBytes(); + + /** + * string label = 2; + * @return The label. + */ + java.lang.String getLabel(); + /** + * string label = 2; + * @return The bytes for label. + */ + com.google.protobuf.ByteString + getLabelBytes(); + } + /** + * Protobuf type {@code supervisor.IDEStatusResponse.DesktopStatus} + */ + public static final class DesktopStatus extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:supervisor.IDEStatusResponse.DesktopStatus) + DesktopStatusOrBuilder { + private static final long serialVersionUID = 0L; + // Use DesktopStatus.newBuilder() to construct. + private DesktopStatus(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private DesktopStatus() { + link_ = ""; + label_ = ""; + } + + @java.lang.Override + @SuppressWarnings({"unused"}) + protected java.lang.Object newInstance( + UnusedPrivateParameter unused) { + return new DesktopStatus(); + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private DesktopStatus( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 10: { + java.lang.String s = input.readStringRequireUtf8(); + + link_ = s; + break; + } + case 18: { + java.lang.String s = input.readStringRequireUtf8(); + + label_ = s; + break; + } + default: { + if (!parseUnknownField( + input, unknownFields, extensionRegistry, tag)) { + done = true; + } + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return io.gitpod.supervisor.api.Status.internal_static_supervisor_IDEStatusResponse_DesktopStatus_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return io.gitpod.supervisor.api.Status.internal_static_supervisor_IDEStatusResponse_DesktopStatus_fieldAccessorTable + .ensureFieldAccessorsInitialized( + io.gitpod.supervisor.api.Status.IDEStatusResponse.DesktopStatus.class, io.gitpod.supervisor.api.Status.IDEStatusResponse.DesktopStatus.Builder.class); + } + + public static final int LINK_FIELD_NUMBER = 1; + private volatile java.lang.Object link_; + /** + * string link = 1; + * @return The link. + */ + @java.lang.Override + public java.lang.String getLink() { + java.lang.Object ref = link_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + link_ = s; + return s; + } + } + /** + * string link = 1; + * @return The bytes for link. + */ + @java.lang.Override + public com.google.protobuf.ByteString + getLinkBytes() { + java.lang.Object ref = link_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + link_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int LABEL_FIELD_NUMBER = 2; + private volatile java.lang.Object label_; + /** + * string label = 2; + * @return The label. + */ + @java.lang.Override + public java.lang.String getLabel() { + java.lang.Object ref = label_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + label_ = s; + return s; + } + } + /** + * string label = 2; + * @return The bytes for label. + */ + @java.lang.Override + public com.google.protobuf.ByteString + getLabelBytes() { + java.lang.Object ref = label_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + label_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (!getLinkBytes().isEmpty()) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 1, link_); + } + if (!getLabelBytes().isEmpty()) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 2, label_); + } + unknownFields.writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (!getLinkBytes().isEmpty()) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, link_); + } + if (!getLabelBytes().isEmpty()) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, label_); + } + size += unknownFields.getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof io.gitpod.supervisor.api.Status.IDEStatusResponse.DesktopStatus)) { + return super.equals(obj); + } + io.gitpod.supervisor.api.Status.IDEStatusResponse.DesktopStatus other = (io.gitpod.supervisor.api.Status.IDEStatusResponse.DesktopStatus) obj; + + if (!getLink() + .equals(other.getLink())) return false; + if (!getLabel() + .equals(other.getLabel())) return false; + if (!unknownFields.equals(other.unknownFields)) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + hash = (37 * hash) + LINK_FIELD_NUMBER; + hash = (53 * hash) + getLink().hashCode(); + hash = (37 * hash) + LABEL_FIELD_NUMBER; + hash = (53 * hash) + getLabel().hashCode(); + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static io.gitpod.supervisor.api.Status.IDEStatusResponse.DesktopStatus parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static io.gitpod.supervisor.api.Status.IDEStatusResponse.DesktopStatus parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static io.gitpod.supervisor.api.Status.IDEStatusResponse.DesktopStatus parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static io.gitpod.supervisor.api.Status.IDEStatusResponse.DesktopStatus parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static io.gitpod.supervisor.api.Status.IDEStatusResponse.DesktopStatus parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static io.gitpod.supervisor.api.Status.IDEStatusResponse.DesktopStatus parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static io.gitpod.supervisor.api.Status.IDEStatusResponse.DesktopStatus parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static io.gitpod.supervisor.api.Status.IDEStatusResponse.DesktopStatus parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static io.gitpod.supervisor.api.Status.IDEStatusResponse.DesktopStatus parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static io.gitpod.supervisor.api.Status.IDEStatusResponse.DesktopStatus parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static io.gitpod.supervisor.api.Status.IDEStatusResponse.DesktopStatus parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static io.gitpod.supervisor.api.Status.IDEStatusResponse.DesktopStatus parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(io.gitpod.supervisor.api.Status.IDEStatusResponse.DesktopStatus prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code supervisor.IDEStatusResponse.DesktopStatus} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:supervisor.IDEStatusResponse.DesktopStatus) + io.gitpod.supervisor.api.Status.IDEStatusResponse.DesktopStatusOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return io.gitpod.supervisor.api.Status.internal_static_supervisor_IDEStatusResponse_DesktopStatus_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return io.gitpod.supervisor.api.Status.internal_static_supervisor_IDEStatusResponse_DesktopStatus_fieldAccessorTable + .ensureFieldAccessorsInitialized( + io.gitpod.supervisor.api.Status.IDEStatusResponse.DesktopStatus.class, io.gitpod.supervisor.api.Status.IDEStatusResponse.DesktopStatus.Builder.class); + } + + // Construct using io.gitpod.supervisor.api.Status.IDEStatusResponse.DesktopStatus.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + } + } + @java.lang.Override + public Builder clear() { + super.clear(); + link_ = ""; + + label_ = ""; + + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return io.gitpod.supervisor.api.Status.internal_static_supervisor_IDEStatusResponse_DesktopStatus_descriptor; + } + + @java.lang.Override + public io.gitpod.supervisor.api.Status.IDEStatusResponse.DesktopStatus getDefaultInstanceForType() { + return io.gitpod.supervisor.api.Status.IDEStatusResponse.DesktopStatus.getDefaultInstance(); + } + + @java.lang.Override + public io.gitpod.supervisor.api.Status.IDEStatusResponse.DesktopStatus build() { + io.gitpod.supervisor.api.Status.IDEStatusResponse.DesktopStatus result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public io.gitpod.supervisor.api.Status.IDEStatusResponse.DesktopStatus buildPartial() { + io.gitpod.supervisor.api.Status.IDEStatusResponse.DesktopStatus result = new io.gitpod.supervisor.api.Status.IDEStatusResponse.DesktopStatus(this); + result.link_ = link_; + result.label_ = label_; + onBuilt(); + return result; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof io.gitpod.supervisor.api.Status.IDEStatusResponse.DesktopStatus) { + return mergeFrom((io.gitpod.supervisor.api.Status.IDEStatusResponse.DesktopStatus)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(io.gitpod.supervisor.api.Status.IDEStatusResponse.DesktopStatus other) { + if (other == io.gitpod.supervisor.api.Status.IDEStatusResponse.DesktopStatus.getDefaultInstance()) return this; + if (!other.getLink().isEmpty()) { + link_ = other.link_; + onChanged(); + } + if (!other.getLabel().isEmpty()) { + label_ = other.label_; + onChanged(); + } + this.mergeUnknownFields(other.unknownFields); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + io.gitpod.supervisor.api.Status.IDEStatusResponse.DesktopStatus parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (io.gitpod.supervisor.api.Status.IDEStatusResponse.DesktopStatus) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + + private java.lang.Object link_ = ""; + /** + * string link = 1; + * @return The link. + */ + public java.lang.String getLink() { + java.lang.Object ref = link_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + link_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * string link = 1; + * @return The bytes for link. + */ + public com.google.protobuf.ByteString + getLinkBytes() { + java.lang.Object ref = link_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + link_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * string link = 1; + * @param value The link to set. + * @return This builder for chaining. + */ + public Builder setLink( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + + link_ = value; + onChanged(); + return this; + } + /** + * string link = 1; + * @return This builder for chaining. + */ + public Builder clearLink() { + + link_ = getDefaultInstance().getLink(); + onChanged(); + return this; + } + /** + * string link = 1; + * @param value The bytes for link to set. + * @return This builder for chaining. + */ + public Builder setLinkBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + link_ = value; + onChanged(); + return this; + } + + private java.lang.Object label_ = ""; + /** + * string label = 2; + * @return The label. + */ + public java.lang.String getLabel() { + java.lang.Object ref = label_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + label_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * string label = 2; + * @return The bytes for label. + */ + public com.google.protobuf.ByteString + getLabelBytes() { + java.lang.Object ref = label_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + label_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * string label = 2; + * @param value The label to set. + * @return This builder for chaining. + */ + public Builder setLabel( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + + label_ = value; + onChanged(); + return this; + } + /** + * string label = 2; + * @return This builder for chaining. + */ + public Builder clearLabel() { + + label_ = getDefaultInstance().getLabel(); + onChanged(); + return this; + } + /** + * string label = 2; + * @param value The bytes for label to set. + * @return This builder for chaining. + */ + public Builder setLabelBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + label_ = value; + onChanged(); + return this; + } + @java.lang.Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:supervisor.IDEStatusResponse.DesktopStatus) + } + + // @@protoc_insertion_point(class_scope:supervisor.IDEStatusResponse.DesktopStatus) + private static final io.gitpod.supervisor.api.Status.IDEStatusResponse.DesktopStatus DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new io.gitpod.supervisor.api.Status.IDEStatusResponse.DesktopStatus(); + } + + public static io.gitpod.supervisor.api.Status.IDEStatusResponse.DesktopStatus getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + private static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Override + public DesktopStatus parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new DesktopStatus(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public io.gitpod.supervisor.api.Status.IDEStatusResponse.DesktopStatus getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + public static final int OK_FIELD_NUMBER = 1; private boolean ok_; /** @@ -2136,6 +2882,32 @@ public boolean getOk() { return ok_; } + public static final int DESKTOP_FIELD_NUMBER = 2; + private io.gitpod.supervisor.api.Status.IDEStatusResponse.DesktopStatus desktop_; + /** + * .supervisor.IDEStatusResponse.DesktopStatus desktop = 2; + * @return Whether the desktop field is set. + */ + @java.lang.Override + public boolean hasDesktop() { + return desktop_ != null; + } + /** + * .supervisor.IDEStatusResponse.DesktopStatus desktop = 2; + * @return The desktop. + */ + @java.lang.Override + public io.gitpod.supervisor.api.Status.IDEStatusResponse.DesktopStatus getDesktop() { + return desktop_ == null ? io.gitpod.supervisor.api.Status.IDEStatusResponse.DesktopStatus.getDefaultInstance() : desktop_; + } + /** + * .supervisor.IDEStatusResponse.DesktopStatus desktop = 2; + */ + @java.lang.Override + public io.gitpod.supervisor.api.Status.IDEStatusResponse.DesktopStatusOrBuilder getDesktopOrBuilder() { + return getDesktop(); + } + private byte memoizedIsInitialized = -1; @java.lang.Override public final boolean isInitialized() { @@ -2153,6 +2925,9 @@ public void writeTo(com.google.protobuf.CodedOutputStream output) if (ok_ != false) { output.writeBool(1, ok_); } + if (desktop_ != null) { + output.writeMessage(2, getDesktop()); + } unknownFields.writeTo(output); } @@ -2166,6 +2941,10 @@ public int getSerializedSize() { size += com.google.protobuf.CodedOutputStream .computeBoolSize(1, ok_); } + if (desktop_ != null) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(2, getDesktop()); + } size += unknownFields.getSerializedSize(); memoizedSize = size; return size; @@ -2183,6 +2962,11 @@ public boolean equals(final java.lang.Object obj) { if (getOk() != other.getOk()) return false; + if (hasDesktop() != other.hasDesktop()) return false; + if (hasDesktop()) { + if (!getDesktop() + .equals(other.getDesktop())) return false; + } if (!unknownFields.equals(other.unknownFields)) return false; return true; } @@ -2197,6 +2981,10 @@ public int hashCode() { hash = (37 * hash) + OK_FIELD_NUMBER; hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean( getOk()); + if (hasDesktop()) { + hash = (37 * hash) + DESKTOP_FIELD_NUMBER; + hash = (53 * hash) + getDesktop().hashCode(); + } hash = (29 * hash) + unknownFields.hashCode(); memoizedHashCode = hash; return hash; @@ -2332,6 +3120,12 @@ public Builder clear() { super.clear(); ok_ = false; + if (desktopBuilder_ == null) { + desktop_ = null; + } else { + desktop_ = null; + desktopBuilder_ = null; + } return this; } @@ -2359,6 +3153,11 @@ public io.gitpod.supervisor.api.Status.IDEStatusResponse build() { public io.gitpod.supervisor.api.Status.IDEStatusResponse buildPartial() { io.gitpod.supervisor.api.Status.IDEStatusResponse result = new io.gitpod.supervisor.api.Status.IDEStatusResponse(this); result.ok_ = ok_; + if (desktopBuilder_ == null) { + result.desktop_ = desktop_; + } else { + result.desktop_ = desktopBuilder_.build(); + } onBuilt(); return result; } @@ -2410,6 +3209,9 @@ public Builder mergeFrom(io.gitpod.supervisor.api.Status.IDEStatusResponse other if (other.getOk() != false) { setOk(other.getOk()); } + if (other.hasDesktop()) { + mergeDesktop(other.getDesktop()); + } this.mergeUnknownFields(other.unknownFields); onChanged(); return this; @@ -2469,6 +3271,125 @@ public Builder clearOk() { onChanged(); return this; } + + private io.gitpod.supervisor.api.Status.IDEStatusResponse.DesktopStatus desktop_; + private com.google.protobuf.SingleFieldBuilderV3< + io.gitpod.supervisor.api.Status.IDEStatusResponse.DesktopStatus, io.gitpod.supervisor.api.Status.IDEStatusResponse.DesktopStatus.Builder, io.gitpod.supervisor.api.Status.IDEStatusResponse.DesktopStatusOrBuilder> desktopBuilder_; + /** + * .supervisor.IDEStatusResponse.DesktopStatus desktop = 2; + * @return Whether the desktop field is set. + */ + public boolean hasDesktop() { + return desktopBuilder_ != null || desktop_ != null; + } + /** + * .supervisor.IDEStatusResponse.DesktopStatus desktop = 2; + * @return The desktop. + */ + public io.gitpod.supervisor.api.Status.IDEStatusResponse.DesktopStatus getDesktop() { + if (desktopBuilder_ == null) { + return desktop_ == null ? io.gitpod.supervisor.api.Status.IDEStatusResponse.DesktopStatus.getDefaultInstance() : desktop_; + } else { + return desktopBuilder_.getMessage(); + } + } + /** + * .supervisor.IDEStatusResponse.DesktopStatus desktop = 2; + */ + public Builder setDesktop(io.gitpod.supervisor.api.Status.IDEStatusResponse.DesktopStatus value) { + if (desktopBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + desktop_ = value; + onChanged(); + } else { + desktopBuilder_.setMessage(value); + } + + return this; + } + /** + * .supervisor.IDEStatusResponse.DesktopStatus desktop = 2; + */ + public Builder setDesktop( + io.gitpod.supervisor.api.Status.IDEStatusResponse.DesktopStatus.Builder builderForValue) { + if (desktopBuilder_ == null) { + desktop_ = builderForValue.build(); + onChanged(); + } else { + desktopBuilder_.setMessage(builderForValue.build()); + } + + return this; + } + /** + * .supervisor.IDEStatusResponse.DesktopStatus desktop = 2; + */ + public Builder mergeDesktop(io.gitpod.supervisor.api.Status.IDEStatusResponse.DesktopStatus value) { + if (desktopBuilder_ == null) { + if (desktop_ != null) { + desktop_ = + io.gitpod.supervisor.api.Status.IDEStatusResponse.DesktopStatus.newBuilder(desktop_).mergeFrom(value).buildPartial(); + } else { + desktop_ = value; + } + onChanged(); + } else { + desktopBuilder_.mergeFrom(value); + } + + return this; + } + /** + * .supervisor.IDEStatusResponse.DesktopStatus desktop = 2; + */ + public Builder clearDesktop() { + if (desktopBuilder_ == null) { + desktop_ = null; + onChanged(); + } else { + desktop_ = null; + desktopBuilder_ = null; + } + + return this; + } + /** + * .supervisor.IDEStatusResponse.DesktopStatus desktop = 2; + */ + public io.gitpod.supervisor.api.Status.IDEStatusResponse.DesktopStatus.Builder getDesktopBuilder() { + + onChanged(); + return getDesktopFieldBuilder().getBuilder(); + } + /** + * .supervisor.IDEStatusResponse.DesktopStatus desktop = 2; + */ + public io.gitpod.supervisor.api.Status.IDEStatusResponse.DesktopStatusOrBuilder getDesktopOrBuilder() { + if (desktopBuilder_ != null) { + return desktopBuilder_.getMessageOrBuilder(); + } else { + return desktop_ == null ? + io.gitpod.supervisor.api.Status.IDEStatusResponse.DesktopStatus.getDefaultInstance() : desktop_; + } + } + /** + * .supervisor.IDEStatusResponse.DesktopStatus desktop = 2; + */ + private com.google.protobuf.SingleFieldBuilderV3< + io.gitpod.supervisor.api.Status.IDEStatusResponse.DesktopStatus, io.gitpod.supervisor.api.Status.IDEStatusResponse.DesktopStatus.Builder, io.gitpod.supervisor.api.Status.IDEStatusResponse.DesktopStatusOrBuilder> + getDesktopFieldBuilder() { + if (desktopBuilder_ == null) { + desktopBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< + io.gitpod.supervisor.api.Status.IDEStatusResponse.DesktopStatus, io.gitpod.supervisor.api.Status.IDEStatusResponse.DesktopStatus.Builder, io.gitpod.supervisor.api.Status.IDEStatusResponse.DesktopStatusOrBuilder>( + getDesktop(), + getParentForChildren(), + isClean()); + desktop_ = null; + } + return desktopBuilder_; + } @java.lang.Override public final Builder setUnknownFields( final com.google.protobuf.UnknownFieldSet unknownFields) { @@ -12447,6 +13368,11 @@ public io.gitpod.supervisor.api.Status.TaskPresentation getDefaultInstanceForTyp private static final com.google.protobuf.GeneratedMessageV3.FieldAccessorTable internal_static_supervisor_IDEStatusResponse_fieldAccessorTable; + private static final com.google.protobuf.Descriptors.Descriptor + internal_static_supervisor_IDEStatusResponse_DesktopStatus_descriptor; + private static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_supervisor_IDEStatusResponse_DesktopStatus_fieldAccessorTable; private static final com.google.protobuf.Descriptors.Descriptor internal_static_supervisor_ContentStatusRequest_descriptor; private static final @@ -12530,68 +13456,71 @@ public io.gitpod.supervisor.api.Status.TaskPresentation getDefaultInstanceForTyp "nnotations.proto\032\nport.proto\"\031\n\027Supervis" + "orStatusRequest\"&\n\030SupervisorStatusRespo" + "nse\022\n\n\002ok\030\001 \001(\010\" \n\020IDEStatusRequest\022\014\n\004w" + - "ait\030\001 \001(\010\"\037\n\021IDEStatusResponse\022\n\n\002ok\030\001 \001" + - "(\010\"$\n\024ContentStatusRequest\022\014\n\004wait\030\001 \001(\010" + - "\"U\n\025ContentStatusResponse\022\021\n\tavailable\030\001" + - " \001(\010\022)\n\006source\030\002 \001(\0162\031.supervisor.Conten" + - "tSource\"\025\n\023BackupStatusRequest\"0\n\024Backup" + - "StatusResponse\022\030\n\020canary_available\030\001 \001(\010" + - "\"%\n\022PortsStatusRequest\022\017\n\007observe\030\001 \001(\010\"" + - "=\n\023PortsStatusResponse\022&\n\005ports\030\001 \003(\0132\027." + - "supervisor.PortsStatus\"\203\001\n\017ExposedPortIn" + - "fo\022.\n\nvisibility\030\001 \001(\0162\032.supervisor.Port" + - "Visibility\022\013\n\003url\030\002 \001(\t\0223\n\non_exposed\030\003 " + - "\001(\0162\037.supervisor.OnPortExposedAction\"\304\001\n" + - "\020TunneledPortInfo\022\023\n\013target_port\030\001 \001(\r\022/" + - "\n\nvisibility\030\002 \001(\0162\033.supervisor.TunnelVi" + - "siblity\022:\n\007clients\030\003 \003(\0132).supervisor.Tu" + - "nneledPortInfo.ClientsEntry\032.\n\014ClientsEn" + - "try\022\013\n\003key\030\001 \001(\t\022\r\n\005value\030\002 \001(\r:\0028\001\"\331\001\n\013" + - "PortsStatus\022\022\n\nlocal_port\030\001 \001(\r\022\023\n\013globa" + - "l_port\030\002 \001(\r\022\016\n\006served\030\004 \001(\010\022,\n\007exposed\030" + - "\005 \001(\0132\033.supervisor.ExposedPortInfo\0223\n\rau" + - "to_exposure\030\007 \001(\0162\034.supervisor.PortAutoE" + - "xposure\022.\n\010tunneled\030\006 \001(\0132\034.supervisor.T" + - "unneledPortInfo\"%\n\022TasksStatusRequest\022\017\n" + - "\007observe\030\001 \001(\010\"<\n\023TasksStatusResponse\022%\n" + - "\005tasks\030\001 \003(\0132\026.supervisor.TaskStatus\"\204\001\n" + - "\nTaskStatus\022\n\n\002id\030\001 \001(\t\022$\n\005state\030\002 \001(\0162\025" + - ".supervisor.TaskState\022\020\n\010terminal\030\003 \001(\t\022" + - "2\n\014presentation\030\004 \001(\0132\034.supervisor.TaskP" + - "resentation\"D\n\020TaskPresentation\022\014\n\004name\030" + - "\001 \001(\t\022\017\n\007open_in\030\002 \001(\t\022\021\n\topen_mode\030\003 \001(" + - "\t*C\n\rContentSource\022\016\n\nfrom_other\020\000\022\017\n\013fr" + - "om_backup\020\001\022\021\n\rfrom_prebuild\020\002*?\n\016PortVi" + - "sibility\022\026\n\022private_visibility\020\000\022\025\n\021publ" + - "ic_visibility\020\001*e\n\023OnPortExposedAction\022\n" + - "\n\006ignore\020\000\022\020\n\014open_browser\020\001\022\020\n\014open_pre" + - "view\020\002\022\n\n\006notify\020\003\022\022\n\016notify_private\020\004*9" + - "\n\020PortAutoExposure\022\n\n\006trying\020\000\022\r\n\tsuccee" + - "ded\020\001\022\n\n\006failed\020\002*1\n\tTaskState\022\013\n\007openin" + - "g\020\000\022\013\n\007running\020\001\022\n\n\006closed\020\0022\313\006\n\rStatusS" + - "ervice\022|\n\020SupervisorStatus\022#.supervisor." + - "SupervisorStatusRequest\032$.supervisor.Sup" + - "ervisorStatusResponse\"\035\202\323\344\223\002\027\022\025/v1/statu" + - "s/supervisor\022\203\001\n\tIDEStatus\022\034.supervisor." + - "IDEStatusRequest\032\035.supervisor.IDEStatusR" + - "esponse\"9\202\323\344\223\0023\022\016/v1/status/ideZ!\022\037/v1/s" + - "tatus/ide/wait/{wait=true}\022\227\001\n\rContentSt" + - "atus\022 .supervisor.ContentStatusRequest\032!" + - ".supervisor.ContentStatusResponse\"A\202\323\344\223\002" + - ";\022\022/v1/status/contentZ%\022#/v1/status/cont" + - "ent/wait/{wait=true}\022l\n\014BackupStatus\022\037.s" + - "upervisor.BackupStatusRequest\032 .supervis" + - "or.BackupStatusResponse\"\031\202\323\344\223\002\023\022\021/v1/sta" + - "tus/backup\022\225\001\n\013PortsStatus\022\036.supervisor." + - "PortsStatusRequest\032\037.supervisor.PortsSta" + - "tusResponse\"C\202\323\344\223\002=\022\020/v1/status/portsZ)\022" + - "\'/v1/status/ports/observe/{observe=true}" + - "0\001\022\225\001\n\013TasksStatus\022\036.supervisor.TasksSta" + - "tusRequest\032\037.supervisor.TasksStatusRespo" + - "nse\"C\202\323\344\223\002=\022\020/v1/status/tasksZ)\022\'/v1/sta" + - "tus/tasks/observe/{observe=true}0\001BF\n\030io" + - ".gitpod.supervisor.apiZ*github.com/gitpo" + - "d-io/gitpod/supervisor/apib\006proto3" + "ait\030\001 \001(\010\"\213\001\n\021IDEStatusResponse\022\n\n\002ok\030\001 " + + "\001(\010\022<\n\007desktop\030\002 \001(\0132+.supervisor.IDESta" + + "tusResponse.DesktopStatus\032,\n\rDesktopStat" + + "us\022\014\n\004link\030\001 \001(\t\022\r\n\005label\030\002 \001(\t\"$\n\024Conte" + + "ntStatusRequest\022\014\n\004wait\030\001 \001(\010\"U\n\025Content" + + "StatusResponse\022\021\n\tavailable\030\001 \001(\010\022)\n\006sou" + + "rce\030\002 \001(\0162\031.supervisor.ContentSource\"\025\n\023" + + "BackupStatusRequest\"0\n\024BackupStatusRespo" + + "nse\022\030\n\020canary_available\030\001 \001(\010\"%\n\022PortsSt" + + "atusRequest\022\017\n\007observe\030\001 \001(\010\"=\n\023PortsSta" + + "tusResponse\022&\n\005ports\030\001 \003(\0132\027.supervisor." + + "PortsStatus\"\203\001\n\017ExposedPortInfo\022.\n\nvisib" + + "ility\030\001 \001(\0162\032.supervisor.PortVisibility\022" + + "\013\n\003url\030\002 \001(\t\0223\n\non_exposed\030\003 \001(\0162\037.super" + + "visor.OnPortExposedAction\"\304\001\n\020TunneledPo" + + "rtInfo\022\023\n\013target_port\030\001 \001(\r\022/\n\nvisibilit" + + "y\030\002 \001(\0162\033.supervisor.TunnelVisiblity\022:\n\007" + + "clients\030\003 \003(\0132).supervisor.TunneledPortI" + + "nfo.ClientsEntry\032.\n\014ClientsEntry\022\013\n\003key\030" + + "\001 \001(\t\022\r\n\005value\030\002 \001(\r:\0028\001\"\331\001\n\013PortsStatus" + + "\022\022\n\nlocal_port\030\001 \001(\r\022\023\n\013global_port\030\002 \001(" + + "\r\022\016\n\006served\030\004 \001(\010\022,\n\007exposed\030\005 \001(\0132\033.sup" + + "ervisor.ExposedPortInfo\0223\n\rauto_exposure" + + "\030\007 \001(\0162\034.supervisor.PortAutoExposure\022.\n\010" + + "tunneled\030\006 \001(\0132\034.supervisor.TunneledPort" + + "Info\"%\n\022TasksStatusRequest\022\017\n\007observe\030\001 " + + "\001(\010\"<\n\023TasksStatusResponse\022%\n\005tasks\030\001 \003(" + + "\0132\026.supervisor.TaskStatus\"\204\001\n\nTaskStatus" + + "\022\n\n\002id\030\001 \001(\t\022$\n\005state\030\002 \001(\0162\025.supervisor" + + ".TaskState\022\020\n\010terminal\030\003 \001(\t\0222\n\014presenta" + + "tion\030\004 \001(\0132\034.supervisor.TaskPresentation" + + "\"D\n\020TaskPresentation\022\014\n\004name\030\001 \001(\t\022\017\n\007op" + + "en_in\030\002 \001(\t\022\021\n\topen_mode\030\003 \001(\t*C\n\rConten" + + "tSource\022\016\n\nfrom_other\020\000\022\017\n\013from_backup\020\001" + + "\022\021\n\rfrom_prebuild\020\002*?\n\016PortVisibility\022\026\n" + + "\022private_visibility\020\000\022\025\n\021public_visibili" + + "ty\020\001*e\n\023OnPortExposedAction\022\n\n\006ignore\020\000\022" + + "\020\n\014open_browser\020\001\022\020\n\014open_preview\020\002\022\n\n\006n" + + "otify\020\003\022\022\n\016notify_private\020\004*9\n\020PortAutoE" + + "xposure\022\n\n\006trying\020\000\022\r\n\tsucceeded\020\001\022\n\n\006fa" + + "iled\020\002*1\n\tTaskState\022\013\n\007opening\020\000\022\013\n\007runn" + + "ing\020\001\022\n\n\006closed\020\0022\313\006\n\rStatusService\022|\n\020S" + + "upervisorStatus\022#.supervisor.SupervisorS" + + "tatusRequest\032$.supervisor.SupervisorStat" + + "usResponse\"\035\202\323\344\223\002\027\022\025/v1/status/superviso" + + "r\022\203\001\n\tIDEStatus\022\034.supervisor.IDEStatusRe" + + "quest\032\035.supervisor.IDEStatusResponse\"9\202\323" + + "\344\223\0023\022\016/v1/status/ideZ!\022\037/v1/status/ide/w" + + "ait/{wait=true}\022\227\001\n\rContentStatus\022 .supe" + + "rvisor.ContentStatusRequest\032!.supervisor" + + ".ContentStatusResponse\"A\202\323\344\223\002;\022\022/v1/stat" + + "us/contentZ%\022#/v1/status/content/wait/{w" + + "ait=true}\022l\n\014BackupStatus\022\037.supervisor.B" + + "ackupStatusRequest\032 .supervisor.BackupSt" + + "atusResponse\"\031\202\323\344\223\002\023\022\021/v1/status/backup\022" + + "\225\001\n\013PortsStatus\022\036.supervisor.PortsStatus" + + "Request\032\037.supervisor.PortsStatusResponse" + + "\"C\202\323\344\223\002=\022\020/v1/status/portsZ)\022\'/v1/status" + + "/ports/observe/{observe=true}0\001\022\225\001\n\013Task" + + "sStatus\022\036.supervisor.TasksStatusRequest\032" + + "\037.supervisor.TasksStatusResponse\"C\202\323\344\223\002=" + + "\022\020/v1/status/tasksZ)\022\'/v1/status/tasks/o" + + "bserve/{observe=true}0\001BF\n\030io.gitpod.sup" + + "ervisor.apiZ*github.com/gitpod-io/gitpod" + + "/supervisor/apib\006proto3" }; descriptor = com.google.protobuf.Descriptors.FileDescriptor .internalBuildGeneratedFileFrom(descriptorData, @@ -12622,7 +13551,13 @@ public io.gitpod.supervisor.api.Status.TaskPresentation getDefaultInstanceForTyp internal_static_supervisor_IDEStatusResponse_fieldAccessorTable = new com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( internal_static_supervisor_IDEStatusResponse_descriptor, - new java.lang.String[] { "Ok", }); + new java.lang.String[] { "Ok", "Desktop", }); + internal_static_supervisor_IDEStatusResponse_DesktopStatus_descriptor = + internal_static_supervisor_IDEStatusResponse_descriptor.getNestedTypes().get(0); + internal_static_supervisor_IDEStatusResponse_DesktopStatus_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_supervisor_IDEStatusResponse_DesktopStatus_descriptor, + new java.lang.String[] { "Link", "Label", }); internal_static_supervisor_ContentStatusRequest_descriptor = getDescriptor().getMessageTypes().get(4); internal_static_supervisor_ContentStatusRequest_fieldAccessorTable = new diff --git a/components/supervisor-api/status.proto b/components/supervisor-api/status.proto index 51de9a29a7a7f0..bc0189790f5382 100644 --- a/components/supervisor-api/status.proto +++ b/components/supervisor-api/status.proto @@ -86,6 +86,13 @@ message IDEStatusRequest { } message IDEStatusResponse { bool ok = 1; + + message DesktopStatus { + string link = 1; + string label = 2; + } + + DesktopStatus desktop = 2; } message ContentStatusRequest { diff --git a/components/supervisor/pkg/supervisor/config.go b/components/supervisor/pkg/supervisor/config.go index 8e51ca2f7a3342..e1f44fe742a786 100644 --- a/components/supervisor/pkg/supervisor/config.go +++ b/components/supervisor/pkg/supervisor/config.go @@ -29,12 +29,14 @@ const supervisorConfigFile = "supervisor-config.json" // there's some configuration that lives with supervisor and its "installation", // For example the IDE config location depends on if supervisor is served via registry-facade. // 2. IDE: Gitpod supports different IDEs, all of which have different configuration needs. -// 3. Workspace: which depends on the individual workspace, its content and configuration. +// 3. DesktopIDE: Gitpod supports to connect external IDEs (like desktop IDEs). +// 4. Workspace: which depends on the individual workspace, its content and configuration. // Config configures supervisor type Config struct { StaticConfig - IDEConfig + IDE IDEConfig + DesktopIDE *IDEConfig WorkspaceConfig } @@ -43,9 +45,14 @@ func (c Config) Validate() error { if err := c.StaticConfig.Validate(); err != nil { return xerrors.Errorf("static supervisor config is invalid: %w", err) } - if err := c.IDEConfig.Validate(); err != nil { + if err := c.IDE.Validate(); err != nil { return xerrors.Errorf("IDE config is invalid: %w", err) } + if c.DesktopIDE != nil { + if err := c.DesktopIDE.Validate(); err != nil { + return xerrors.Errorf("Desktop IDE config is invalid: %w", err) + } + } if err := c.WorkspaceConfig.Validate(); err != nil { return xerrors.Errorf("Workspace config is invalid: %w", err) } @@ -55,11 +62,11 @@ func (c Config) Validate() error { // LogRateLimit returns the log rate limit for the IDE process in kib/sec. // If log rate limiting is disbaled, this function returns 0. -func (c Config) LogRateLimit() int { - if c.WorkspaceLogRateLimit < c.IDELogRateLimit { +func (c Config) IDELogRateLimit(ideConfig *IDEConfig) int { + if c.WorkspaceLogRateLimit < ideConfig.LogRateLimit { return c.WorkspaceLogRateLimit } - return c.IDELogRateLimit + return ideConfig.LogRateLimit } // StaticConfig is the supervisor-wide configuration @@ -67,6 +74,9 @@ type StaticConfig struct { // IDEConfigLocation is a path in the filesystem where to find the IDE configuration IDEConfigLocation string `json:"ideConfigLocation"` + // DesktopIDEConfigLocation is a path in the filesystem where to find the desktop IDE configuration + DesktopIDEConfigLocation string `json:"desktopIdeConfigLocation"` + // FrontendLocation is a path in the filesystem where to find supervisor's frontend assets FrontendLocation string `json:"frontendLocation"` @@ -114,10 +124,13 @@ type IDEConfig struct { // code the workspace is stopped. Entrypoint string `json:"entrypoint"` + // EntrypointArgs + EntrypointArgs []string `json:"entrypointArgs"` + // LogRateLimit can be used to limit the log output of the IDE process. // Any output that exceeds this limit is silently dropped. // Expressed in kb/sec. Can be overriden by the workspace config (smallest value wins). - IDELogRateLimit int `json:"logRateLimit"` + LogRateLimit int `json:"logRateLimit"` // ReadinessProbe configures the probe used to serve the IDE status ReadinessProbe struct { @@ -127,7 +140,16 @@ type IDEConfig struct { // HTTPProbe configures the HTTP readiness probe. HTTPProbe struct { - // Path is the path to make requests to. Defaults to "/" + // Schema is either "http" or "https". Defaults to "http". + Schema string `json:"schema"` + + // Host is the host to make requests to. Default to "localhost". + Host string `json:"host"` + + // Port is the port to make requests to. Default it the IDE port in the supervisor config. + Port int `json:"port"` + + // Path is the path to make requests to. Defaults to "/". Path string `json:"path"` } `json:"http"` } `json:"readinessProbe"` @@ -144,7 +166,7 @@ func (c IDEConfig) Validate() error { return xerrors.Errorf("entrypoint is a directory, but should be a file") } - if c.IDELogRateLimit < 0 { + if c.LogRateLimit < 0 { return xerrors.Errorf("logRateLimit must be >= 0") } @@ -357,6 +379,16 @@ func GetConfig() (*Config, error) { return nil, err } + var desktopIde *IDEConfig + if static.DesktopIDEConfigLocation != "" { + if _, err := os.Stat(static.DesktopIDEConfigLocation); !os.IsNotExist((err)) { + desktopIde, err = loadIDEConfigFromFile(static.DesktopIDEConfigLocation) + if err != nil { + return nil, err + } + } + } + workspace, err := loadWorkspaceConfigFromEnv() if err != nil { return nil, err @@ -364,7 +396,8 @@ func GetConfig() (*Config, error) { return &Config{ StaticConfig: *static, - IDEConfig: *ide, + IDE: *ide, + DesktopIDE: desktopIde, WorkspaceConfig: *workspace, }, nil } diff --git a/components/supervisor/pkg/supervisor/services.go b/components/supervisor/pkg/supervisor/services.go index ca75aa9f6a9047..6cca46e6133bcb 100644 --- a/components/supervisor/pkg/supervisor/services.go +++ b/components/supervisor/pkg/supervisor/services.go @@ -39,8 +39,14 @@ type RegisterableRESTService interface { RegisterREST(mux *runtime.ServeMux, grpcEndpoint string) error } +type DesktopIDEStatus struct { + Link string `json:"link"` + Label string `json:"label"` +} + type ideReadyState struct { ready bool + info *DesktopIDEStatus cond *sync.Cond } @@ -59,29 +65,32 @@ func (service *ideReadyState) Wait() <-chan struct{} { } // Get checks whether IDE is ready -func (service *ideReadyState) Get() bool { +func (service *ideReadyState) Get() (bool, *DesktopIDEStatus) { service.cond.L.Lock() ready := service.ready + info := service.info service.cond.L.Unlock() - return ready + return ready, info } // Set updates IDE ready state -func (service *ideReadyState) Set(ready bool) { +func (service *ideReadyState) Set(ready bool, info *DesktopIDEStatus) { service.cond.L.Lock() defer service.cond.L.Unlock() if service.ready == ready { return } service.ready = ready + service.info = info service.cond.Broadcast() } type statusService struct { - ContentState ContentState - Ports *ports.Manager - Tasks *tasksManager - ideReady *ideReadyState + ContentState ContentState + Ports *ports.Manager + Tasks *tasksManager + ideReady *ideReadyState + desktopIdeReady *ideReadyState api.UnimplementedStatusServiceServer } @@ -102,7 +111,9 @@ func (s *statusService) IDEStatus(ctx context.Context, req *api.IDEStatusRequest if req.Wait { select { case <-s.ideReady.Wait(): - return &api.IDEStatusResponse{Ok: true}, nil + { + // do nothing + } case <-ctx.Done(): if errors.Is(ctx.Err(), context.Canceled) { return nil, status.Error(codes.Canceled, "execution canceled") @@ -110,10 +121,34 @@ func (s *statusService) IDEStatus(ctx context.Context, req *api.IDEStatusRequest return nil, status.Error(codes.DeadlineExceeded, ctx.Err().Error()) } + + if s.desktopIdeReady != nil { + select { + case <-s.desktopIdeReady.Wait(): + { + // do nothing + } + case <-ctx.Done(): + if errors.Is(ctx.Err(), context.Canceled) { + return nil, status.Error(codes.Canceled, "execution canceled") + } + + return nil, status.Error(codes.DeadlineExceeded, ctx.Err().Error()) + } + } } - ok := s.ideReady.Get() - return &api.IDEStatusResponse{Ok: ok}, nil + ok, _ := s.ideReady.Get() + desktopStatus := &api.IDEStatusResponse_DesktopStatus{} + if s.desktopIdeReady != nil { + okR, i := s.desktopIdeReady.Get() + if i != nil { + desktopStatus.Link = i.Link + desktopStatus.Label = i.Label + } + ok = ok && okR + } + return &api.IDEStatusResponse{Ok: ok, Desktop: desktopStatus}, nil } // ContentStatus provides feedback regarding the workspace content readiness diff --git a/components/supervisor/pkg/supervisor/supervisor.go b/components/supervisor/pkg/supervisor/supervisor.go index 5cd7832162dcf8..6c2e8b11243f76 100644 --- a/components/supervisor/pkg/supervisor/supervisor.go +++ b/components/supervisor/pkg/supervisor/supervisor.go @@ -111,6 +111,23 @@ const ( ShutdownReasonExecutionError ShutdownReason = 1 ) +type IDEKind int64 + +const ( + WebIDE IDEKind = iota + DesktopIDE +) + +func (s IDEKind) String() string { + switch s { + case WebIDE: + return "IDE" + case DesktopIDE: + return "Desktop IDE" + } + return "unknown" +} + // Run serves as main entrypoint to the supervisor func Run(options ...RunOption) { exitCode := 0 @@ -169,12 +186,13 @@ func Run(options ...RunOption) { ctx, cancel := context.WithCancel(context.Background()) var ( - shutdown = make(chan ShutdownReason, 1) - ideReady = &ideReadyState{cond: sync.NewCond(&sync.Mutex{})} - cstate = NewInMemoryContentState(cfg.RepoRoot) - gitpodService = createGitpodService(cfg, tokenService) - gitpodConfigService = config.NewConfigService(cfg.RepoRoot+"/.gitpod.yml", cstate.ContentReady(), log.Log) - portMgmt = ports.NewManager( + shutdown = make(chan ShutdownReason, 1) + ideReady = &ideReadyState{cond: sync.NewCond(&sync.Mutex{})} + desktopIdeReady *ideReadyState = nil + cstate = NewInMemoryContentState(cfg.RepoRoot) + gitpodService = createGitpodService(cfg, tokenService) + gitpodConfigService = config.NewConfigService(cfg.RepoRoot+"/.gitpod.yml", cstate.ContentReady(), log.Log) + portMgmt = ports.NewManager( createExposedPortsImpl(cfg, gitpodService), &ports.PollingServedPortsObserver{ RefreshInterval: 2 * time.Second, @@ -191,6 +209,9 @@ func Run(options ...RunOption) { analytics = analytics.NewFromEnvironment() notificationService = NewNotificationService() ) + if cfg.DesktopIDE != nil { + desktopIdeReady = &ideReadyState{cond: sync.NewCond(&sync.Mutex{})} + } tokenService.provider[KindGit] = []tokenProvider{NewGitTokenProvider(gitpodService, cfg.WorkspaceConfig, notificationService)} go gitpodConfigService.Watch(ctx) @@ -219,10 +240,11 @@ func Run(options ...RunOption) { apiServices := []RegisterableService{ &statusService{ - ContentState: cstate, - Ports: portMgmt, - Tasks: taskManager, - ideReady: ideReady, + ContentState: cstate, + Ports: portMgmt, + Tasks: taskManager, + ideReady: ideReady, + desktopIdeReady: desktopIdeReady, }, termMuxSrv, RegistrableTokenService{Service: tokenService}, @@ -245,7 +267,11 @@ func Run(options ...RunOption) { var ideWG sync.WaitGroup ideWG.Add(1) - go startAndWatchIDE(ctx, cfg, &ideWG, ideReady) + go startAndWatchIDE(ctx, cfg, &cfg.IDE, &ideWG, ideReady, WebIDE) + if cfg.DesktopIDE != nil { + ideWG.Add(1) + go startAndWatchIDE(ctx, cfg, cfg.DesktopIDE, &ideWG, desktopIdeReady, DesktopIDE) + } var wg sync.WaitGroup wg.Add(1) @@ -477,22 +503,24 @@ func reaper(terminatingReaper <-chan bool) { } } -func startAndWatchIDE(ctx context.Context, cfg *Config, wg *sync.WaitGroup, ideReady *ideReadyState) { +type ideStatus int + +const ( + statusNeverRan ideStatus = iota + statusShouldRun + statusShouldShutdown +) + +func startAndWatchIDE(ctx context.Context, cfg *Config, ideConfig *IDEConfig, wg *sync.WaitGroup, ideReady *ideReadyState, ide IDEKind) { defer wg.Done() - defer log.Debug("startAndWatchIDE shutdown") + defer log.WithField("ide", ide.String()).Debug("startAndWatchIDE shutdown") if cfg.isHeadless() { - ideReady.Set(true) + ideReady.Set(true, nil) return } - type status int - const ( - statusNeverRan status = iota - statusShouldRun - statusShouldShutdown - ) - s := statusNeverRan + ideStatus := statusNeverRan var ( cmd *exec.Cmd @@ -500,63 +528,23 @@ func startAndWatchIDE(ctx context.Context, cfg *Config, wg *sync.WaitGroup, ideR ) supervisorLoop: for { - if s == statusShouldShutdown { + if ideStatus == statusShouldShutdown { break } ideStopped = make(chan struct{}, 1) - go func() { - cmd = prepareIDELaunch(cfg) - - // prepareIDELaunch sets Pdeathsig, which on on Linux, will kill the - // child process when the thread dies, not when the process dies. - // runtime.LockOSThread ensures that as long as this function is - // executing that OS thread will still be around. - // - // see https://github.com/golang/go/issues/27505#issuecomment-713706104 - runtime.LockOSThread() - defer runtime.UnlockOSThread() - - err := cmd.Start() - if err != nil { - if s == statusNeverRan { - log.WithError(err).Fatal("IDE failed to start") - } - - return - } - s = statusShouldRun - - go func() { - runIDEReadinessProbe(cfg) - ideReady.Set(true) - }() - - err = cmd.Wait() - if err != nil && !(strings.Contains(err.Error(), "signal: interrupt") || strings.Contains(err.Error(), "wait: no child processes")) { - log.WithError(err).Warn("IDE was stopped") - - ideWasReady := ideReady.Get() - if !ideWasReady { - log.WithError(err).Fatal("IDE failed to start") - return - } - } - - ideReady.Set(false) - close(ideStopped) - }() + launchIDE(cfg, ideConfig, cmd, ideStopped, ideReady, &ideStatus, ide) select { case <-ideStopped: // IDE was stopped - let's just restart it after a small delay (in case the IDE doesn't start at all) in the next round - if s == statusShouldShutdown { + if ideStatus == statusShouldShutdown { break supervisorLoop } time.Sleep(1 * time.Second) case <-ctx.Done(): // we've been asked to shut down - s = statusShouldShutdown + ideStatus = statusShouldShutdown if cmd != nil && cmd.Process != nil { cmd.Process.Signal(os.Interrupt) } @@ -564,24 +552,78 @@ supervisorLoop: } } - log.WithField("budget", timeBudgetIDEShutdown.String()).Info("IDE supervisor loop ended - waiting for IDE to come down") + log.WithField("ide", ide.String()).WithField("budget", timeBudgetIDEShutdown.String()).Info("IDE supervisor loop ended - waiting for IDE to come down") select { case <-ideStopped: return case <-time.After(timeBudgetIDEShutdown): - log.WithField("timeBudgetIDEShutdown", timeBudgetIDEShutdown.String()).Error("IDE did not stop in time - sending SIGKILL") + log.WithField("ide", ide.String()).WithField("timeBudgetIDEShutdown", timeBudgetIDEShutdown.String()).Error("IDE did not stop in time - sending SIGKILL") cmd.Process.Signal(syscall.SIGKILL) } } -func prepareIDELaunch(cfg *Config) *exec.Cmd { - var args []string - args = append(args, cfg.WorkspaceRoot) - args = append(args, "--port", strconv.Itoa(cfg.IDEPort)) - args = append(args, "--hostname", "0.0.0.0") - log.WithField("args", args).WithField("entrypoint", cfg.Entrypoint).Info("launching IDE") +func launchIDE(cfg *Config, ideConfig *IDEConfig, cmd *exec.Cmd, ideStopped chan struct{}, ideReady *ideReadyState, s *ideStatus, ide IDEKind) { + go func() { + cmd = prepareIDELaunch(cfg, ideConfig) + + // prepareIDELaunch sets Pdeathsig, which on on Linux, will kill the + // child process when the thread dies, not when the process dies. + // runtime.LockOSThread ensures that as long as this function is + // executing that OS thread will still be around. + // + // see https://github.com/golang/go/issues/27505#issuecomment-713706104 + runtime.LockOSThread() + defer runtime.UnlockOSThread() + + err := cmd.Start() + if err != nil { + if s == func() *ideStatus { i := statusNeverRan; return &i }() { + log.WithField("ide", ide.String()).WithError(err).Fatal("IDE failed to start") + } + + return + } + s = func() *ideStatus { i := statusShouldRun; return &i }() + + go func() { + desktopIDEStatus := runIDEReadinessProbe(cfg, ideConfig, ide) + ideReady.Set(true, desktopIDEStatus) + }() + + err = cmd.Wait() + if err != nil && !(strings.Contains(err.Error(), "signal: interrupt") || strings.Contains(err.Error(), "wait: no child processes")) { + log.WithField("ide", ide.String()).WithError(err).Warn("IDE was stopped") + + ideWasReady, _ := ideReady.Get() + if !ideWasReady { + log.WithField("ide", ide.String()).WithError(err).Fatal("IDE failed to start") + return + } + } + + ideReady.Set(false, nil) + close(ideStopped) + }() +} + +func prepareIDELaunch(cfg *Config, ideConfig *IDEConfig) *exec.Cmd { + args := ideConfig.EntrypointArgs + + // Add default args for IDE (not desktop IDE) to be backwards compatible + if ideConfig.Entrypoint == "/ide/startup.sh" && len(args) == 0 { + args = append(args, "{WORKSPACEROOT}") + args = append(args, "--port", "{IDEPORT}") + args = append(args, "--hostname", "{IDEHOSTNAME}") + } - cmd := exec.Command(cfg.Entrypoint, args...) + for i := range args { + args[i] = strings.ReplaceAll(args[i], "{WORKSPACEROOT}", cfg.WorkspaceRoot) + args[i] = strings.ReplaceAll(args[i], "{IDEPORT}", strconv.Itoa(cfg.IDEPort)) + args[i] = strings.ReplaceAll(args[i], "{IDEHOSTNAME}", "0.0.0.0") + } + log.WithField("args", args).WithField("entrypoint", ideConfig.Entrypoint).Info("launching IDE") + + cmd := exec.Command(ideConfig.Entrypoint, args...) cmd.SysProcAttr = &syscall.SysProcAttr{ // We need the child process to run in its own process group, s.t. we can suspend and resume // IDE and its children. @@ -601,7 +643,7 @@ func prepareIDELaunch(cfg *Config) *exec.Cmd { // This would break the JSON parsing of the headless builds. cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr - if lrr := cfg.LogRateLimit(); lrr > 0 { + if lrr := cfg.IDELogRateLimit(ideConfig); lrr > 0 { limit := int64(lrr) cmd.Stdout = dropwriter.Writer(cmd.Stdout, dropwriter.NewBucket(limit*1024*3, limit*1024)) cmd.Stderr = dropwriter.Writer(cmd.Stderr, dropwriter.NewBucket(limit*1024*3, limit*1024)) @@ -670,16 +712,33 @@ func buildChildProcEnv(cfg *Config, envvars []string) []string { return env } -func runIDEReadinessProbe(cfg *Config) { - defer log.Info("IDE is ready") +func runIDEReadinessProbe(cfg *Config, ideConfig *IDEConfig, ide IDEKind) (desktopIDEStatus *DesktopIDEStatus) { + defer log.WithField("ide", ide.String()).Info("IDE is ready") + + defaultIfEmpty := func(value, defaultValue string) string { + if len(value) == 0 { + return defaultValue + } + return value + } + + defaultIfZero := func(value, defaultValue int) int { + if value == 0 { + return defaultValue + } + return value + } - switch cfg.ReadinessProbe.Type { + switch ideConfig.ReadinessProbe.Type { case ReadinessProcessProbe: return case ReadinessHTTPProbe: var ( - url = fmt.Sprintf("http://localhost:%d/%s", cfg.IDEPort, strings.TrimPrefix(cfg.ReadinessProbe.HTTPProbe.Path, "/")) + schema = defaultIfEmpty(ideConfig.ReadinessProbe.HTTPProbe.Schema, "http") + host = defaultIfEmpty(ideConfig.ReadinessProbe.HTTPProbe.Host, "localhost") + port = defaultIfZero(ideConfig.ReadinessProbe.HTTPProbe.Port, cfg.IDEPort) + url = fmt.Sprintf("%s://%s:%d/%s", schema, host, port, strings.TrimPrefix(ideConfig.ReadinessProbe.HTTPProbe.Path, "/")) client = http.Client{Timeout: 1 * time.Second} tick = time.NewTicker(500 * time.Millisecond) ) @@ -694,16 +753,32 @@ func runIDEReadinessProbe(cfg *Config) { if err != nil { continue } - resp.Body.Close() + defer resp.Body.Close() if resp.StatusCode == http.StatusOK { - log.WithField("status", resp.StatusCode).Infof("IDE readiness took %.3f seconds", time.Since(t0).Seconds()) + log.WithField("ide", ide.String()).WithField("status", resp.StatusCode).Infof("IDE readiness took %.3f seconds", time.Since(t0).Seconds()) + + if ide == DesktopIDE { + bodyBytes, err := ioutil.ReadAll(resp.Body) + log.WithField("ide", ide.String()).Infof("IDE status probe body: %s", string(bodyBytes)) + if err != nil { + log.WithField("ide", ide.String()).WithError(err).Infof("Error reading response body from IDE status probe.") + break + } + err = json.Unmarshal(bodyBytes, &desktopIDEStatus) + if err != nil { + log.WithField("ide", ide.String()).WithError(err).WithField("body", bodyBytes).Debugf("Error parsing JSON body from IDE status probe.") + break + } + log.WithField("ide", ide.String()).Infof("Desktop IDE status: %s", desktopIDEStatus) + } break } - log.WithField("status", resp.StatusCode).Info("IDE readiness probe came back with non-200 status code") + log.WithField("ide", ide.String()).WithField("status", resp.StatusCode).Info("IDE readiness probe came back with non-200 status code") } } + return } func isBlacklistedEnvvar(name string) bool { diff --git a/components/supervisor/supervisor-config.json b/components/supervisor/supervisor-config.json index 5f2084c9bed7bf..2a5800eec655f7 100644 --- a/components/supervisor/supervisor-config.json +++ b/components/supervisor/supervisor-config.json @@ -1,5 +1,6 @@ { "ideConfigLocation": "/ide/supervisor-ide-config.json", + "desktopIdeConfigLocation": "/ide-desktop/supervisor-ide-config.json", "frontendLocation": "/.supervisor/frontend/", "apiEndpointPort": 22999, "sshPort": 23001 From 911541c574949f7f37ec1fde4eb51a7c268adae7 Mon Sep 17 00:00:00 2001 From: "Cornelius A. Ludmann" Date: Fri, 22 Oct 2021 15:03:33 +0000 Subject: [PATCH 4/7] [supervisor] Add desktop IDE frontend support /werft with-clean-slate-deployment --- components/dashboard/src/start/StartPage.tsx | 11 ++-- .../dashboard/src/start/StartWorkspace.tsx | 30 ++++++++++- .../src/ide/supervisor-service-client.ts | 4 +- components/supervisor/frontend/src/index.ts | 53 ++++++++++++++++--- .../frontend/src/shared/loading-frame.ts | 6 +-- 5 files changed, 87 insertions(+), 17 deletions(-) diff --git a/components/dashboard/src/start/StartPage.tsx b/components/dashboard/src/start/StartPage.tsx index b1aa4255061919..77e67ebe07f304 100644 --- a/components/dashboard/src/start/StartPage.tsx +++ b/components/dashboard/src/start/StartPage.tsx @@ -13,8 +13,9 @@ export enum StartPhase { Creating = 2, Starting = 3, Running = 4, - Stopping = 5, - Stopped = 6, + IdeReady = 5, + Stopping = 6, + Stopped = 7, }; function getPhaseTitle(phase?: StartPhase, error?: StartWorkspaceError) { @@ -32,6 +33,8 @@ function getPhaseTitle(phase?: StartPhase, error?: StartWorkspaceError) { return "Starting"; case StartPhase.Running: return "Starting"; + case StartPhase.IdeReady: + return "Your Workspace is Ready!"; case StartPhase.Stopping: return "Stopping"; case StartPhase.Stopped: @@ -84,9 +87,9 @@ export function StartPage(props: StartPageProps) { return
- Gitpod's logo + Gitpod's logo

{title}

- {typeof(phase) === 'number' && phase < StartPhase.Stopping && } + {typeof(phase) === 'number' && phase < StartPhase.IdeReady && } {error && } {props.children}
diff --git a/components/dashboard/src/start/StartWorkspace.tsx b/components/dashboard/src/start/StartWorkspace.tsx index 22385f43e68f52..9797c643fbd229 100644 --- a/components/dashboard/src/start/StartWorkspace.tsx +++ b/components/dashboard/src/start/StartWorkspace.tsx @@ -27,6 +27,10 @@ export interface StartWorkspaceState { workspace?: Workspace; hasImageBuildLogs?: boolean; error?: StartWorkspaceError; + desktopIde?: { + link: string + label: string + } } export default class StartWorkspace extends React.Component { @@ -46,6 +50,10 @@ export default class StartWorkspace extends React.Component; } - phase = StartPhase.Running; - statusMessage =

Opening IDE …

; + if (!this.state.desktopIde) { + phase = StartPhase.Running; + statusMessage =

Opening IDE …

; + } else { + phase = StartPhase.IdeReady; + statusMessage =
+
+
 
+
+

{this.state.workspaceInstance.workspaceId}

+

{this.state.workspace?.contextURL}

+
+
+
+ + +
+
; + } + break; // Interrupted is an exceptional state where the container should be running but is temporarily unavailable. diff --git a/components/supervisor/frontend/src/ide/supervisor-service-client.ts b/components/supervisor/frontend/src/ide/supervisor-service-client.ts index 7233455bff0f87..2b5614731c77ac 100644 --- a/components/supervisor/frontend/src/ide/supervisor-service-client.ts +++ b/components/supervisor/frontend/src/ide/supervisor-service-client.ts @@ -20,7 +20,7 @@ export class SupervisorServiceClient { private readonly gitpodServiceClient: GitpodServiceClient ) { } - private async checkReady(kind: 'content' | 'ide' | 'supervisor', delay?: boolean): Promise { + private async checkReady(kind: 'content' | 'ide' | 'supervisor', delay?: boolean): Promise { if (delay) { await new Promise((resolve) => setTimeout(resolve, 1000)); } @@ -54,7 +54,7 @@ export class SupervisorServiceClient { return; } if (kind === 'ide' && (result as IDEStatusResponse.AsObject).ok) { - return; + return result; } } console.debug(`failed to check whether ${kind} is ready, trying again...`, response.status, response.statusText, JSON.stringify(result, undefined, 2)); diff --git a/components/supervisor/frontend/src/index.ts b/components/supervisor/frontend/src/index.ts index 1569325d0d3b77..9b75fe222b595e 100644 --- a/components/supervisor/frontend/src/index.ts +++ b/components/supervisor/frontend/src/index.ts @@ -30,6 +30,8 @@ IDEWebSocket.install(); const ideService = IDEFrontendService.create(); const pendingGitpodServiceClient = GitpodServiceClient.create(); const loadingIDE = new Promise(resolve => window.addEventListener('DOMContentLoaded', resolve, { once: true })); +const toStop = new DisposableCollection(); + (async () => { const gitpodServiceClient = await pendingGitpodServiceClient; @@ -53,21 +55,23 @@ const loadingIDE = new Promise(resolve => window.addEventListener('DOMContentLoa }); }); } - const supervisorServiceClinet = new SupervisorServiceClient(gitpodServiceClient); - await Promise.all([supervisorServiceClinet.ideReady, supervisorServiceClinet.contentReady, loadingIDE]); + const supervisorServiceClient = new SupervisorServiceClient(gitpodServiceClient); + const [ideStatus] = await Promise.all([supervisorServiceClient.ideReady, supervisorServiceClient.contentReady, loadingIDE]); if (isWorkspaceInstancePhase('stopping') || isWorkspaceInstancePhase('stopped')) { return; } - const toStop = new DisposableCollection(); toStop.pushAll([ IDEWebSocket.connectWorkspace(), - ideService.start(), gitpodServiceClient.onDidChangeInfo(() => { if (isWorkspaceInstancePhase('stopping') || isWorkspaceInstancePhase('stopped')) { toStop.dispose(); } }) ]); + const isDesktopIde = ideStatus && ideStatus.desktop && ideStatus.desktop.link; + if (!isDesktopIde) { + toStop.push(ideService.start()); + } //#endregion })(); @@ -83,14 +87,46 @@ const loadingIDE = new Promise(resolve => window.addEventListener('DOMContentLoa return; } + const supervisorServiceClient = new SupervisorServiceClient(gitpodServiceClient); + + let hideDesktopIde = false; + const serverOrigin = startUrl.url.origin; + const hideDesktopIdeEventListener = (event: MessageEvent) => { + if (event.origin === serverOrigin && event.data.type == 'openBrowserIde') { + window.removeEventListener('message', hideDesktopIdeEventListener); + hideDesktopIde = true; + toStop.push(ideService.start()); + } + } + window.addEventListener('message', hideDesktopIdeEventListener, false); + toStop.push({ dispose: () => window.removeEventListener('message', hideDesktopIdeEventListener) }); + + let isDesktopIde: undefined | boolean = undefined; + let ideStatus: undefined | { desktop: { link: string, label: string } } = undefined; + //#region current-frame let current: HTMLElement = loading.frame; let stopped = false; const nextFrame = () => { const instance = gitpodServiceClient.info.latestInstance; if (instance) { - if (instance.status.phase === 'running' && ideService.state === 'ready') { - return document.body; + if (instance.status.phase === 'running') { + if (!hideDesktopIde) { + if (isDesktopIde == undefined) { + return loading.frame; + } + if (isDesktopIde && !!ideStatus) { + loading.setState({ + desktopIdeLink: ideStatus.desktop.link, + desktopIdeLabel: ideStatus.desktop.label || "Open Desktop IDE" + }); + // window.open(ideStatus.desktop.link); + return loading.frame; + } + } + if (ideService.state === 'ready') { + return document.body; + } } if (instance.status.phase === 'stopped') { stopped = true; @@ -161,6 +197,11 @@ const loadingIDE = new Promise(resolve => window.addEventListener('DOMContentLoa updateCurrentFrame(); trackIDEStatusRenderedEvent(); }); + supervisorServiceClient.ideReady.then(newIdeStatus => { + ideStatus = newIdeStatus; + isDesktopIde = !!ideStatus && !!ideStatus.desktop && !!ideStatus.desktop.link; + updateCurrentFrame(); + }).catch(error => console.error(`Unexpected error from supervisorServiceClient.ideReady: ${error}`)); window.addEventListener('unload', () => trackStatusRenderedEvent('window-unload'), { capture: true }); //#endregion diff --git a/components/supervisor/frontend/src/shared/loading-frame.ts b/components/supervisor/frontend/src/shared/loading-frame.ts index 82a1fe416cd708..4de953253e9f71 100644 --- a/components/supervisor/frontend/src/shared/loading-frame.ts +++ b/components/supervisor/frontend/src/shared/loading-frame.ts @@ -22,13 +22,13 @@ window.addEventListener('message', relocateListener, false); let resolveSessionId: (sessionId: string) => void; const sessionId = new Promise(resolve => resolveSessionId = resolve); -const setSessinoIdListener = (event: MessageEvent) => { +const setSessionIdListener = (event: MessageEvent) => { if (event.origin === serverOrigin && event.data.type == '$setSessionId' && event.data.sessionId) { - window.removeEventListener('message', setSessinoIdListener); + window.removeEventListener('message', setSessionIdListener); resolveSessionId(event.data.sessionId); } }; -window.addEventListener('message', setSessinoIdListener, false); +window.addEventListener('message', setSessionIdListener, false); export function load({ gitpodService }: { gitpodService: ReturnType From 15e9f4b81310c14d47ee1a8f3089a38bdb6e472b Mon Sep 17 00:00:00 2001 From: "Cornelius A. Ludmann" Date: Mon, 25 Oct 2021 09:51:06 +0000 Subject: [PATCH 5/7] [ide] Add JetBrains IDE images --- .werft/build.ts | 3 +- .werft/build.yaml | 3 + chart/templates/server-ide-configmap.yaml | 17 +++- chart/values.yaml | 5 ++ components/BUILD.yaml | 3 +- .../ide/jetbrains/backend-plugin/.project | 2 +- .../ide/jetbrains/backend-plugin/BUILD.yaml | 3 + components/ide/jetbrains/image/BUILD.yaml | 52 ++++++++++++ .../ide/jetbrains/image/leeway.Dockerfile | 23 ++++++ components/ide/jetbrains/image/startup.sh | 16 ++++ components/ide/jetbrains/image/status/go.mod | 3 + components/ide/jetbrains/image/status/main.go | 81 +++++++++++++++++++ .../image/supervisor-ide-config_goland.json | 11 +++ .../image/supervisor-ide-config_intellij.json | 11 +++ 14 files changed, 229 insertions(+), 4 deletions(-) create mode 100644 components/ide/jetbrains/image/BUILD.yaml create mode 100644 components/ide/jetbrains/image/leeway.Dockerfile create mode 100755 components/ide/jetbrains/image/startup.sh create mode 100644 components/ide/jetbrains/image/status/go.mod create mode 100644 components/ide/jetbrains/image/status/main.go create mode 100644 components/ide/jetbrains/image/supervisor-ide-config_goland.json create mode 100644 components/ide/jetbrains/image/supervisor-ide-config_intellij.json diff --git a/.werft/build.ts b/.werft/build.ts index 478c27c3ac3176..310577e78634dc 100644 --- a/.werft/build.ts +++ b/.werft/build.ts @@ -148,7 +148,8 @@ export async function build(context, version) { if (withContrib || publishRelease) { exec(`leeway build --docker-build-options network=host --werft=true -c remote ${dontTest ? '--dont-test' : ''} -Dversion=${version} -DimageRepoBase=${imageRepo} contrib:all`); } - exec(`leeway build --docker-build-options network=host --werft=true -c remote ${retag} --coverage-output-path=${coverageOutput} -Dversion=${version} -DremoveSources=false -DimageRepoBase=${imageRepo} -DlocalAppVersion=${localAppVersion} -DnpmPublishTrigger=${publishToNpm ? Date.now() : 'false'}`); + const jetbrainsArgs = `-DINTELLIJ_PLUGIN_PLATFORM_VERSION=${process.env.INTELLIJ_PLUGIN_PLATFORM_VERSION} -DINTELLIJ_BACKEND_URL=${process.env.INTELLIJ_BACKEND_URL} -DGOLAND_BACKEND_URL=${process.env.GOLAND_BACKEND_URL}`; + exec(`leeway build --docker-build-options network=host --werft=true -c remote ${retag} --coverage-output-path=${coverageOutput} -Dversion=${version} -DremoveSources=false -DimageRepoBase=${imageRepo} -DlocalAppVersion=${localAppVersion} ${jetbrainsArgs} -DnpmPublishTrigger=${publishToNpm ? Date.now() : 'false'}`); if (publishRelease) { try { werft.phase("publish", "checking version semver compliance..."); diff --git a/.werft/build.yaml b/.werft/build.yaml index 49c58b9468ea2e..7f24c32c1048f3 100644 --- a/.werft/build.yaml +++ b/.werft/build.yaml @@ -138,6 +138,9 @@ pod: secretKeyRef: name: codecov key: token + envFrom: + - secretRef: + name: jetbrains-secrets command: - bash - -c diff --git a/chart/templates/server-ide-configmap.yaml b/chart/templates/server-ide-configmap.yaml index c5ede8825d6b21..6d7c905552156f 100644 --- a/chart/templates/server-ide-configmap.yaml +++ b/chart/templates/server-ide-configmap.yaml @@ -18,6 +18,20 @@ {{ template "gitpod.comp.imageRepo" . }}:{{- $comp.insidersVersion | default (include "gitpod.comp.version" .) -}} {{- end -}} +{{- define "ide-images-aliases"}} +{{- $ := .root -}} +{{- $gp := .gp -}} +code: {{ (include "stable-image-full" (dict "root" $ "gp" $gp "comp" $gp.components.workspace.codeImage)) }} +code-latest: {{ (include "insider-image-full" (dict "root" $ "gp" $gp "comp" $gp.components.workspace.codeImage)) }} +{{ end }} + +{{- define "desktop-ide-images-aliases"}} +{{- $ := .root -}} +{{- $gp := .gp -}} +intellij: {{ (include "gitpod.comp.imageFull" (dict "root" $ "gp" $gp "comp" $gp.components.workspace.desktopIdeImages.intellij)) }} +goland: {{ (include "gitpod.comp.imageFull" (dict "root" $ "gp" $gp "comp" $gp.components.workspace.desktopIdeImages.goland)) }} +{{ end }} + {{- if $comp.serverIdeConfigDeploy.enabled }} apiVersion: v1 kind: ConfigMap @@ -33,6 +47,7 @@ data: { "ideVersion": "{{ .Values.components.workspace.codeImage.stableVersion }}", "ideImageRepo": "{{ template "gitpod.comp.imageRepo" (dict "root" . "gp" $.Values "comp" .Values.components.workspace.codeImage) }}", - "ideImageAliases": {{ (dict "code-latest" (include "insider-image-full" (dict "root" . "gp" $.Values "comp" .Values.components.workspace.codeImage)) "code" (include "stable-image-full" (dict "root" . "gp" $.Values "comp" .Values.components.workspace.codeImage))) | toJson }} + "ideImageAliases": {{ (include "ide-images-aliases" (dict "root" . "gp" $.Values)) | fromYaml | toJson }}, + "desktopIdeImageAliases": {{ (include "desktop-ide-images-aliases" (dict "root" . "gp" $.Values)) | fromYaml | toJson }} } {{- end }} \ No newline at end of file diff --git a/chart/values.yaml b/chart/values.yaml index 9aa89a58efffe9..4d4cc6d338ae92 100644 --- a/chart/values.yaml +++ b/chart/values.yaml @@ -401,6 +401,11 @@ components: imageName: "ide/code" stableVersion: "commit-7107fb8bde0b1f92265402ad5fa09a51022b14dd" insidersVersion: "nightly" + desktopIdeImages: + intellij: + imageName: "ide/intellij" + goland: + imageName: "ide/goland" supervisor: imageName: "supervisor" dockerUp: diff --git a/components/BUILD.yaml b/components/BUILD.yaml index 19520e546e3b11..2c9129acaa6498 100644 --- a/components/BUILD.yaml +++ b/components/BUILD.yaml @@ -14,7 +14,6 @@ packages: - dev:all-app - installer:app - components/gitpod-protocol:all - - components/ide/jetbrains/backend-plugin:plugin - operations/observability/mixins:lint - name: docker-versions type: docker @@ -41,6 +40,8 @@ packages: - components/ee/ws-scheduler:docker - components/gitpod-db:docker - components/ide/code:docker + - components/ide/jetbrains/image:intellij + - components/ide/jetbrains/image:goland - components/ide/theia:docker - components/image-builder:docker - components/image-builder-mk3:docker diff --git a/components/ide/jetbrains/backend-plugin/.project b/components/ide/jetbrains/backend-plugin/.project index 955f47e5756f9c..13196d8ceedd00 100644 --- a/components/ide/jetbrains/backend-plugin/.project +++ b/components/ide/jetbrains/backend-plugin/.project @@ -22,7 +22,7 @@ - 1634286379907 + 0 30 diff --git a/components/ide/jetbrains/backend-plugin/BUILD.yaml b/components/ide/jetbrains/backend-plugin/BUILD.yaml index cd80adfbe4f42b..1925b6085b2bc1 100644 --- a/components/ide/jetbrains/backend-plugin/BUILD.yaml +++ b/components/ide/jetbrains/backend-plugin/BUILD.yaml @@ -11,8 +11,11 @@ packages: - "gradle/wrapper/*" - "gradlew" - "settings.gradle.kts" + argdeps: + - INTELLIJ_PLUGIN_PLATFORM_VERSION env: - JAVA_HOME=/home/gitpod/.sdkman/candidates/java/current + - INTELLIJ_PLUGIN_PLATFORM_VERSION=${INTELLIJ_PLUGIN_PLATFORM_VERSION} config: commands: - ["./gradlew", "-PsupervisorApiProjectPath=components-supervisor-api-java--lib/", "-PgitpodProtocolProjectPath=components-gitpod-protocol-java--lib/", "buildPlugin"] diff --git a/components/ide/jetbrains/image/BUILD.yaml b/components/ide/jetbrains/image/BUILD.yaml new file mode 100644 index 00000000000000..d298e609ae61b6 --- /dev/null +++ b/components/ide/jetbrains/image/BUILD.yaml @@ -0,0 +1,52 @@ +packages: + - name: docker + type: generic + argdeps: + - version + deps: + - :intellij + - :goland + - name: intellij + type: docker + srcs: + - "startup.sh" + - "supervisor-ide-config_intellij.json" + - "status/go.mod" + - "status/main.go" + deps: + - components/ide/jetbrains/backend-plugin:plugin + argdeps: + - imageRepoBase + - INTELLIJ_BACKEND_URL + config: + dockerfile: leeway.Dockerfile + metadata: + helm-component: workspace.desktopIdeImages.intellij + buildArgs: + JETBRAINS_BACKEND_URL: ${INTELLIJ_BACKEND_URL} + SUPERVISOR_IDE_CONFIG: supervisor-ide-config_intellij.json + image: + - ${imageRepoBase}/ide/intellij:${version} + - ${imageRepoBase}/ide/intellij:commit-${__git_commit} + - name: goland + type: docker + srcs: + - "startup.sh" + - "supervisor-ide-config_goland.json" + - "status/go.mod" + - "status/main.go" + deps: + - components/ide/jetbrains/backend-plugin:plugin + argdeps: + - imageRepoBase + - GOLAND_BACKEND_URL + config: + dockerfile: leeway.Dockerfile + metadata: + helm-component: workspace.desktopIdeImages.goland + buildArgs: + JETBRAINS_BACKEND_URL: ${GOLAND_BACKEND_URL} + SUPERVISOR_IDE_CONFIG: supervisor-ide-config_goland.json + image: + - ${imageRepoBase}/ide/goland:${version} + - ${imageRepoBase}/ide/goland:commit-${__git_commit} diff --git a/components/ide/jetbrains/image/leeway.Dockerfile b/components/ide/jetbrains/image/leeway.Dockerfile new file mode 100644 index 00000000000000..f7cd98c44f1e94 --- /dev/null +++ b/components/ide/jetbrains/image/leeway.Dockerfile @@ -0,0 +1,23 @@ +# Copyright (c) 2021 Gitpod GmbH. All rights reserved. +# Licensed under the GNU Affero General Public License (AGPL). +# See License-AGPL.txt in the project root for license information. + +FROM golang:1.17 AS build +WORKDIR /app +COPY status/* /app/ +RUN go build -o status + +FROM alpine:3.14 as download +ARG JETBRAINS_BACKEND_URL +WORKDIR /workdir +RUN apk add --no-cache --upgrade curl gzip tar unzip +RUN curl -sSLo backend.tar.gz "$JETBRAINS_BACKEND_URL" && tar -xf backend.tar.gz --strip-components=1 && rm backend.tar.gz +COPY --chown=33333:33333 components-ide-jetbrains-backend-plugin--plugin/build/distributions/jetbrains-backend-plugin-1.0-SNAPSHOT.zip /workdir +RUN unzip jetbrains-backend-plugin-1.0-SNAPSHOT.zip -d plugins/ && rm jetbrains-backend-plugin-1.0-SNAPSHOT.zip + +FROM scratch +ARG SUPERVISOR_IDE_CONFIG +COPY --chown=33333:33333 ${SUPERVISOR_IDE_CONFIG} /ide-desktop/supervisor-ide-config.json +COPY --chown=33333:33333 startup.sh /ide-desktop/ +COPY --chown=33333:33333 --from=build /app/status /ide-desktop/ +COPY --chown=33333:33333 --from=download /workdir/ /ide-desktop/backend/ diff --git a/components/ide/jetbrains/image/startup.sh b/components/ide/jetbrains/image/startup.sh new file mode 100755 index 00000000000000..014cf1906bb4ca --- /dev/null +++ b/components/ide/jetbrains/image/startup.sh @@ -0,0 +1,16 @@ +#!/bin/bash -li +# Copyright (c) 2021 Gitpod GmbH. All rights reserved. +# Licensed under the GNU Affero General Public License (AGPL). +# See License-AGPL.txt in the project root for license information. + +set -euo pipefail + +# kill background jobs when the script exits +trap "jobs -p | xargs -r kill" SIGINT SIGTERM EXIT + +/ide-desktop/status 24000 "$1" & + +export CWM_NON_INTERACTIVE=1 +export CWM_HOST_PASSWORD=gitpod +export CWM_HOST_STATUS_OVER_HTTP_TOKEN=gitpod +/ide-desktop/backend/bin/remote-dev-server.sh cwmHost "$GITPOD_REPO_ROOT" diff --git a/components/ide/jetbrains/image/status/go.mod b/components/ide/jetbrains/image/status/go.mod new file mode 100644 index 00000000000000..9f8e692f627b16 --- /dev/null +++ b/components/ide/jetbrains/image/status/go.mod @@ -0,0 +1,3 @@ +module github.com/gitpod-io/gitpod/jetbrains/status + +go 1.17 diff --git a/components/ide/jetbrains/image/status/main.go b/components/ide/jetbrains/image/status/main.go new file mode 100644 index 00000000000000..d99ff3cb06d06e --- /dev/null +++ b/components/ide/jetbrains/image/status/main.go @@ -0,0 +1,81 @@ +// Copyright (c) 2021 Gitpod GmbH. All rights reserved. +// Licensed under the GNU Affero General Public License (AGPL). +// See License-AGPL.txt in the project root for license information. + +package main + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "log" + "net/http" + "os" + "time" +) + +// proxy for the Code With Me status endpoints that transforms it into the supervisor status format. +func main() { + if len(os.Args) < 2 { + fmt.Printf("Usage: %s []\n", os.Args[0]) + os.Exit(1) + } + port := os.Args[1] + label := "Open JetBrains IDE" + if len(os.Args) > 2 { + label = os.Args[2] + } + + http.HandleFunc("/status", func(w http.ResponseWriter, r *http.Request) { + var ( + url = "http://localhost:63342/codeWithMe/unattendedHostStatus?token=gitpod" + client = http.Client{Timeout: 1 * time.Second} + ) + resp, err := client.Get(url) + if err != nil { + http.Error(w, err.Error(), http.StatusServiceUnavailable) + return + } + defer resp.Body.Close() + + bodyBytes, err := ioutil.ReadAll(resp.Body) + if err != nil { + http.Error(w, err.Error(), http.StatusServiceUnavailable) + return + } + + if resp.StatusCode != http.StatusOK { + // log.Printf("Desktop IDE status proxy: getting non-200 status - %d\n%s\n", resp.StatusCode, bodyBytes) + http.Error(w, string(bodyBytes), resp.StatusCode) + return + } + + type Projects struct { + JoinLink string `json:"joinLink"` + } + type Response struct { + Projects []Projects `json:"projects"` + } + jsonResp := &Response{} + err = json.Unmarshal(bodyBytes, &jsonResp) + + if err != nil { + http.Error(w, "Error parsing JSON body from IDE status probe.", http.StatusServiceUnavailable) + return + } + if len(jsonResp.Projects) != 1 { + http.Error(w, "projects size != 1", http.StatusServiceUnavailable) + return + } + response := make(map[string]string) + response["link"] = jsonResp.Projects[0].JoinLink + response["label"] = label + w.Header().Set("Content-Type", "application/json") + json.NewEncoder(w).Encode(response) + }) + + fmt.Printf("Starting status proxy for desktop IDE at port %s\n", port) + if err := http.ListenAndServe(fmt.Sprintf(":%s", port), nil); err != nil { + log.Fatal(err) + } +} diff --git a/components/ide/jetbrains/image/supervisor-ide-config_goland.json b/components/ide/jetbrains/image/supervisor-ide-config_goland.json new file mode 100644 index 00000000000000..7a6a95c21861d2 --- /dev/null +++ b/components/ide/jetbrains/image/supervisor-ide-config_goland.json @@ -0,0 +1,11 @@ +{ + "entrypoint": "/ide-desktop/startup.sh", + "entrypointArgs": [ "Open GoLand IDE" ], + "readinessProbe": { + "type": "http", + "http": { + "port": 24000, + "path": "/status" + } + } +} diff --git a/components/ide/jetbrains/image/supervisor-ide-config_intellij.json b/components/ide/jetbrains/image/supervisor-ide-config_intellij.json new file mode 100644 index 00000000000000..f33290e76702e2 --- /dev/null +++ b/components/ide/jetbrains/image/supervisor-ide-config_intellij.json @@ -0,0 +1,11 @@ +{ + "entrypoint": "/ide-desktop/startup.sh", + "entrypointArgs": [ "Open IntelliJ IDEA IDE" ], + "readinessProbe": { + "type": "http", + "http": { + "port": 24000, + "path": "/status" + } + } +} From 1d01b3dbc5cb81dbc195af108608ee7f278ad0b7 Mon Sep 17 00:00:00 2001 From: "Cornelius A. Ludmann" Date: Fri, 22 Oct 2021 15:37:35 +0000 Subject: [PATCH 6/7] [server] Add preferences to choose a desktop IDE --- .../dashboard/src/images/golandLogo.svg | 1 + .../dashboard/src/images/intellijIdeaLogo.svg | 1 + .../dashboard/src/settings/Preferences.tsx | 52 +++++++++++++++++++ components/gitpod-protocol/java/.project | 2 +- components/gitpod-protocol/src/protocol.ts | 2 + 5 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 components/dashboard/src/images/golandLogo.svg create mode 100644 components/dashboard/src/images/intellijIdeaLogo.svg diff --git a/components/dashboard/src/images/golandLogo.svg b/components/dashboard/src/images/golandLogo.svg new file mode 100644 index 00000000000000..3640b1d89f2782 --- /dev/null +++ b/components/dashboard/src/images/golandLogo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/components/dashboard/src/images/intellijIdeaLogo.svg b/components/dashboard/src/images/intellijIdeaLogo.svg new file mode 100644 index 00000000000000..04d5d6155d2153 --- /dev/null +++ b/components/dashboard/src/images/intellijIdeaLogo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/components/dashboard/src/settings/Preferences.tsx b/components/dashboard/src/settings/Preferences.tsx index eea22268d4615a..22f62667de4c41 100644 --- a/components/dashboard/src/settings/Preferences.tsx +++ b/components/dashboard/src/settings/Preferences.tsx @@ -5,10 +5,13 @@ */ import { useContext, useState } from "react"; +import CheckBox from "../components/CheckBox"; import { PageWithSubMenu } from "../components/PageWithSubMenu"; import SelectableCard from "../components/SelectableCard"; import Tooltip from "../components/Tooltip"; import vscode from '../images/vscode.svg'; +import ideaLogo from '../images/intellijIdeaLogo.svg'; +import golandLogo from '../images/golandLogo.svg'; import { getGitpodService } from "../service/service"; import { ThemeContext } from "../theme-context"; import { UserContext } from "../user-context"; @@ -19,6 +22,7 @@ type Theme = 'light' | 'dark' | 'system'; export default function Preferences() { const { user } = useContext(UserContext); const { setIsDark } = useContext(ThemeContext); + const [defaultIde, setDefaultIde] = useState(user?.additionalData?.ideSettings?.defaultIde || 'code'); const actuallySetDefaultIde = async (value: string) => { const additionalData = user?.additionalData || {}; @@ -28,6 +32,31 @@ export default function Preferences() { await getGitpodService().server.updateLoggedInUser({ additionalData }); setDefaultIde(value); } + + const desktopIdeFeatureEnabled = !!user?.rolesOrPermissions?.includes('admin'); + + const [defaultDesktopIde, setDefaultDesktopIde] = useState(user?.additionalData?.ideSettings?.defaultDesktopIde || 'intellij'); + const actuallySetDefaultDesktopIde = async (value: string) => { + const additionalData = user?.additionalData || {}; + const settings = additionalData.ideSettings || {}; + settings.defaultDesktopIde = value; + additionalData.ideSettings = settings; + await getGitpodService().server.updateLoggedInUser({ additionalData }); + setDefaultDesktopIde(value); + } + + const [useDesktopIde, setUseDesktopIde] = useState(user?.additionalData?.ideSettings?.useDesktopIde || false); + const actuallySetUseDesktopIde = async (value: boolean) => { + const additionalData = user?.additionalData || {}; + const settings = additionalData.ideSettings || {}; + settings.useDesktopIde = value; + // Make sure that default desktop IDE is set even when the user did not explicitly select one. + settings.defaultDesktopIde = defaultDesktopIde; + additionalData.ideSettings = settings; + await getGitpodService().server.updateLoggedInUser({ additionalData }); + setUseDesktopIde(value); + } + const [theme, setTheme] = useState(localStorage.theme || 'light'); const actuallySetTheme = (theme: Theme) => { if (theme === 'dark' || theme === 'system') { @@ -59,6 +88,29 @@ export default function Preferences() {
+ {desktopIdeFeatureEnabled && +
+ actuallySetUseDesktopIde(evt.target.checked)} /> +
+ } + {desktopIdeFeatureEnabled && useDesktopIde && +
+ actuallySetDefaultDesktopIde('intellij')}> +
+ +
+
+ actuallySetDefaultDesktopIde('goland')}> +
+ +
+
+
+ }

Theme

Early bird or night owl? Choose your side.

diff --git a/components/gitpod-protocol/java/.project b/components/gitpod-protocol/java/.project index 2a230d24c39ebb..9dd6734ca4aba8 100644 --- a/components/gitpod-protocol/java/.project +++ b/components/gitpod-protocol/java/.project @@ -22,7 +22,7 @@ - 1632232136569 + 0 30 diff --git a/components/gitpod-protocol/src/protocol.ts b/components/gitpod-protocol/src/protocol.ts index 7579e21f37e444..a9625d9ff7073a 100644 --- a/components/gitpod-protocol/src/protocol.ts +++ b/components/gitpod-protocol/src/protocol.ts @@ -114,6 +114,8 @@ export interface EmailNotificationSettings { export type IDESettings = { defaultIde?: string + useDesktopIde?: boolean + defaultDesktopIde?: string } export interface UserPlatform { From c9313751e09e5cc27c5b03ae4170968c3ef49b5f Mon Sep 17 00:00:00 2001 From: "Cornelius A. Ludmann" Date: Fri, 22 Oct 2021 15:51:36 +0000 Subject: [PATCH 7/7] [server] Pass selected desktop IDE to ws-manager --- .../gitpod-protocol/src/workspace-instance.ts | 3 +++ components/server/src/ide-config.ts | 12 ++++++++++-- .../server/src/workspace/workspace-starter.ts | 16 ++++++++++++++++ 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/components/gitpod-protocol/src/workspace-instance.ts b/components/gitpod-protocol/src/workspace-instance.ts index ff6440bb444e7d..9ed22626ae9d7b 100644 --- a/components/gitpod-protocol/src/workspace-instance.ts +++ b/components/gitpod-protocol/src/workspace-instance.ts @@ -212,4 +212,7 @@ export interface WorkspaceInstanceConfiguration { // ideImage is the ref of the IDE image this instance uses. ideImage: string; + + // desktopIdeImage is the ref of the desktop IDE image this instance uses. + desktopIdeImage?: string } diff --git a/components/server/src/ide-config.ts b/components/server/src/ide-config.ts index c033a1a9638969..7182e6d31cc7ee 100644 --- a/components/server/src/ide-config.ts +++ b/components/server/src/ide-config.ts @@ -17,6 +17,7 @@ interface RawIDEConfig { ideVersion: string; ideImageRepo: string; ideImageAliases?: { [index: string]: string }; + desktopIdeImageAliases?: { [index: string]: string }; } const scheme = { "type": "object", @@ -30,7 +31,11 @@ const scheme = { "ideImageAliases": { "type": "object", "additionalProperties": { "type": "string" } - } + }, + "desktopIdeImageAliases": { + "type": "object", + "additionalProperties": { "type": "string" } + }, }, "required": [ "ideVersion", @@ -42,7 +47,7 @@ export interface IDEConfig { ideVersion: string; ideImageRepo: string; ideImageAliases: { [index: string]: string }; - + desktopIdeImageAliases: { [index: string]: string }; ideImage: string; } @@ -112,6 +117,9 @@ export class IDEConfigService { ideImageAliases: { ...raw.ideImageAliases, "theia": ideImage, + }, + desktopIdeImageAliases: { + ...raw.desktopIdeImageAliases } } } diff --git a/components/server/src/workspace/workspace-starter.ts b/components/server/src/workspace/workspace-starter.ts index 4b3e7da148706c..03e0ebc3c07a22 100644 --- a/components/server/src/workspace/workspace-starter.ts +++ b/components/server/src/workspace/workspace-starter.ts @@ -323,6 +323,21 @@ export class WorkspaceStarter { } } + const useDesktopIdeChoice = user.additionalData?.ideSettings?.useDesktopIde || false; + if (useDesktopIdeChoice) { + const desktopIdeChoice = user.additionalData?.ideSettings?.defaultDesktopIde; + if (!!desktopIdeChoice) { + const mappedImage = ideConfig.desktopIdeImageAliases[desktopIdeChoice]; + if (!!mappedImage) { + configuration.desktopIdeImage = mappedImage; + } else if (this.authService.hasPermission(user, "ide-settings")) { + // if the IDE choice isn't one of the preconfiured choices, we assume its the image name. + // For now, this feature requires special permissions. + configuration.desktopIdeImage = desktopIdeChoice; + } + } + } + let featureFlags: NamedWorkspaceFeatureFlag[] = workspace.config._featureFlags || []; featureFlags = featureFlags.concat(this.config.workspaceDefaults.defaultFeatureFlags); if (user.featureFlags && user.featureFlags.permanentWSFeatureFlags) { @@ -724,6 +739,7 @@ export class WorkspaceStarter { spec.setPortsList(ports); spec.setInitializer((await initializerPromise).initializer); spec.setIdeImage(ideImage); + spec.setDesktopIdeImage(instance.configuration?.desktopIdeImage || ""); spec.setWorkspaceImage(instance.workspaceImage); spec.setWorkspaceLocation(workspace.config.workspaceLocation || spec.getCheckoutLocation()); spec.setFeatureFlagsList(this.toWorkspaceFeatureFlags(featureFlags));