Skip to content

Commit 47d4ac5

Browse files
corneliusludmannroboquat
authored andcommitted
[ws-proxy] Get supervisor image from pod annotation
instead from ws-proxy config
1 parent 7deb5c8 commit 47d4ac5

File tree

5 files changed

+72
-31
lines changed

5 files changed

+72
-31
lines changed

components/ws-proxy/BUILD.yaml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,4 +50,7 @@ packages:
5050
- CGO_ENABLED=0
5151
- GOOS=linux
5252
config:
53-
packaging: library
53+
packaging: library
54+
# it's already tested in :app and running both tests for :app and :lib in
55+
# parallel leads to port already in use errors
56+
dontTest: true

components/ws-proxy/pkg/proxy/config.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
validation "github.com/go-ozzo/ozzo-validation"
1212
"golang.org/x/xerrors"
1313

14+
"github.com/gitpod-io/gitpod/common-go/log"
1415
"github.com/gitpod-io/gitpod/common-go/util"
1516
)
1617

@@ -70,8 +71,9 @@ func (c *HostBasedIngressConfig) Validate() error {
7071

7172
// WorkspacePodConfig contains config around the workspace pod.
7273
type WorkspacePodConfig struct {
73-
TheiaPort uint16 `json:"theiaPort"`
74-
SupervisorPort uint16 `json:"supervisorPort"`
74+
TheiaPort uint16 `json:"theiaPort"`
75+
SupervisorPort uint16 `json:"supervisorPort"`
76+
// SupervisorImage is deprecated
7577
SupervisorImage string `json:"supervisorImage"`
7678
}
7779

@@ -84,8 +86,10 @@ func (c *WorkspacePodConfig) Validate() error {
8486
err := validation.ValidateStruct(c,
8587
validation.Field(&c.TheiaPort, validation.Required),
8688
validation.Field(&c.SupervisorPort, validation.Required),
87-
validation.Field(&c.SupervisorImage, validation.Required),
8889
)
90+
if len(c.SupervisorImage) > 0 {
91+
log.Warn("config value 'workspacePodConfig.supervisorImage' is deprected, use it only to be backwards compatible")
92+
}
8993
if err != nil {
9094
return err
9195
}

components/ws-proxy/pkg/proxy/infoprovider.go

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,8 @@ type WorkspaceInfo struct {
4949
InstanceID string
5050
URL string
5151

52-
IDEImage string
52+
IDEImage string
53+
SupervisorImage string
5354

5455
// (parsed from URL)
5556
IDEPublicPort string
@@ -148,15 +149,16 @@ func mapPodToWorkspaceInfo(pod *corev1.Pod) *WorkspaceInfo {
148149
workspaceURL := pod.Annotations[kubernetes.WorkspaceURLAnnotation]
149150

150151
return &WorkspaceInfo{
151-
WorkspaceID: pod.Labels[kubernetes.MetaIDLabel],
152-
InstanceID: pod.Labels[kubernetes.WorkspaceIDLabel],
153-
URL: workspaceURL,
154-
IDEImage: imageSpec.IdeRef,
155-
IDEPublicPort: getPortStr(workspaceURL),
156-
IPAddress: pod.Status.PodIP,
157-
Ports: extractExposedPorts(pod).Ports,
158-
Auth: &wsapi.WorkspaceAuthentication{Admission: admission, OwnerToken: ownerToken},
159-
StartedAt: pod.CreationTimestamp.Time,
152+
WorkspaceID: pod.Labels[kubernetes.MetaIDLabel],
153+
InstanceID: pod.Labels[kubernetes.WorkspaceIDLabel],
154+
URL: workspaceURL,
155+
IDEImage: imageSpec.IdeRef,
156+
IDEPublicPort: getPortStr(workspaceURL),
157+
SupervisorImage: imageSpec.SupervisorRef,
158+
IPAddress: pod.Status.PodIP,
159+
Ports: extractExposedPorts(pod).Ports,
160+
Auth: &wsapi.WorkspaceAuthentication{Admission: admission, OwnerToken: ownerToken},
161+
StartedAt: pod.CreationTimestamp.Time,
160162
}
161163
}
162164

components/ws-proxy/pkg/proxy/routes.go

Lines changed: 45 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,7 @@ func (ir *ideRoutes) HandleSupervisorFrontendRoute(route *mux.Route) {
163163

164164
r := route.Subrouter()
165165
r.Use(logRouteHandlerHandler("SupervisorIDEHostHandler"))
166+
r.Use(ir.workspaceMustExistHandler)
166167
// strip the frontend prefix, just for good measure
167168
r.Use(func(h http.Handler) http.Handler {
168169
return http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) {
@@ -171,17 +172,27 @@ func (ir *ideRoutes) HandleSupervisorFrontendRoute(route *mux.Route) {
171172
})
172173
})
173174
// always hit the blobserver to ensure that blob is downloaded
174-
r.NewRoute().HandlerFunc(proxyPass(ir.Config, ir.InfoProvider, func(cfg *Config, _ WorkspaceInfoProvider, req *http.Request) (*url.URL, error) {
175-
return resolveSupervisorURL(cfg), nil
175+
r.NewRoute().HandlerFunc(proxyPass(ir.Config, ir.InfoProvider, func(cfg *Config, infoProvider WorkspaceInfoProvider, req *http.Request) (*url.URL, error) {
176+
info := getWorkspaceInfoFromContext(req.Context())
177+
return resolveSupervisorURL(cfg, info, req)
176178
}, func(h *proxyPassConfig) {
177179
h.Transport = &blobserveTransport{
178180
transport: h.Transport,
179181
Config: ir.Config.Config,
180182
resolveImage: func(t *blobserveTransport, req *http.Request) string {
181-
var (
182-
image = ir.Config.Config.WorkspacePodConfig.SupervisorImage
183-
path = strings.TrimPrefix(req.URL.Path, "/"+image)
184-
)
183+
info := getWorkspaceInfoFromContext(req.Context())
184+
if info == nil && len(ir.Config.Config.WorkspacePodConfig.SupervisorImage) == 0 {
185+
// no workspace information available - cannot resolve supervisor image
186+
return ""
187+
}
188+
189+
// use the config value for backwards compatibility when info.SupervisorImage is not set
190+
image := ir.Config.Config.WorkspacePodConfig.SupervisorImage
191+
if info != nil && len(info.SupervisorImage) > 0 {
192+
image = info.SupervisorImage
193+
}
194+
195+
path := strings.TrimPrefix(req.URL.Path, "/"+image)
185196
if path == "/worker-proxy.js" {
186197
// worker must be served from the same origin
187198
return ""
@@ -192,12 +203,23 @@ func (ir *ideRoutes) HandleSupervisorFrontendRoute(route *mux.Route) {
192203
}))
193204
}
194205

195-
func resolveSupervisorURL(cfg *Config) *url.URL {
206+
func resolveSupervisorURL(cfg *Config, info *WorkspaceInfo, req *http.Request) (*url.URL, error) {
207+
if info == nil && len(cfg.WorkspacePodConfig.SupervisorImage) == 0 {
208+
log.WithFields(log.OWI("", getWorkspaceCoords(req).ID, "")).Warn("no workspace info available - cannot resolve supervisor route")
209+
return nil, xerrors.Errorf("no workspace information available - cannot resolve supervisor route")
210+
}
211+
212+
// use the config value for backwards compatibility when info.SupervisorImage is not set
213+
supervisorImage := cfg.WorkspacePodConfig.SupervisorImage
214+
if info != nil && len(info.SupervisorImage) > 0 {
215+
supervisorImage = info.SupervisorImage
216+
}
217+
196218
var dst url.URL
197219
dst.Scheme = cfg.BlobServer.Scheme
198220
dst.Host = cfg.BlobServer.Host
199-
dst.Path = "/" + cfg.WorkspacePodConfig.SupervisorImage
200-
return &dst
221+
dst.Path = "/" + supervisorImage
222+
return &dst, nil
201223
}
202224

203225
type BlobserveInlineVars struct {
@@ -234,8 +256,13 @@ func (ir *ideRoutes) HandleRoot(route *mux.Route) {
234256
// but it has to know exposed URLs in the context of current workspace cluster
235257
// so first we ask blobserve to preload the supervisor image
236258
// and if it is successful we pass exposed URLs to IDE and supervisor to blobserve for inlining
237-
supervisorURL := resolveSupervisorURL(t.Config).String() + "/main.js"
238-
preloadSupervisorReq, err := http.NewRequest("GET", supervisorURL, nil)
259+
supervisorURL, err := resolveSupervisorURL(t.Config, info, req)
260+
if err != nil {
261+
log.WithError(err).Error("could not preload supervisor")
262+
return image
263+
}
264+
supervisorURLString := supervisorURL.String() + "/main.js"
265+
preloadSupervisorReq, err := http.NewRequest("GET", supervisorURLString, nil)
239266
if err != nil {
240267
log.WithField("supervisorURL", supervisorURL).WithError(err).Error("could not preload supervisor")
241268
return image
@@ -251,9 +278,15 @@ func (ir *ideRoutes) HandleRoot(route *mux.Route) {
251278
return image
252279
}
253280

281+
// use the config value for backwards compatibility when info.SupervisorImage is not set
282+
supervisorImage := t.Config.WorkspacePodConfig.SupervisorImage
283+
if len(info.SupervisorImage) > 0 {
284+
supervisorImage = info.SupervisorImage
285+
}
286+
254287
inlineVars := &BlobserveInlineVars{
255288
IDE: t.asBlobserveURL(image, ""),
256-
SupervisorImage: t.asBlobserveURL(t.Config.WorkspacePodConfig.SupervisorImage, ""),
289+
SupervisorImage: t.asBlobserveURL(supervisorImage, ""),
257290
}
258291
inlinveVarsValue, err := json.Marshal(inlineVars)
259292
if err != nil {

components/ws-proxy/pkg/proxy/routes_test.go

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@ const (
3333
var (
3434
workspaces = []WorkspaceInfo{
3535
{
36-
IDEImage: "gitpod-io/ide:latest",
36+
IDEImage: "gitpod-io/ide:latest",
37+
SupervisorImage: "gitpod-io/supervisor:latest",
3738
Auth: &api.WorkspaceAuthentication{
3839
Admission: api.AdmissionLevel_ADMIT_OWNER_ONLY,
3940
OwnerToken: "owner-token",
@@ -72,9 +73,8 @@ var (
7273
Scheme: "http",
7374
},
7475
WorkspacePodConfig: &WorkspacePodConfig{
75-
TheiaPort: workspacePort,
76-
SupervisorPort: supervisorPort,
77-
SupervisorImage: "gitpod-io/supervisor:latest",
76+
TheiaPort: workspacePort,
77+
SupervisorPort: supervisorPort,
7878
},
7979
BuiltinPages: BuiltinPagesConfig{
8080
Location: "../../public",
@@ -203,7 +203,6 @@ func TestRoutes(t *testing.T) {
203203
Desc string
204204
Config *Config
205205
Request *http.Request
206-
Workspaces []WorkspaceInfo
207206
Router RouterFactory
208207
Targets *Targets
209208
IgnoreBody bool

0 commit comments

Comments
 (0)