diff --git a/components/common-go/experiments/configcat.go b/components/common-go/experiments/configcat.go index db66230a79e1af..7524ba5c6fa6e8 100644 --- a/components/common-go/experiments/configcat.go +++ b/components/common-go/experiments/configcat.go @@ -6,10 +6,8 @@ package experiments import ( "context" - "time" configcat "github.com/configcat/go-sdk/v7" - "github.com/gitpod-io/gitpod/common-go/log" "github.com/sirupsen/logrus" ) @@ -21,14 +19,9 @@ const ( vscodeClientIDAttribute = "vscode_client_id" ) -func newConfigCatClient(sdkKey string) *configCatClient { +func newConfigCatClient(config configcat.Config) *configCatClient { return &configCatClient{ - client: configcat.NewCustomClient(configcat.Config{ - SDKKey: sdkKey, - PollInterval: 3 * time.Minute, - HTTPTimeout: 3 * time.Second, - Logger: &configCatLogger{log.Log}, - }), + client: configcat.NewCustomClient(config), } } diff --git a/components/common-go/experiments/flags.go b/components/common-go/experiments/flags.go index 11d407399fdd91..a34b0c4bdd3e4c 100644 --- a/components/common-go/experiments/flags.go +++ b/components/common-go/experiments/flags.go @@ -7,8 +7,10 @@ package experiments import "context" const ( - PersonalAccessTokensEnabledFlag = "personalAccessTokensEnabled" - OIDCServiceEnabledFlag = "oidcServiceEnabled" + PersonalAccessTokensEnabledFlag = "personalAccessTokensEnabled" + OIDCServiceEnabledFlag = "oidcServiceEnabled" + SupervisorPersistServerAPIChannelWhenStartFlag = "supervisor_persist_serverapi_channel_when_start" + SupervisorUsePublicAPIFlag = "supervisor_experimental_publicapi" ) func IsPersonalAccessTokensEnabled(ctx context.Context, client Client, attributes Attributes) bool { @@ -18,3 +20,11 @@ func IsPersonalAccessTokensEnabled(ctx context.Context, client Client, attribute func IsOIDCServiceEnabled(ctx context.Context, client Client, attributes Attributes) bool { return client.GetBoolValue(ctx, OIDCServiceEnabledFlag, false, attributes) } + +func SupervisorPersistServerAPIChannelWhenStart(ctx context.Context, client Client, attributes Attributes) bool { + return client.GetBoolValue(ctx, SupervisorPersistServerAPIChannelWhenStartFlag, true, attributes) +} + +func SupervisorUsePublicAPI(ctx context.Context, client Client, attributes Attributes) bool { + return client.GetBoolValue(ctx, SupervisorUsePublicAPIFlag, false, attributes) +} diff --git a/components/common-go/experiments/types.go b/components/common-go/experiments/types.go index 9e7e5d85a83b6c..7d46dad7f7fa55 100644 --- a/components/common-go/experiments/types.go +++ b/components/common-go/experiments/types.go @@ -6,7 +6,12 @@ package experiments import ( "context" + "fmt" "os" + "time" + + configcat "github.com/configcat/go-sdk/v7" + "github.com/gitpod-io/gitpod/common-go/log" ) type Client interface { @@ -32,10 +37,23 @@ type Attributes struct { // If the environment contains CONFIGCAT_SDK_KEY value, it vill be used to construct a ConfigCat client. // Otherwise, it returns a client which always returns the default value. This client is used for Self-Hosted installations. func NewClient() Client { + gitpodHost := os.Getenv("GITPOD_HOST") + if gitpodHost != "" { + return newConfigCatClient(configcat.Config{ + SDKKey: "gitpod", + BaseURL: fmt.Sprintf("%s%s", gitpodHost, "/configcat"), + PollInterval: 1 * time.Minute, + HTTPTimeout: 3 * time.Second, + }) + } sdkKey := os.Getenv("CONFIGCAT_SDK_KEY") if sdkKey == "" { return NewAlwaysReturningDefaultValueClient() } - - return newConfigCatClient(sdkKey) + return newConfigCatClient(configcat.Config{ + SDKKey: sdkKey, + PollInterval: 3 * time.Minute, + HTTPTimeout: 3 * time.Second, + Logger: &configCatLogger{log.Log}, + }) } diff --git a/components/supervisor/BUILD.yaml b/components/supervisor/BUILD.yaml index 7f3bc5c9de719e..14268dc9a2b7cc 100644 --- a/components/supervisor/BUILD.yaml +++ b/components/supervisor/BUILD.yaml @@ -13,6 +13,7 @@ packages: - components/supervisor-api/go:lib - components/ws-daemon-api/go:lib - components/ide-metrics-api/go:lib + - components/public-api/go:lib env: - CGO_ENABLED=0 - GOOS=linux diff --git a/components/supervisor/go.mod b/components/supervisor/go.mod index 38a17463b9b319..f8b10b68454585 100644 --- a/components/supervisor/go.mod +++ b/components/supervisor/go.mod @@ -5,10 +5,11 @@ go 1.19 require ( github.com/Netflix/go-env v0.0.0-20220526054621-78278af1949d github.com/c9s/goprocinfo v0.0.0-20210130143923-c95fcf8c64a8 - github.com/cenkalti/backoff/v4 v4.1.3 + github.com/cenkalti/backoff/v4 v4.2.0 github.com/creack/pty v1.1.11 github.com/fsnotify/fsnotify v1.4.9 github.com/gitpod-io/gitpod/common-go v0.0.0-00010101000000-000000000000 + github.com/gitpod-io/gitpod/components/public-api/go v0.0.0-00010101000000-000000000000 github.com/gitpod-io/gitpod/content-service v0.0.0-00010101000000-000000000000 github.com/gitpod-io/gitpod/content-service/api v0.0.0-00010101000000-000000000000 github.com/gitpod-io/gitpod/gitpod-protocol v0.0.0-00010101000000-000000000000 @@ -16,7 +17,7 @@ require ( github.com/gitpod-io/gitpod/supervisor/api v0.0.0-00010101000000-000000000000 github.com/gitpod-io/gitpod/ws-daemon/api v0.0.0-00010101000000-000000000000 github.com/golang/mock v1.6.0 - github.com/google/go-cmp v0.5.8 + github.com/google/go-cmp v0.5.9 github.com/google/uuid v1.3.0 github.com/gorilla/websocket v1.5.0 github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 @@ -69,8 +70,10 @@ require ( github.com/aws/aws-sdk-go-v2/service/sts v1.17.5 // indirect github.com/aws/smithy-go v1.13.4 // indirect github.com/beorn7/perks v1.0.1 // indirect + github.com/blang/semver v3.5.1+incompatible // indirect github.com/cenkalti/backoff v2.2.1+incompatible // indirect github.com/cespare/xxhash/v2 v2.1.2 // indirect + github.com/configcat/go-sdk/v7 v7.6.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f // indirect github.com/dustin/go-humanize v1.0.0 // indirect @@ -133,6 +136,8 @@ replace github.com/gitpod-io/gitpod/common-go => ../common-go // leeway replace github.com/gitpod-io/gitpod/content-service => ../content-service // leeway +replace github.com/gitpod-io/gitpod/components/public-api/go => ../public-api/go // leeway + replace github.com/gitpod-io/gitpod/content-service/api => ../content-service-api/go // leeway replace github.com/gitpod-io/gitpod/gitpod-protocol => ../gitpod-protocol/go // leeway diff --git a/components/supervisor/go.sum b/components/supervisor/go.sum index 53777d1ed8d523..7b75b60dcfc2e5 100644 --- a/components/supervisor/go.sum +++ b/components/supervisor/go.sum @@ -116,13 +116,15 @@ github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24 github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ= +github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4YnC6+E63dPcxHo2sUxDIu8g3QgEJdRY= github.com/c9s/goprocinfo v0.0.0-20210130143923-c95fcf8c64a8 h1:SjZ2GvvOononHOpK84APFuMvxqsk3tEIaKH/z4Rpu3g= github.com/c9s/goprocinfo v0.0.0-20210130143923-c95fcf8c64a8/go.mod h1:uEyr4WpAH4hio6LFriaPkL938XnrvLpNPmQHBdrmbIE= github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= -github.com/cenkalti/backoff/v4 v4.1.3 h1:cFAlzYUlVYDysBEH2T5hyJZMh3+5+WCBvSnK6Q8UtC4= -github.com/cenkalti/backoff/v4 v4.1.3/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= +github.com/cenkalti/backoff/v4 v4.2.0 h1:HN5dHm3WBOgndBH6E8V0q2jIYIR3s9yglV8k/+MN3u4= +github.com/cenkalti/backoff/v4 v4.2.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= @@ -141,6 +143,8 @@ github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWH github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/configcat/go-sdk/v7 v7.6.0 h1:CthQJ7DMz4bvUrpc8aek6VouJjisCvZCfuTG2gyNzL4= +github.com/configcat/go-sdk/v7 v7.6.0/go.mod h1:2245V6Igy1Xz6GXvcYuK5z996Ct0VyzyuI470XS6aTw= github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.11 h1:07n33Z8lZxZ2qwegKbObQohDhXDQxiMMz1NOUGYlesw= github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= @@ -168,6 +172,8 @@ github.com/fatih/gomodifytags v1.14.0/go.mod h1:TbUyEjH1Zo0GkJd2Q52oVYqYcJ0eGNqG github.com/fatih/structtag v1.2.0 h1:/OdNE99OxoI/PqaW/SuSK9uxxT3f/tcSZgon/ssNSx4= github.com/fatih/structtag v1.2.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94= github.com/felixge/httpsnoop v1.0.2 h1:+nS9g82KMXccJ/wp0zyRW9ZBHFETmMGtkk+2CTTrW4o= +github.com/frankban/quicktest v1.11.2 h1:mjwHjStlXWibxOohM7HYieIViKyh56mmt3+6viyhDDI= +github.com/frankban/quicktest v1.11.2/go.mod h1:K+q6oSqb0W0Ininfk863uOk1lMy69l/P6txr3mVT54s= github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsouza/fake-gcs-server v1.37.11 h1:Of18n+AunBntGLiv7O96wzOuT8PBEt8CYXcJkc/ehsI= @@ -260,8 +266,9 @@ github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= -github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= @@ -352,8 +359,9 @@ github.com/klauspost/cpuid v1.3.1/go.mod h1:bYW4mA6ZgKPob1/Dlai2LviZJO7KGI3uoWLd github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= -github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= diff --git a/components/supervisor/pkg/metrics/reporter.go b/components/supervisor/pkg/metrics/reporter.go index 52af6e3695b9b7..d59faec39cdc23 100644 --- a/components/supervisor/pkg/metrics/reporter.go +++ b/components/supervisor/pkg/metrics/reporter.go @@ -41,6 +41,9 @@ func NewGrpcMetricsReporter(gitpodHost string) *GrpcMetricsReporter { "grpc_server_handling_seconds": true, "supervisor_ide_ready_duration_total": true, "supervisor_initializer_bytes_second": true, + "grpc_client_started_total": true, + "grpc_client_handled_total": true, + "grpc_client_handling_seconds": true, }, values: make(map[string]float64), addCounter: func(name string, labels map[string]string, value uint64) { diff --git a/components/supervisor/pkg/ports/exposed-ports.go b/components/supervisor/pkg/ports/exposed-ports.go index 295f8926f6b16d..9d01d1a9dd88b5 100644 --- a/components/supervisor/pkg/ports/exposed-ports.go +++ b/components/supervisor/pkg/ports/exposed-ports.go @@ -13,6 +13,7 @@ import ( backoff "github.com/cenkalti/backoff/v4" "github.com/gitpod-io/gitpod/common-go/log" gitpod "github.com/gitpod-io/gitpod/gitpod-protocol" + "github.com/gitpod-io/gitpod/supervisor/pkg/serverapi" ) // ExposedPort represents an exposed pprt @@ -59,10 +60,10 @@ func (*NoopExposedPorts) Expose(ctx context.Context, local uint32, public bool) // GitpodExposedPorts uses a connection to the Gitpod server to implement // the ExposedPortsInterface. type GitpodExposedPorts struct { - WorkspaceID string - InstanceID string - WorkspaceUrl string - C gitpod.APIInterface + WorkspaceID string + InstanceID string + WorkspaceUrl string + gitpodService serverapi.APIInterface localExposedPort []uint32 localExposedNotice chan struct{} @@ -78,12 +79,12 @@ type exposePortRequest struct { } // NewGitpodExposedPorts creates a new instance of GitpodExposedPorts -func NewGitpodExposedPorts(workspaceID string, instanceID string, workspaceUrl string, gitpodService gitpod.APIInterface) *GitpodExposedPorts { +func NewGitpodExposedPorts(workspaceID string, instanceID string, workspaceUrl string, gitpodService serverapi.APIInterface) *GitpodExposedPorts { return &GitpodExposedPorts{ - WorkspaceID: workspaceID, - InstanceID: instanceID, - WorkspaceUrl: workspaceUrl, - C: gitpodService, + WorkspaceID: workspaceID, + InstanceID: instanceID, + WorkspaceUrl: workspaceUrl, + gitpodService: gitpodService, // allow clients to submit 30 expose requests without blocking requests: make(chan *exposePortRequest, 30), @@ -120,7 +121,7 @@ func (g *GitpodExposedPorts) Observe(ctx context.Context) (<-chan []ExposedPort, defer close(reschan) defer close(errchan) - updates, err := g.C.InstanceUpdates(ctx, g.InstanceID) + updates, err := g.gitpodService.InstanceUpdates(ctx, g.InstanceID, g.WorkspaceID) if err != nil { errchan <- err return @@ -204,7 +205,7 @@ func (g *GitpodExposedPorts) doExpose(req *exposePortRequest) { exp.Reset() attempt := 0 for { - _, err = g.C.OpenPort(req.ctx, g.WorkspaceID, req.port) + _, err = g.gitpodService.OpenPort(req.ctx, g.WorkspaceID, req.port) if err == nil || req.ctx.Err() != nil || attempt == 5 { return } diff --git a/components/supervisor/pkg/ports/ports-config.go b/components/supervisor/pkg/ports/ports-config.go index c51190f9a72980..f88a7cadff9323 100644 --- a/components/supervisor/pkg/ports/ports-config.go +++ b/components/supervisor/pkg/ports/ports-config.go @@ -99,15 +99,13 @@ type ConfigInterace interface { type ConfigService struct { workspaceID string configService config.ConfigInterface - gitpodAPI gitpod.APIInterface } // NewConfigService creates a new instance of ConfigService. -func NewConfigService(workspaceID string, configService config.ConfigInterface, gitpodAPI gitpod.APIInterface) *ConfigService { +func NewConfigService(workspaceID string, configService config.ConfigInterface) *ConfigService { return &ConfigService{ workspaceID: workspaceID, configService: configService, - gitpodAPI: gitpodAPI, } } diff --git a/components/supervisor/pkg/ports/ports-config_test.go b/components/supervisor/pkg/ports/ports-config_test.go index 515b506db8b012..43fe8f34ec721c 100644 --- a/components/supervisor/pkg/ports/ports-config_test.go +++ b/components/supervisor/pkg/ports/ports-config_test.go @@ -94,9 +94,7 @@ func TestPortsConfig(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() - gitpodAPI := gitpod.NewMockAPIInterface(ctrl) - - service := NewConfigService(workspaceID, configService, gitpodAPI) + service := NewConfigService(workspaceID, configService) updates, errors := service.Observe(context) actual := &PortConfigTestExpectations{} diff --git a/components/supervisor/pkg/serverapi/publicapi.go b/components/supervisor/pkg/serverapi/publicapi.go new file mode 100644 index 00000000000000..1ff8372d7e0d3e --- /dev/null +++ b/components/supervisor/pkg/serverapi/publicapi.go @@ -0,0 +1,377 @@ +// Copyright (c) 2022 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 serverapi + +import ( + "context" + "crypto/tls" + "errors" + "fmt" + "reflect" + "time" + + backoff "github.com/cenkalti/backoff/v4" + "github.com/gitpod-io/gitpod/common-go/experiments" + "github.com/gitpod-io/gitpod/common-go/log" + v1 "github.com/gitpod-io/gitpod/components/public-api/go/experimental/v1" + gitpod "github.com/gitpod-io/gitpod/gitpod-protocol" + "github.com/gitpod-io/gitpod/supervisor/api" + grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware" + grpc_prometheus "github.com/grpc-ecosystem/go-grpc-prometheus" + "github.com/prometheus/client_golang/prometheus" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials" + "google.golang.org/grpc/metadata" +) + +type APIInterface interface { + GetOwnerID(ctx context.Context, workspaceID string) (ownerID string, err error) + GetToken(ctx context.Context, query *gitpod.GetTokenSearchOptions) (res *gitpod.Token, err error) + OpenPort(ctx context.Context, workspaceID string, port *gitpod.WorkspaceInstancePort) (res *gitpod.WorkspaceInstancePort, err error) + InstanceUpdates(ctx context.Context, instanceID string, workspaceID string) (<-chan *gitpod.WorkspaceInstance, error) + + // Remove this and use segment client directly + TrackEvent(ctx context.Context, event *gitpod.RemoteTrackMessage) (err error) + + // Metrics + RegisterMetrics(registry *prometheus.Registry) error +} + +const ( + // KindGitpod marks tokens that provide access to the Gitpod server API. + KindGitpod = "gitpod" +) + +var errNotConnected = errors.New("not connected to server/public api") + +type ServiceConfig struct { + Host string + Endpoint string + InstanceID string + WorkspaceID string + SupervisorVersion string +} + +type Service struct { + cfg *ServiceConfig + experiments experiments.Client + + token string + ownerID string + + lastServerInstance *gitpod.WorkspaceInstance + + // gitpodService server API + gitpodService gitpod.APIInterface + // publicAPIConn public API publicAPIConn + publicAPIConn *grpc.ClientConn + publicApiMetrics *grpc_prometheus.ClientMetrics + + previousUsingPublicAPI bool +} + +var _ APIInterface = (*Service)(nil) + +func NewServerApiService(ctx context.Context, cfg *ServiceConfig, tknsrv api.TokenServiceServer) *Service { + tknres, err := tknsrv.GetToken(context.Background(), &api.GetTokenRequest{ + Kind: KindGitpod, + Host: cfg.Host, + Scope: []string{ + "function:getToken", + "function:openPort", + "function:trackEvent", + "function:getWorkspace", + }, + }) + if err != nil { + log.WithError(err).Error("cannot get token for Gitpod API") + return nil + } + // server api + gitpodService, err := gitpod.ConnectToServer(cfg.Endpoint, gitpod.ConnectToServerOpts{ + Token: tknres.Token, + Log: log.Log, + ExtraHeaders: map[string]string{ + "User-Agent": "gitpod/supervisor", + "X-Workspace-Instance-Id": cfg.InstanceID, + "X-Client-Version": cfg.SupervisorVersion, + }, + }) + if err != nil { + log.WithError(err).Error("cannot connect to Gitpod API") + return nil + } + + service := &Service{ + token: tknres.Token, + gitpodService: gitpodService, + cfg: cfg, + experiments: experiments.NewClient(), + publicApiMetrics: grpc_prometheus.NewClientMetrics(), + } + + service.publicApiMetrics.EnableClientHandlingTimeHistogram( + // it should be aligned with https://github.com/gitpod-io/gitpod/blob/84ed1a0672d91446ba33cb7b504cfada769271a8/install/installer/pkg/components/ide-metrics/configmap.go#L315 + grpc_prometheus.WithHistogramBuckets([]float64{0.1, 0.2, 0.5, 1, 2, 5, 10}), + ) + + // public api + service.tryConnToPublicAPI() + // listen to server instance update + go service.listenInstanceUpdate(ctx, cfg.InstanceID) + + if wsInfo, err := gitpodService.GetWorkspace(ctx, cfg.WorkspaceID); err != nil { + log.WithError(err).Error("cannot get workspace info") + } else { + service.ownerID = wsInfo.Workspace.OwnerID + } + return service +} + +func (s *Service) tryConnToPublicAPI() { + endpoint := fmt.Sprintf("api.%s:443", s.cfg.Host) + log.WithField("endpoint", endpoint).Info("connecting to PublicAPI...") + opts := []grpc.DialOption{ + grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{MinVersion: tls.VersionTLS13})), + grpc.WithUnaryInterceptor(grpc_middleware.ChainUnaryClient([]grpc.UnaryClientInterceptor{ + s.publicApiMetrics.UnaryClientInterceptor(), + func(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error { + withAuth := metadata.AppendToOutgoingContext(ctx, "authorization", "Bearer "+s.token) + return invoker(withAuth, method, req, reply, cc, opts...) + }, + }...)), + } + if conn, err := grpc.Dial(endpoint, opts...); err != nil { + log.WithError(err).Errorf("failed to dial public api %s", endpoint) + } else { + s.publicAPIConn = conn + } +} + +func (s *Service) persistServerAPIChannelWhenStart(ctx context.Context) bool { + if s.publicAPIConn == nil || s.ownerID == "" { + return true + } + return experiments.SupervisorPersistServerAPIChannelWhenStart(ctx, s.experiments, experiments.Attributes{ + UserID: s.ownerID, + }) +} + +func (s *Service) usePublicAPI(ctx context.Context) bool { + if s.publicAPIConn == nil || s.ownerID == "" { + return false + } + usePublicAPI := experiments.SupervisorUsePublicAPI(ctx, s.experiments, experiments.Attributes{ + UserID: s.ownerID, + }) + if usePublicAPI != s.previousUsingPublicAPI { + if usePublicAPI { + log.Info("switch to use PublicAPI") + } else { + log.Info("switch to use ServerAPI") + } + s.previousUsingPublicAPI = usePublicAPI + } + return usePublicAPI +} + +// GetToken implements protocol.APIInterface +func (s *Service) GetToken(ctx context.Context, query *gitpod.GetTokenSearchOptions) (res *gitpod.Token, err error) { + if s == nil { + return nil, errNotConnected + } + if !s.usePublicAPI(ctx) { + return s.gitpodService.GetToken(ctx, query) + } + + service := v1.NewUserServiceClient(s.publicAPIConn) + resp, err := service.GetGitToken(ctx, &v1.GetGitTokenRequest{ + Host: query.Host, + }) + if err != nil { + log.WithField("method", "GetGitToken").WithError(err).Error("failed to call PublicAPI") + return nil, err + } + return &gitpod.Token{ + ExpiryDate: resp.Token.ExpiryDate, + IDToken: resp.Token.IdToken, + RefreshToken: resp.Token.RefreshToken, + Scopes: resp.Token.Scopes, + UpdateDate: resp.Token.UpdateDate, + Username: resp.Token.Username, + Value: resp.Token.Value, + }, nil +} + +// OpenPort implements protocol.APIInterface +func (s *Service) OpenPort(ctx context.Context, workspaceID string, port *gitpod.WorkspaceInstancePort) (res *gitpod.WorkspaceInstancePort, err error) { + if s == nil { + return nil, errNotConnected + } + if !s.usePublicAPI(ctx) { + return s.gitpodService.OpenPort(ctx, workspaceID, port) + } + service := v1.NewWorkspacesServiceClient(s.publicAPIConn) + + payload := &v1.UpdatePortRequest{ + WorkspaceId: workspaceID, + Port: &v1.PortSpec{ + Port: uint64(port.Port), + }, + } + if port.Visibility == gitpod.PortVisibilityPublic { + payload.Port.Policy = v1.PortPolicy_PORT_POLICY_PUBLIC + } else { + payload.Port.Policy = v1.PortPolicy_PORT_POLICY_PRIVATE + } + _, err = service.UpdatePort(ctx, payload) + if err != nil { + log.WithField("method", "UpdatePort").WithError(err).Error("failed to call PublicAPI") + return nil, err + } + // server don't respond anything + // see https://github.com/gitpod-io/gitpod/blob/2967579c330de67090d975661a6e3e1cd970ab68/components/server/src/workspace/gitpod-server-impl.ts#L1521 + return port, nil +} + +func (s *Service) listenInstanceUpdate(ctx context.Context, instanceID string) { + for { + uptChan, err := backoff.RetryWithData( + func() (<-chan *gitpod.WorkspaceInstance, error) { + return s.gitpodService.InstanceUpdates(ctx, instanceID) + }, + backoff.NewExponentialBackOff(), + ) + if err != nil { + log.WithError(err).Error("failed to get workspace instance chan several retries") + continue + } + for { + select { + case <-ctx.Done(): + return + case instance := <-uptChan: + s.lastServerInstance = instance + } + } + } +} + +func (s *Service) getWorkspaceInfo(ctx context.Context, instanceID, workspaceID string) (*gitpod.WorkspaceInstance, error) { + getData := func() (*gitpod.WorkspaceInstance, error) { + if !s.usePublicAPI(ctx) { + return s.lastServerInstance, nil + } + service := v1.NewWorkspacesServiceClient(s.publicAPIConn) + resp, err := service.GetWorkspace(ctx, &v1.GetWorkspaceRequest{ + WorkspaceId: workspaceID, + }) + if err != nil { + log.WithField("method", "GetWorkspace").WithError(err).Error("failed to call PublicAPI") + return nil, err + } + instance := &gitpod.WorkspaceInstance{ + CreationTime: resp.Result.Status.Instance.CreatedAt.String(), + ID: resp.Result.Status.Instance.InstanceId, + Status: &gitpod.WorkspaceInstanceStatus{ + ExposedPorts: []*gitpod.WorkspaceInstancePort{}, + Message: resp.Result.Status.Instance.Status.Message, + // OwnerToken: "", not used so ignore + Phase: resp.Result.Status.Instance.Status.Phase.String(), + Timeout: resp.Result.Status.Instance.Status.Conditions.Timeout, + Version: int(resp.Result.Status.Instance.Status.StatusVersion), + }, + WorkspaceID: resp.Result.WorkspaceId, + } + for _, port := range resp.Result.Status.Instance.Status.Ports { + info := &gitpod.WorkspaceInstancePort{ + Port: float64(port.Port), + URL: port.Url, + } + if port.Policy == v1.PortPolicy_PORT_POLICY_PUBLIC { + info.Visibility = gitpod.PortVisibilityPublic + } else { + info.Visibility = gitpod.PortVisibilityPrivate + } + instance.Status.ExposedPorts = append(instance.Status.ExposedPorts, info) + } + return instance, nil + } + exp := &backoff.ExponentialBackOff{ + InitialInterval: 2 * time.Second, + RandomizationFactor: 0.5, + Multiplier: 1.5, + MaxInterval: 30 * time.Second, + MaxElapsedTime: 0, + Stop: backoff.Stop, + Clock: backoff.SystemClock, + } + return backoff.RetryWithData(getData, exp) +} + +// InstanceUpdates implements protocol.APIInterface +func (s *Service) InstanceUpdates(ctx context.Context, instanceID string, workspaceID string) (<-chan *gitpod.WorkspaceInstance, error) { + if s == nil { + return nil, errNotConnected + } + if !s.usePublicAPI(ctx) && s.persistServerAPIChannelWhenStart(ctx) { + return s.gitpodService.InstanceUpdates(ctx, instanceID) + } + updateChan := make(chan *gitpod.WorkspaceInstance) + var latestInstance *gitpod.WorkspaceInstance + go func() { + for { + if ctx.Err() != nil { + close(updateChan) + break + } + if instance, err := s.getWorkspaceInfo(ctx, instanceID, workspaceID); err == nil { + if reflect.DeepEqual(latestInstance, instance) { + continue + } + latestInstance = instance + updateChan <- instance + } + time.Sleep(1 * time.Second) + } + }() + return updateChan, nil +} + +// GetOwnerID implements APIInterface +func (s *Service) GetOwnerID(ctx context.Context, workspaceID string) (ownerID string, err error) { + if s == nil { + return "", errNotConnected + } + if !s.usePublicAPI(ctx) { + resp, err := s.gitpodService.GetWorkspace(ctx, workspaceID) + if err != nil { + return "", err + } + return resp.Workspace.OwnerID, nil + } + service := v1.NewWorkspacesServiceClient(s.publicAPIConn) + resp, err := service.GetWorkspace(ctx, &v1.GetWorkspaceRequest{ + WorkspaceId: workspaceID, + }) + if err != nil { + return "", err + } + return resp.Result.OwnerId, nil +} + +func (s *Service) TrackEvent(ctx context.Context, event *gitpod.RemoteTrackMessage) (err error) { + if s == nil { + return errNotConnected + } + return s.gitpodService.TrackEvent(ctx, event) +} + +func (s *Service) RegisterMetrics(registry *prometheus.Registry) error { + if s == nil { + return errNotConnected + } + return registry.Register(s.publicApiMetrics) +} diff --git a/components/supervisor/pkg/supervisor/git.go b/components/supervisor/pkg/supervisor/git.go index ed8aa81589634f..ef0af31fbda9c1 100644 --- a/components/supervisor/pkg/supervisor/git.go +++ b/components/supervisor/pkg/supervisor/git.go @@ -12,6 +12,7 @@ import ( gitpod "github.com/gitpod-io/gitpod/gitpod-protocol" "github.com/gitpod-io/gitpod/supervisor/api" + "github.com/gitpod-io/gitpod/supervisor/pkg/serverapi" ) // GitTokenProvider provides tokens for Git hosting services by asking @@ -19,11 +20,11 @@ import ( type GitTokenProvider struct { notificationService *NotificationService workspaceConfig WorkspaceConfig - gitpodAPI gitpod.APIInterface + gitpodAPI serverapi.APIInterface } // NewGitTokenProvider creates a new instance of gitTokenProvider. -func NewGitTokenProvider(gitpodAPI gitpod.APIInterface, workspaceConfig WorkspaceConfig, notificationService *NotificationService) *GitTokenProvider { +func NewGitTokenProvider(gitpodAPI serverapi.APIInterface, workspaceConfig WorkspaceConfig, notificationService *NotificationService) *GitTokenProvider { return &GitTokenProvider{ notificationService: notificationService, workspaceConfig: workspaceConfig, diff --git a/components/supervisor/pkg/supervisor/supervisor.go b/components/supervisor/pkg/supervisor/supervisor.go index d4b69585385527..ae8da2df63dbbe 100644 --- a/components/supervisor/pkg/supervisor/supervisor.go +++ b/components/supervisor/pkg/supervisor/supervisor.go @@ -24,6 +24,7 @@ import ( "os/signal" "path/filepath" "runtime" + "runtime/debug" "strconv" "strings" "sync" @@ -56,6 +57,7 @@ import ( "github.com/gitpod-io/gitpod/supervisor/pkg/dropwriter" "github.com/gitpod-io/gitpod/supervisor/pkg/metrics" "github.com/gitpod-io/gitpod/supervisor/pkg/ports" + "github.com/gitpod-io/gitpod/supervisor/pkg/serverapi" "github.com/gitpod-io/gitpod/supervisor/pkg/terminal" "github.com/prometheus/client_golang/prometheus" @@ -118,9 +120,6 @@ const ( ) const ( - // KindGitpod marks tokens that provide access to the Gitpod server API. - KindGitpod = "gitpod" - // KindGit marks any kind of Git access token. KindGit = "git" ) @@ -153,6 +152,16 @@ func (s IDEKind) String() string { func Run(options ...RunOption) { exitCode := 0 defer handleExit(&exitCode) + defer func() { + r := recover() + if r == nil { + return + } + log.WithField("cause", r).WithField("stack", string(debug.Stack())).Error("panicked") + if exitCode == 0 { + exitCode = 1 + } + }() opts := runOptions{ Args: os.Args, @@ -220,12 +229,22 @@ func Run(options ...RunOption) { internalPorts = append(internalPorts, desktopIDEPort) } + endpoint, host, err := cfg.GitpodAPIEndpoint() + if err != nil { + log.WithError(err).Fatal("cannot find Gitpod API endpoint") + } var ( ideReady = &ideReadyState{cond: sync.NewCond(&sync.Mutex{})} desktopIdeReady *ideReadyState = nil cstate = NewInMemoryContentState(cfg.RepoRoot) - gitpodService = createGitpodService(cfg, tokenService) + gitpodService = serverapi.NewServerApiService(ctx, &serverapi.ServiceConfig{ + Host: host, + Endpoint: endpoint, + InstanceID: cfg.WorkspaceInstanceID, + WorkspaceID: cfg.WorkspaceID, + SupervisorVersion: Version, + }, tokenService) notificationService = NewNotificationService() ) @@ -245,7 +264,7 @@ func Run(options ...RunOption) { &ports.PollingServedPortsObserver{ RefreshInterval: 2 * time.Second, }, - ports.NewConfigService(cfg.WorkspaceID, gitpodConfigService, gitpodService), + ports.NewConfigService(cfg.WorkspaceID, gitpodConfigService), tunneledPortsService, internalPorts..., ) @@ -263,10 +282,15 @@ func Run(options ...RunOption) { } _, gitpodHost, err := cfg.GitpodAPIEndpoint() if err != nil { - log.WithError(err).Error("supervisor: grpc metrics: failed to parse gitpod host") + log.WithError(err).Error("grpc metrics: failed to parse gitpod host") } else { metricsReporter = metrics.NewGrpcMetricsReporter(gitpodHost) - supervisorMetrics.Register(metricsReporter.Registry) + if err := supervisorMetrics.Register(metricsReporter.Registry); err != nil { + log.WithError(err).Error("could not register supervisor metrics") + } + if err := gitpodService.RegisterMetrics(metricsReporter.Registry); err != nil { + log.WithError(err).Error("could not register public api metrics") + } } } @@ -602,44 +626,7 @@ func installDotfiles(ctx context.Context, cfg *Config, tokenService *InMemoryTok } } -func createGitpodService(cfg *Config, tknsrv api.TokenServiceServer) *gitpod.APIoverJSONRPC { - endpoint, host, err := cfg.GitpodAPIEndpoint() - if err != nil { - log.WithError(err).Fatal("cannot find Gitpod API endpoint") - return nil - } - tknres, err := tknsrv.GetToken(context.Background(), &api.GetTokenRequest{ - Kind: KindGitpod, - Host: host, - Scope: []string{ - "function:getToken", - "function:openPort", - "function:getOpenPorts", - "function:guessGitTokenScopes", - }, - }) - if err != nil { - log.WithError(err).Error("cannot get token for Gitpod API") - return nil - } - - gitpodService, err := gitpod.ConnectToServer(endpoint, gitpod.ConnectToServerOpts{ - Token: tknres.Token, - Log: log.Log, - ExtraHeaders: map[string]string{ - "User-Agent": "gitpod/supervisor", - "X-Workspace-Instance-Id": cfg.WorkspaceInstanceID, - "X-Client-Version": Version, - }, - }) - if err != nil { - log.WithError(err).Error("cannot connect to Gitpod API") - return nil - } - return gitpodService -} - -func createExposedPortsImpl(cfg *Config, gitpodService *gitpod.APIoverJSONRPC) ports.ExposedPortsInterface { +func createExposedPortsImpl(cfg *Config, gitpodService serverapi.APIInterface) ports.ExposedPortsInterface { if gitpodService == nil { log.Error("auto-port exposure won't work") return &ports.NoopExposedPorts{} @@ -1524,7 +1511,7 @@ func socketActivationForDocker(ctx context.Context, wg *sync.WaitGroup, term *te } } -func startAnalyze(ctx context.Context, cfg *Config, gitpodConfigService config.ConfigInterface, topService *TopService, gitpodService gitpod.APIInterface) { +func startAnalyze(ctx context.Context, cfg *Config, gitpodConfigService config.ConfigInterface, topService *TopService, gitpodService serverapi.APIInterface) { analytics := analytics.NewFromEnvironment() go analyseConfigChanges(ctx, cfg, analytics, gitpodConfigService, gitpodService) go analysePerfChanges(ctx, cfg, analytics, topService, gitpodService) @@ -1553,8 +1540,8 @@ func (a *PerfAnalyzer) analyze(used float64) bool { return true } -func analysePerfChanges(ctx context.Context, wscfg *Config, w analytics.Writer, topService *TopService, gitpodAPI gitpod.APIInterface) { - info, err := gitpodAPI.GetWorkspace(ctx, wscfg.WorkspaceID) +func analysePerfChanges(ctx context.Context, wscfg *Config, w analytics.Writer, topService *TopService, gitpodAPI serverapi.APIInterface) { + ownerID, err := gitpodAPI.GetOwnerID(ctx, wscfg.WorkspaceID) if err != nil { log.WithError(err).Error("gitpod perf analytics: failed to resolve workspace info") return @@ -1566,7 +1553,7 @@ func analysePerfChanges(ctx context.Context, wscfg *Config, w analytics.Writer, } log.WithField("buckets", analyzer.buckets).WithField("used", used).WithField("label", analyzer.label).Debug("gitpod perf analytics: changed") w.Track(analytics.TrackMessage{ - Identity: analytics.Identity{UserID: info.Workspace.OwnerID}, + Identity: analytics.Identity{UserID: ownerID}, Event: "gitpod_" + analyzer.label + "_changed", Properties: map[string]interface{}{ "used": used, @@ -1595,8 +1582,8 @@ func analysePerfChanges(ctx context.Context, wscfg *Config, w analytics.Writer, } } -func analyseConfigChanges(ctx context.Context, wscfg *Config, w analytics.Writer, cfgobs config.ConfigInterface, gitpodAPI gitpod.APIInterface) { - info, err := gitpodAPI.GetWorkspace(ctx, wscfg.WorkspaceID) +func analyseConfigChanges(ctx context.Context, wscfg *Config, w analytics.Writer, cfgobs config.ConfigInterface, gitpodAPI serverapi.APIInterface) { + ownerID, err := gitpodAPI.GetOwnerID(ctx, wscfg.WorkspaceID) if err != nil { log.WithError(err).Error("gitpod config analytics: failed to resolve workspace info") return @@ -1617,7 +1604,7 @@ func analyseConfigChanges(ctx context.Context, wscfg *Config, w analytics.Writer } else { analyzer = config.NewConfigAnalyzer(log.Log, 5*time.Second, func(field string) { w.Track(analytics.TrackMessage{ - Identity: analytics.Identity{UserID: info.Workspace.OwnerID}, + Identity: analytics.Identity{UserID: ownerID}, Event: "gitpod_config_changed", Properties: map[string]interface{}{ "key": field, @@ -1634,14 +1621,14 @@ func analyseConfigChanges(ctx context.Context, wscfg *Config, w analytics.Writer } } -func trackReadiness(ctx context.Context, gitpodService *gitpod.APIoverJSONRPC, cfg *Config, cstate *InMemoryContentState, ideReady *ideReadyState, desktopIdeReady *ideReadyState) { +func trackReadiness(ctx context.Context, gitpodService serverapi.APIInterface, cfg *Config, cstate *InMemoryContentState, ideReady *ideReadyState, desktopIdeReady *ideReadyState) { type SupervisorReadiness struct { Kind string `json:"kind,omitempty"` WorkspaceId string `json:"workspaceId,omitempty"` WorkspaceInstanceId string `json:"instanceId,omitempty"` Timestamp int64 `json:"timestamp,omitempty"` } - trackFn := func(ctx context.Context, gitpodService *gitpod.APIoverJSONRPC, cfg *Config, kind string) { + trackFn := func(ctx context.Context, gitpodService serverapi.APIInterface, cfg *Config, kind string) { err := gitpodService.TrackEvent(ctx, &gitpod.RemoteTrackMessage{ Event: "supervisor_readiness", Properties: SupervisorReadiness{ diff --git a/install/installer/cmd/testdata/render/aws-setup/output.golden b/install/installer/cmd/testdata/render/aws-setup/output.golden index 532f0920295779..a66bea8b112d33 100644 --- a/install/installer/cmd/testdata/render/aws-setup/output.golden +++ b/install/installer/cmd/testdata/render/aws-setup/output.golden @@ -4399,6 +4399,67 @@ data: "defaultValue": "" } ] + }, + { + "name": "grpc_client_started_total", + "help": "Total number of RPCs started on the client.", + "labels": [ + { + "name": "grpc_method", + "allowValues": [ + "*" + ], + "defaultValue": "" + }, + { + "name": "grpc_service", + "allowValues": [ + "*" + ], + "defaultValue": "" + }, + { + "name": "grpc_type", + "allowValues": [ + "*" + ], + "defaultValue": "" + } + ] + }, + { + "name": "grpc_client_handled_total", + "help": "Total number of RPCs completed by the client, regardless of success or failure.", + "labels": [ + { + "name": "grpc_method", + "allowValues": [ + "*" + ], + "defaultValue": "" + }, + { + "name": "grpc_service", + "allowValues": [ + "*" + ], + "defaultValue": "" + }, + { + "name": "grpc_type", + "allowValues": [ + "*" + ], + "defaultValue": "" + }, + { + "name": "grpc_code", + "allowValues": [ + "*" + ], + "defaultValue": "" + } + ] } ], "histogramMetrics": [ @@ -4550,6 +4611,42 @@ data: 1073741824, 2147483648 ] + }, + { + "name": "grpc_client_handling_seconds", + "help": "Histogram of response latency (seconds) of the gRPC until it is finished by the application.", + "labels": [ + { + "name": "grpc_type", + "allowValues": [ + "*" + ], + "defaultValue": "" + }, + { + "name": "grpc_service", + "allowValues": [ + "*" + ], + "defaultValue": "" + }, + { + "name": "grpc_method", + "allowValues": [ + "*" + ], + "defaultValue": "" + } + ], + "buckets": [ + 0.1, + 0.2, + 0.5, + 1, + 2, + 5, + 10 + ] } ], "errorReporting": { @@ -8770,7 +8867,7 @@ spec: template: metadata: annotations: - gitpod.io/checksum_config: cc52e275885690e10f10dac466a0ffd1e4a4551efa2ee5dcbb5c4c824d987f95 + gitpod.io/checksum_config: d42da55c46ab5e8278c46a30a13e4f2c614ad4f340863a57c91fc6183a1068fc creationTimestamp: null labels: app: gitpod diff --git a/install/installer/cmd/testdata/render/azure-setup/output.golden b/install/installer/cmd/testdata/render/azure-setup/output.golden index ff92caafe7d93b..60150b27abdc5d 100644 --- a/install/installer/cmd/testdata/render/azure-setup/output.golden +++ b/install/installer/cmd/testdata/render/azure-setup/output.golden @@ -4314,6 +4314,67 @@ data: "defaultValue": "" } ] + }, + { + "name": "grpc_client_started_total", + "help": "Total number of RPCs started on the client.", + "labels": [ + { + "name": "grpc_method", + "allowValues": [ + "*" + ], + "defaultValue": "" + }, + { + "name": "grpc_service", + "allowValues": [ + "*" + ], + "defaultValue": "" + }, + { + "name": "grpc_type", + "allowValues": [ + "*" + ], + "defaultValue": "" + } + ] + }, + { + "name": "grpc_client_handled_total", + "help": "Total number of RPCs completed by the client, regardless of success or failure.", + "labels": [ + { + "name": "grpc_method", + "allowValues": [ + "*" + ], + "defaultValue": "" + }, + { + "name": "grpc_service", + "allowValues": [ + "*" + ], + "defaultValue": "" + }, + { + "name": "grpc_type", + "allowValues": [ + "*" + ], + "defaultValue": "" + }, + { + "name": "grpc_code", + "allowValues": [ + "*" + ], + "defaultValue": "" + } + ] } ], "histogramMetrics": [ @@ -4465,6 +4526,42 @@ data: 1073741824, 2147483648 ] + }, + { + "name": "grpc_client_handling_seconds", + "help": "Histogram of response latency (seconds) of the gRPC until it is finished by the application.", + "labels": [ + { + "name": "grpc_type", + "allowValues": [ + "*" + ], + "defaultValue": "" + }, + { + "name": "grpc_service", + "allowValues": [ + "*" + ], + "defaultValue": "" + }, + { + "name": "grpc_method", + "allowValues": [ + "*" + ], + "defaultValue": "" + } + ], + "buckets": [ + 0.1, + 0.2, + 0.5, + 1, + 2, + 5, + 10 + ] } ], "errorReporting": { @@ -8597,7 +8694,7 @@ spec: template: metadata: annotations: - gitpod.io/checksum_config: cc52e275885690e10f10dac466a0ffd1e4a4551efa2ee5dcbb5c4c824d987f95 + gitpod.io/checksum_config: d42da55c46ab5e8278c46a30a13e4f2c614ad4f340863a57c91fc6183a1068fc creationTimestamp: null labels: app: gitpod diff --git a/install/installer/cmd/testdata/render/customization/output.golden b/install/installer/cmd/testdata/render/customization/output.golden index 21edc907631bc8..f6aba9384be4b5 100644 --- a/install/installer/cmd/testdata/render/customization/output.golden +++ b/install/installer/cmd/testdata/render/customization/output.golden @@ -5184,6 +5184,67 @@ data: "defaultValue": "" } ] + }, + { + "name": "grpc_client_started_total", + "help": "Total number of RPCs started on the client.", + "labels": [ + { + "name": "grpc_method", + "allowValues": [ + "*" + ], + "defaultValue": "" + }, + { + "name": "grpc_service", + "allowValues": [ + "*" + ], + "defaultValue": "" + }, + { + "name": "grpc_type", + "allowValues": [ + "*" + ], + "defaultValue": "" + } + ] + }, + { + "name": "grpc_client_handled_total", + "help": "Total number of RPCs completed by the client, regardless of success or failure.", + "labels": [ + { + "name": "grpc_method", + "allowValues": [ + "*" + ], + "defaultValue": "" + }, + { + "name": "grpc_service", + "allowValues": [ + "*" + ], + "defaultValue": "" + }, + { + "name": "grpc_type", + "allowValues": [ + "*" + ], + "defaultValue": "" + }, + { + "name": "grpc_code", + "allowValues": [ + "*" + ], + "defaultValue": "" + } + ] } ], "histogramMetrics": [ @@ -5335,6 +5396,42 @@ data: 1073741824, 2147483648 ] + }, + { + "name": "grpc_client_handling_seconds", + "help": "Histogram of response latency (seconds) of the gRPC until it is finished by the application.", + "labels": [ + { + "name": "grpc_type", + "allowValues": [ + "*" + ], + "defaultValue": "" + }, + { + "name": "grpc_service", + "allowValues": [ + "*" + ], + "defaultValue": "" + }, + { + "name": "grpc_method", + "allowValues": [ + "*" + ], + "defaultValue": "" + } + ], + "buckets": [ + 0.1, + 0.2, + 0.5, + 1, + 2, + 5, + 10 + ] } ], "errorReporting": { @@ -10112,7 +10209,7 @@ spec: metadata: annotations: gitpod.io: hello - gitpod.io/checksum_config: a87108c855371364faa6d0202ed2bef9c681928e38f7ff2cf90fe79f78caa73f + gitpod.io/checksum_config: b412b24494cba05f0480f767e407b5351094c34472d0966722428f0b23d05ff7 hello: world creationTimestamp: null labels: diff --git a/install/installer/cmd/testdata/render/external-registry/output.golden b/install/installer/cmd/testdata/render/external-registry/output.golden index bc71e4fcff4075..8f9ebb72bc9748 100644 --- a/install/installer/cmd/testdata/render/external-registry/output.golden +++ b/install/installer/cmd/testdata/render/external-registry/output.golden @@ -4455,6 +4455,67 @@ data: "defaultValue": "" } ] + }, + { + "name": "grpc_client_started_total", + "help": "Total number of RPCs started on the client.", + "labels": [ + { + "name": "grpc_method", + "allowValues": [ + "*" + ], + "defaultValue": "" + }, + { + "name": "grpc_service", + "allowValues": [ + "*" + ], + "defaultValue": "" + }, + { + "name": "grpc_type", + "allowValues": [ + "*" + ], + "defaultValue": "" + } + ] + }, + { + "name": "grpc_client_handled_total", + "help": "Total number of RPCs completed by the client, regardless of success or failure.", + "labels": [ + { + "name": "grpc_method", + "allowValues": [ + "*" + ], + "defaultValue": "" + }, + { + "name": "grpc_service", + "allowValues": [ + "*" + ], + "defaultValue": "" + }, + { + "name": "grpc_type", + "allowValues": [ + "*" + ], + "defaultValue": "" + }, + { + "name": "grpc_code", + "allowValues": [ + "*" + ], + "defaultValue": "" + } + ] } ], "histogramMetrics": [ @@ -4606,6 +4667,42 @@ data: 1073741824, 2147483648 ] + }, + { + "name": "grpc_client_handling_seconds", + "help": "Histogram of response latency (seconds) of the gRPC until it is finished by the application.", + "labels": [ + { + "name": "grpc_type", + "allowValues": [ + "*" + ], + "defaultValue": "" + }, + { + "name": "grpc_service", + "allowValues": [ + "*" + ], + "defaultValue": "" + }, + { + "name": "grpc_method", + "allowValues": [ + "*" + ], + "defaultValue": "" + } + ], + "buckets": [ + 0.1, + 0.2, + 0.5, + 1, + 2, + 5, + 10 + ] } ], "errorReporting": { @@ -9038,7 +9135,7 @@ spec: template: metadata: annotations: - gitpod.io/checksum_config: cc52e275885690e10f10dac466a0ffd1e4a4551efa2ee5dcbb5c4c824d987f95 + gitpod.io/checksum_config: d42da55c46ab5e8278c46a30a13e4f2c614ad4f340863a57c91fc6183a1068fc creationTimestamp: null labels: app: gitpod diff --git a/install/installer/cmd/testdata/render/gcp-setup/output.golden b/install/installer/cmd/testdata/render/gcp-setup/output.golden index 8dd9f1befcb414..622620ef44bf4d 100644 --- a/install/installer/cmd/testdata/render/gcp-setup/output.golden +++ b/install/installer/cmd/testdata/render/gcp-setup/output.golden @@ -4285,6 +4285,67 @@ data: "defaultValue": "" } ] + }, + { + "name": "grpc_client_started_total", + "help": "Total number of RPCs started on the client.", + "labels": [ + { + "name": "grpc_method", + "allowValues": [ + "*" + ], + "defaultValue": "" + }, + { + "name": "grpc_service", + "allowValues": [ + "*" + ], + "defaultValue": "" + }, + { + "name": "grpc_type", + "allowValues": [ + "*" + ], + "defaultValue": "" + } + ] + }, + { + "name": "grpc_client_handled_total", + "help": "Total number of RPCs completed by the client, regardless of success or failure.", + "labels": [ + { + "name": "grpc_method", + "allowValues": [ + "*" + ], + "defaultValue": "" + }, + { + "name": "grpc_service", + "allowValues": [ + "*" + ], + "defaultValue": "" + }, + { + "name": "grpc_type", + "allowValues": [ + "*" + ], + "defaultValue": "" + }, + { + "name": "grpc_code", + "allowValues": [ + "*" + ], + "defaultValue": "" + } + ] } ], "histogramMetrics": [ @@ -4436,6 +4497,42 @@ data: 1073741824, 2147483648 ] + }, + { + "name": "grpc_client_handling_seconds", + "help": "Histogram of response latency (seconds) of the gRPC until it is finished by the application.", + "labels": [ + { + "name": "grpc_type", + "allowValues": [ + "*" + ], + "defaultValue": "" + }, + { + "name": "grpc_service", + "allowValues": [ + "*" + ], + "defaultValue": "" + }, + { + "name": "grpc_method", + "allowValues": [ + "*" + ], + "defaultValue": "" + } + ], + "buckets": [ + 0.1, + 0.2, + 0.5, + 1, + 2, + 5, + 10 + ] } ], "errorReporting": { @@ -8641,7 +8738,7 @@ spec: template: metadata: annotations: - gitpod.io/checksum_config: cc52e275885690e10f10dac466a0ffd1e4a4551efa2ee5dcbb5c4c824d987f95 + gitpod.io/checksum_config: d42da55c46ab5e8278c46a30a13e4f2c614ad4f340863a57c91fc6183a1068fc creationTimestamp: null labels: app: gitpod diff --git a/install/installer/cmd/testdata/render/http-proxy/output.golden b/install/installer/cmd/testdata/render/http-proxy/output.golden index f627680e027e40..be500068446207 100644 --- a/install/installer/cmd/testdata/render/http-proxy/output.golden +++ b/install/installer/cmd/testdata/render/http-proxy/output.golden @@ -4624,6 +4624,67 @@ data: "defaultValue": "" } ] + }, + { + "name": "grpc_client_started_total", + "help": "Total number of RPCs started on the client.", + "labels": [ + { + "name": "grpc_method", + "allowValues": [ + "*" + ], + "defaultValue": "" + }, + { + "name": "grpc_service", + "allowValues": [ + "*" + ], + "defaultValue": "" + }, + { + "name": "grpc_type", + "allowValues": [ + "*" + ], + "defaultValue": "" + } + ] + }, + { + "name": "grpc_client_handled_total", + "help": "Total number of RPCs completed by the client, regardless of success or failure.", + "labels": [ + { + "name": "grpc_method", + "allowValues": [ + "*" + ], + "defaultValue": "" + }, + { + "name": "grpc_service", + "allowValues": [ + "*" + ], + "defaultValue": "" + }, + { + "name": "grpc_type", + "allowValues": [ + "*" + ], + "defaultValue": "" + }, + { + "name": "grpc_code", + "allowValues": [ + "*" + ], + "defaultValue": "" + } + ] } ], "histogramMetrics": [ @@ -4775,6 +4836,42 @@ data: 1073741824, 2147483648 ] + }, + { + "name": "grpc_client_handling_seconds", + "help": "Histogram of response latency (seconds) of the gRPC until it is finished by the application.", + "labels": [ + { + "name": "grpc_type", + "allowValues": [ + "*" + ], + "defaultValue": "" + }, + { + "name": "grpc_service", + "allowValues": [ + "*" + ], + "defaultValue": "" + }, + { + "name": "grpc_method", + "allowValues": [ + "*" + ], + "defaultValue": "" + } + ], + "buckets": [ + 0.1, + 0.2, + 0.5, + 1, + 2, + 5, + 10 + ] } ], "errorReporting": { @@ -10123,7 +10220,7 @@ spec: template: metadata: annotations: - gitpod.io/checksum_config: cc52e275885690e10f10dac466a0ffd1e4a4551efa2ee5dcbb5c4c824d987f95 + gitpod.io/checksum_config: d42da55c46ab5e8278c46a30a13e4f2c614ad4f340863a57c91fc6183a1068fc creationTimestamp: null labels: app: gitpod diff --git a/install/installer/cmd/testdata/render/kind-ide/output.golden b/install/installer/cmd/testdata/render/kind-ide/output.golden index 6240fcfb715b6a..3b692271cd948b 100644 --- a/install/installer/cmd/testdata/render/kind-ide/output.golden +++ b/install/installer/cmd/testdata/render/kind-ide/output.golden @@ -2142,6 +2142,67 @@ data: "defaultValue": "" } ] + }, + { + "name": "grpc_client_started_total", + "help": "Total number of RPCs started on the client.", + "labels": [ + { + "name": "grpc_method", + "allowValues": [ + "*" + ], + "defaultValue": "" + }, + { + "name": "grpc_service", + "allowValues": [ + "*" + ], + "defaultValue": "" + }, + { + "name": "grpc_type", + "allowValues": [ + "*" + ], + "defaultValue": "" + } + ] + }, + { + "name": "grpc_client_handled_total", + "help": "Total number of RPCs completed by the client, regardless of success or failure.", + "labels": [ + { + "name": "grpc_method", + "allowValues": [ + "*" + ], + "defaultValue": "" + }, + { + "name": "grpc_service", + "allowValues": [ + "*" + ], + "defaultValue": "" + }, + { + "name": "grpc_type", + "allowValues": [ + "*" + ], + "defaultValue": "" + }, + { + "name": "grpc_code", + "allowValues": [ + "*" + ], + "defaultValue": "" + } + ] } ], "histogramMetrics": [ @@ -2293,6 +2354,42 @@ data: 1073741824, 2147483648 ] + }, + { + "name": "grpc_client_handling_seconds", + "help": "Histogram of response latency (seconds) of the gRPC until it is finished by the application.", + "labels": [ + { + "name": "grpc_type", + "allowValues": [ + "*" + ], + "defaultValue": "" + }, + { + "name": "grpc_service", + "allowValues": [ + "*" + ], + "defaultValue": "" + }, + { + "name": "grpc_method", + "allowValues": [ + "*" + ], + "defaultValue": "" + } + ], + "buckets": [ + 0.1, + 0.2, + 0.5, + 1, + 2, + 5, + 10 + ] } ], "errorReporting": { @@ -3312,7 +3409,7 @@ spec: template: metadata: annotations: - gitpod.io/checksum_config: cc52e275885690e10f10dac466a0ffd1e4a4551efa2ee5dcbb5c4c824d987f95 + gitpod.io/checksum_config: d42da55c46ab5e8278c46a30a13e4f2c614ad4f340863a57c91fc6183a1068fc creationTimestamp: null labels: app: gitpod diff --git a/install/installer/cmd/testdata/render/kind-meta/output.golden b/install/installer/cmd/testdata/render/kind-meta/output.golden index 1fbb9210247900..881ab9276bc943 100644 --- a/install/installer/cmd/testdata/render/kind-meta/output.golden +++ b/install/installer/cmd/testdata/render/kind-meta/output.golden @@ -3593,6 +3593,67 @@ data: "defaultValue": "" } ] + }, + { + "name": "grpc_client_started_total", + "help": "Total number of RPCs started on the client.", + "labels": [ + { + "name": "grpc_method", + "allowValues": [ + "*" + ], + "defaultValue": "" + }, + { + "name": "grpc_service", + "allowValues": [ + "*" + ], + "defaultValue": "" + }, + { + "name": "grpc_type", + "allowValues": [ + "*" + ], + "defaultValue": "" + } + ] + }, + { + "name": "grpc_client_handled_total", + "help": "Total number of RPCs completed by the client, regardless of success or failure.", + "labels": [ + { + "name": "grpc_method", + "allowValues": [ + "*" + ], + "defaultValue": "" + }, + { + "name": "grpc_service", + "allowValues": [ + "*" + ], + "defaultValue": "" + }, + { + "name": "grpc_type", + "allowValues": [ + "*" + ], + "defaultValue": "" + }, + { + "name": "grpc_code", + "allowValues": [ + "*" + ], + "defaultValue": "" + } + ] } ], "histogramMetrics": [ @@ -3744,6 +3805,42 @@ data: 1073741824, 2147483648 ] + }, + { + "name": "grpc_client_handling_seconds", + "help": "Histogram of response latency (seconds) of the gRPC until it is finished by the application.", + "labels": [ + { + "name": "grpc_type", + "allowValues": [ + "*" + ], + "defaultValue": "" + }, + { + "name": "grpc_service", + "allowValues": [ + "*" + ], + "defaultValue": "" + }, + { + "name": "grpc_method", + "allowValues": [ + "*" + ], + "defaultValue": "" + } + ], + "buckets": [ + 0.1, + 0.2, + 0.5, + 1, + 2, + 5, + 10 + ] } ], "errorReporting": { @@ -6642,7 +6739,7 @@ spec: template: metadata: annotations: - gitpod.io/checksum_config: cc52e275885690e10f10dac466a0ffd1e4a4551efa2ee5dcbb5c4c824d987f95 + gitpod.io/checksum_config: d42da55c46ab5e8278c46a30a13e4f2c614ad4f340863a57c91fc6183a1068fc creationTimestamp: null labels: app: gitpod diff --git a/install/installer/cmd/testdata/render/minimal/output.golden b/install/installer/cmd/testdata/render/minimal/output.golden index 13fab54ed425af..1739e985a15ca3 100644 --- a/install/installer/cmd/testdata/render/minimal/output.golden +++ b/install/installer/cmd/testdata/render/minimal/output.golden @@ -4621,6 +4621,67 @@ data: "defaultValue": "" } ] + }, + { + "name": "grpc_client_started_total", + "help": "Total number of RPCs started on the client.", + "labels": [ + { + "name": "grpc_method", + "allowValues": [ + "*" + ], + "defaultValue": "" + }, + { + "name": "grpc_service", + "allowValues": [ + "*" + ], + "defaultValue": "" + }, + { + "name": "grpc_type", + "allowValues": [ + "*" + ], + "defaultValue": "" + } + ] + }, + { + "name": "grpc_client_handled_total", + "help": "Total number of RPCs completed by the client, regardless of success or failure.", + "labels": [ + { + "name": "grpc_method", + "allowValues": [ + "*" + ], + "defaultValue": "" + }, + { + "name": "grpc_service", + "allowValues": [ + "*" + ], + "defaultValue": "" + }, + { + "name": "grpc_type", + "allowValues": [ + "*" + ], + "defaultValue": "" + }, + { + "name": "grpc_code", + "allowValues": [ + "*" + ], + "defaultValue": "" + } + ] } ], "histogramMetrics": [ @@ -4772,6 +4833,42 @@ data: 1073741824, 2147483648 ] + }, + { + "name": "grpc_client_handling_seconds", + "help": "Histogram of response latency (seconds) of the gRPC until it is finished by the application.", + "labels": [ + { + "name": "grpc_type", + "allowValues": [ + "*" + ], + "defaultValue": "" + }, + { + "name": "grpc_service", + "allowValues": [ + "*" + ], + "defaultValue": "" + }, + { + "name": "grpc_method", + "allowValues": [ + "*" + ], + "defaultValue": "" + } + ], + "buckets": [ + 0.1, + 0.2, + 0.5, + 1, + 2, + 5, + 10 + ] } ], "errorReporting": { @@ -9318,7 +9415,7 @@ spec: template: metadata: annotations: - gitpod.io/checksum_config: cc52e275885690e10f10dac466a0ffd1e4a4551efa2ee5dcbb5c4c824d987f95 + gitpod.io/checksum_config: d42da55c46ab5e8278c46a30a13e4f2c614ad4f340863a57c91fc6183a1068fc creationTimestamp: null labels: app: gitpod diff --git a/install/installer/cmd/testdata/render/shortname/output.golden b/install/installer/cmd/testdata/render/shortname/output.golden index dfce8ff05dc316..faba81f57e5169 100644 --- a/install/installer/cmd/testdata/render/shortname/output.golden +++ b/install/installer/cmd/testdata/render/shortname/output.golden @@ -4621,6 +4621,67 @@ data: "defaultValue": "" } ] + }, + { + "name": "grpc_client_started_total", + "help": "Total number of RPCs started on the client.", + "labels": [ + { + "name": "grpc_method", + "allowValues": [ + "*" + ], + "defaultValue": "" + }, + { + "name": "grpc_service", + "allowValues": [ + "*" + ], + "defaultValue": "" + }, + { + "name": "grpc_type", + "allowValues": [ + "*" + ], + "defaultValue": "" + } + ] + }, + { + "name": "grpc_client_handled_total", + "help": "Total number of RPCs completed by the client, regardless of success or failure.", + "labels": [ + { + "name": "grpc_method", + "allowValues": [ + "*" + ], + "defaultValue": "" + }, + { + "name": "grpc_service", + "allowValues": [ + "*" + ], + "defaultValue": "" + }, + { + "name": "grpc_type", + "allowValues": [ + "*" + ], + "defaultValue": "" + }, + { + "name": "grpc_code", + "allowValues": [ + "*" + ], + "defaultValue": "" + } + ] } ], "histogramMetrics": [ @@ -4772,6 +4833,42 @@ data: 1073741824, 2147483648 ] + }, + { + "name": "grpc_client_handling_seconds", + "help": "Histogram of response latency (seconds) of the gRPC until it is finished by the application.", + "labels": [ + { + "name": "grpc_type", + "allowValues": [ + "*" + ], + "defaultValue": "" + }, + { + "name": "grpc_service", + "allowValues": [ + "*" + ], + "defaultValue": "" + }, + { + "name": "grpc_method", + "allowValues": [ + "*" + ], + "defaultValue": "" + } + ], + "buckets": [ + 0.1, + 0.2, + 0.5, + 1, + 2, + 5, + 10 + ] } ], "errorReporting": { @@ -9318,7 +9415,7 @@ spec: template: metadata: annotations: - gitpod.io/checksum_config: cc52e275885690e10f10dac466a0ffd1e4a4551efa2ee5dcbb5c4c824d987f95 + gitpod.io/checksum_config: d42da55c46ab5e8278c46a30a13e4f2c614ad4f340863a57c91fc6183a1068fc creationTimestamp: null labels: app: gitpod diff --git a/install/installer/cmd/testdata/render/statefulset-customization/output.golden b/install/installer/cmd/testdata/render/statefulset-customization/output.golden index f4780163395bb7..ca16bd9b0dc43c 100644 --- a/install/installer/cmd/testdata/render/statefulset-customization/output.golden +++ b/install/installer/cmd/testdata/render/statefulset-customization/output.golden @@ -4633,6 +4633,67 @@ data: "defaultValue": "" } ] + }, + { + "name": "grpc_client_started_total", + "help": "Total number of RPCs started on the client.", + "labels": [ + { + "name": "grpc_method", + "allowValues": [ + "*" + ], + "defaultValue": "" + }, + { + "name": "grpc_service", + "allowValues": [ + "*" + ], + "defaultValue": "" + }, + { + "name": "grpc_type", + "allowValues": [ + "*" + ], + "defaultValue": "" + } + ] + }, + { + "name": "grpc_client_handled_total", + "help": "Total number of RPCs completed by the client, regardless of success or failure.", + "labels": [ + { + "name": "grpc_method", + "allowValues": [ + "*" + ], + "defaultValue": "" + }, + { + "name": "grpc_service", + "allowValues": [ + "*" + ], + "defaultValue": "" + }, + { + "name": "grpc_type", + "allowValues": [ + "*" + ], + "defaultValue": "" + }, + { + "name": "grpc_code", + "allowValues": [ + "*" + ], + "defaultValue": "" + } + ] } ], "histogramMetrics": [ @@ -4784,6 +4845,42 @@ data: 1073741824, 2147483648 ] + }, + { + "name": "grpc_client_handling_seconds", + "help": "Histogram of response latency (seconds) of the gRPC until it is finished by the application.", + "labels": [ + { + "name": "grpc_type", + "allowValues": [ + "*" + ], + "defaultValue": "" + }, + { + "name": "grpc_service", + "allowValues": [ + "*" + ], + "defaultValue": "" + }, + { + "name": "grpc_method", + "allowValues": [ + "*" + ], + "defaultValue": "" + } + ], + "buckets": [ + 0.1, + 0.2, + 0.5, + 1, + 2, + 5, + 10 + ] } ], "errorReporting": { @@ -9330,7 +9427,7 @@ spec: template: metadata: annotations: - gitpod.io/checksum_config: cc52e275885690e10f10dac466a0ffd1e4a4551efa2ee5dcbb5c4c824d987f95 + gitpod.io/checksum_config: d42da55c46ab5e8278c46a30a13e4f2c614ad4f340863a57c91fc6183a1068fc creationTimestamp: null labels: app: gitpod diff --git a/install/installer/cmd/testdata/render/use-pod-security-policies/output.golden b/install/installer/cmd/testdata/render/use-pod-security-policies/output.golden index 7ca79d3f9cda39..a6b3c694ac90f2 100644 --- a/install/installer/cmd/testdata/render/use-pod-security-policies/output.golden +++ b/install/installer/cmd/testdata/render/use-pod-security-policies/output.golden @@ -4954,6 +4954,67 @@ data: "defaultValue": "" } ] + }, + { + "name": "grpc_client_started_total", + "help": "Total number of RPCs started on the client.", + "labels": [ + { + "name": "grpc_method", + "allowValues": [ + "*" + ], + "defaultValue": "" + }, + { + "name": "grpc_service", + "allowValues": [ + "*" + ], + "defaultValue": "" + }, + { + "name": "grpc_type", + "allowValues": [ + "*" + ], + "defaultValue": "" + } + ] + }, + { + "name": "grpc_client_handled_total", + "help": "Total number of RPCs completed by the client, regardless of success or failure.", + "labels": [ + { + "name": "grpc_method", + "allowValues": [ + "*" + ], + "defaultValue": "" + }, + { + "name": "grpc_service", + "allowValues": [ + "*" + ], + "defaultValue": "" + }, + { + "name": "grpc_type", + "allowValues": [ + "*" + ], + "defaultValue": "" + }, + { + "name": "grpc_code", + "allowValues": [ + "*" + ], + "defaultValue": "" + } + ] } ], "histogramMetrics": [ @@ -5105,6 +5166,42 @@ data: 1073741824, 2147483648 ] + }, + { + "name": "grpc_client_handling_seconds", + "help": "Histogram of response latency (seconds) of the gRPC until it is finished by the application.", + "labels": [ + { + "name": "grpc_type", + "allowValues": [ + "*" + ], + "defaultValue": "" + }, + { + "name": "grpc_service", + "allowValues": [ + "*" + ], + "defaultValue": "" + }, + { + "name": "grpc_method", + "allowValues": [ + "*" + ], + "defaultValue": "" + } + ], + "buckets": [ + 0.1, + 0.2, + 0.5, + 1, + 2, + 5, + 10 + ] } ], "errorReporting": { @@ -9762,7 +9859,7 @@ spec: template: metadata: annotations: - gitpod.io/checksum_config: cc52e275885690e10f10dac466a0ffd1e4a4551efa2ee5dcbb5c4c824d987f95 + gitpod.io/checksum_config: d42da55c46ab5e8278c46a30a13e4f2c614ad4f340863a57c91fc6183a1068fc creationTimestamp: null labels: app: gitpod diff --git a/install/installer/cmd/testdata/render/vsxproxy-pvc/output.golden b/install/installer/cmd/testdata/render/vsxproxy-pvc/output.golden index 5d99d43f36a231..a20c452c1fd8db 100644 --- a/install/installer/cmd/testdata/render/vsxproxy-pvc/output.golden +++ b/install/installer/cmd/testdata/render/vsxproxy-pvc/output.golden @@ -4623,6 +4623,67 @@ data: "defaultValue": "" } ] + }, + { + "name": "grpc_client_started_total", + "help": "Total number of RPCs started on the client.", + "labels": [ + { + "name": "grpc_method", + "allowValues": [ + "*" + ], + "defaultValue": "" + }, + { + "name": "grpc_service", + "allowValues": [ + "*" + ], + "defaultValue": "" + }, + { + "name": "grpc_type", + "allowValues": [ + "*" + ], + "defaultValue": "" + } + ] + }, + { + "name": "grpc_client_handled_total", + "help": "Total number of RPCs completed by the client, regardless of success or failure.", + "labels": [ + { + "name": "grpc_method", + "allowValues": [ + "*" + ], + "defaultValue": "" + }, + { + "name": "grpc_service", + "allowValues": [ + "*" + ], + "defaultValue": "" + }, + { + "name": "grpc_type", + "allowValues": [ + "*" + ], + "defaultValue": "" + }, + { + "name": "grpc_code", + "allowValues": [ + "*" + ], + "defaultValue": "" + } + ] } ], "histogramMetrics": [ @@ -4774,6 +4835,42 @@ data: 1073741824, 2147483648 ] + }, + { + "name": "grpc_client_handling_seconds", + "help": "Histogram of response latency (seconds) of the gRPC until it is finished by the application.", + "labels": [ + { + "name": "grpc_type", + "allowValues": [ + "*" + ], + "defaultValue": "" + }, + { + "name": "grpc_service", + "allowValues": [ + "*" + ], + "defaultValue": "" + }, + { + "name": "grpc_method", + "allowValues": [ + "*" + ], + "defaultValue": "" + } + ], + "buckets": [ + 0.1, + 0.2, + 0.5, + 1, + 2, + 5, + 10 + ] } ], "errorReporting": { @@ -9308,7 +9405,7 @@ spec: template: metadata: annotations: - gitpod.io/checksum_config: cc52e275885690e10f10dac466a0ffd1e4a4551efa2ee5dcbb5c4c824d987f95 + gitpod.io/checksum_config: d42da55c46ab5e8278c46a30a13e4f2c614ad4f340863a57c91fc6183a1068fc creationTimestamp: null labels: app: gitpod diff --git a/install/installer/cmd/testdata/render/workspace-requests-limits/output.golden b/install/installer/cmd/testdata/render/workspace-requests-limits/output.golden index 8c207b4834bdd4..b9762b6d3cde94 100644 --- a/install/installer/cmd/testdata/render/workspace-requests-limits/output.golden +++ b/install/installer/cmd/testdata/render/workspace-requests-limits/output.golden @@ -4624,6 +4624,67 @@ data: "defaultValue": "" } ] + }, + { + "name": "grpc_client_started_total", + "help": "Total number of RPCs started on the client.", + "labels": [ + { + "name": "grpc_method", + "allowValues": [ + "*" + ], + "defaultValue": "" + }, + { + "name": "grpc_service", + "allowValues": [ + "*" + ], + "defaultValue": "" + }, + { + "name": "grpc_type", + "allowValues": [ + "*" + ], + "defaultValue": "" + } + ] + }, + { + "name": "grpc_client_handled_total", + "help": "Total number of RPCs completed by the client, regardless of success or failure.", + "labels": [ + { + "name": "grpc_method", + "allowValues": [ + "*" + ], + "defaultValue": "" + }, + { + "name": "grpc_service", + "allowValues": [ + "*" + ], + "defaultValue": "" + }, + { + "name": "grpc_type", + "allowValues": [ + "*" + ], + "defaultValue": "" + }, + { + "name": "grpc_code", + "allowValues": [ + "*" + ], + "defaultValue": "" + } + ] } ], "histogramMetrics": [ @@ -4775,6 +4836,42 @@ data: 1073741824, 2147483648 ] + }, + { + "name": "grpc_client_handling_seconds", + "help": "Histogram of response latency (seconds) of the gRPC until it is finished by the application.", + "labels": [ + { + "name": "grpc_type", + "allowValues": [ + "*" + ], + "defaultValue": "" + }, + { + "name": "grpc_service", + "allowValues": [ + "*" + ], + "defaultValue": "" + }, + { + "name": "grpc_method", + "allowValues": [ + "*" + ], + "defaultValue": "" + } + ], + "buckets": [ + 0.1, + 0.2, + 0.5, + 1, + 2, + 5, + 10 + ] } ], "errorReporting": { @@ -9321,7 +9418,7 @@ spec: template: metadata: annotations: - gitpod.io/checksum_config: cc52e275885690e10f10dac466a0ffd1e4a4551efa2ee5dcbb5c4c824d987f95 + gitpod.io/checksum_config: d42da55c46ab5e8278c46a30a13e4f2c614ad4f340863a57c91fc6183a1068fc creationTimestamp: null labels: app: gitpod diff --git a/install/installer/pkg/components/ide-metrics/configmap.go b/install/installer/pkg/components/ide-metrics/configmap.go index a5f527eaba55c0..404b0c8673756d 100644 --- a/install/installer/pkg/components/ide-metrics/configmap.go +++ b/install/installer/pkg/components/ide-metrics/configmap.go @@ -183,6 +183,44 @@ func configmap(ctx *common.RenderContext) ([]runtime.Object, error) { AllowValues: []string{"*"}, }, }, + }, { + Name: "grpc_client_started_total", + Help: "Total number of RPCs started on the client.", + Labels: []config.LabelAllowList{ + { + Name: "grpc_method", + AllowValues: []string{"*"}, + }, + { + Name: "grpc_service", + AllowValues: []string{"*"}, + }, + { + Name: "grpc_type", + AllowValues: []string{"*"}, + }, + }, + }, { + Name: "grpc_client_handled_total", + Help: "Total number of RPCs completed by the client, regardless of success or failure.", + Labels: []config.LabelAllowList{ + { + Name: "grpc_method", + AllowValues: []string{"*"}, + }, + { + Name: "grpc_service", + AllowValues: []string{"*"}, + }, + { + Name: "grpc_type", + AllowValues: []string{"*"}, + }, + { + Name: "grpc_code", + AllowValues: []string{"*"}, + }, + }, }, } @@ -257,6 +295,24 @@ func configmap(ctx *common.RenderContext) ([]runtime.Object, error) { AllowValues: []string{"*"}, }, }, + }, { + Name: "grpc_client_handling_seconds", + Help: "Histogram of response latency (seconds) of the gRPC until it is finished by the application.", + Labels: []config.LabelAllowList{ + { + Name: "grpc_type", + AllowValues: []string{"*"}, + }, + { + Name: "grpc_service", + AllowValues: []string{"*"}, + }, + { + Name: "grpc_method", + AllowValues: []string{"*"}, + }, + }, + Buckets: []float64{0.1, 0.2, 0.5, 1, 2, 5, 10}, }, }