Skip to content

Commit f57bf3b

Browse files
akosyakovAndrea Falzetti
authored and
Andrea Falzetti
committed
[supervisor] make it compatible with run-gp
1 parent 034543f commit f57bf3b

15 files changed

+354
-43
lines changed

components/supervisor/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
supervisor

components/supervisor/cmd/run.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ var runCmd = &cobra.Command{
2323
Short: "starts the supervisor",
2424

2525
Run: func(cmd *cobra.Command, args []string) {
26-
log.Init(ServiceName, Version, true, os.Getenv("SUPERVISOR_DEBUG_ENABLE") == "true")
26+
log.Init(ServiceName, Version, !runOpts.RunGP, os.Getenv("SUPERVISOR_DEBUG_ENABLE") == "true")
2727
common_grpc.SetupLogging()
2828
supervisor.Version = Version
2929
supervisor.Run(supervisor.WithRunGP(runOpts.RunGP))

components/supervisor/hot-swap.sh

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
#!/bin/bash
2+
# Copyright (c) 2022 Gitpod GmbH. All rights reserved.
3+
# Licensed under the GNU Affero General Public License (AGPL).
4+
# See License.AGPL.txt in the project root for license information.
5+
6+
set -Eeuo pipefail
7+
8+
# This script swaps the backend startup endpoint with a built one
9+
# in a workspace and restarts the JB backend.
10+
11+
component=${PWD##*/}
12+
workspaceUrl=$(echo "${1}" |sed -e "s/\/$//")
13+
echo "URL: $workspaceUrl"
14+
15+
workspaceDesc=$(gpctl workspaces describe "$workspaceUrl" -o=json)
16+
17+
podName=$(echo "$workspaceDesc" | jq .runtime.pod_name -r)
18+
echo "Pod: $podName"
19+
20+
workspaceId=$(echo "$workspaceDesc" | jq .metadata.meta_id -r)
21+
echo "ID: $workspaceId"
22+
23+
clusterHost=$(kubectl exec -it "$podName" -- printenv GITPOD_WORKSPACE_CLUSTER_HOST |sed -e "s/\s//g")
24+
echo "Cluster Host: $clusterHost"
25+
26+
# prepare ssh
27+
ownerToken=$(kubectl get pod "$podName" -o=json | jq ".metadata.annotations.\"gitpod\/ownerToken\"" -r)
28+
sshConfig="./ssh-config"
29+
echo "Host $workspaceId" > "$sshConfig"
30+
echo " Hostname \"$workspaceId.ssh.$clusterHost\"" >> "$sshConfig"
31+
echo " User \"$workspaceId#$ownerToken\"" >> "$sshConfig"
32+
33+
# build
34+
go build .
35+
echo "$component built"
36+
37+
# upload
38+
uploadDest="/.supervisor/$component"
39+
echo "Upload Dest: $uploadDest"
40+
ssh -F "$sshConfig" "$workspaceId" "sudo chmod 777 $uploadDest && sudo rm $uploadDest"
41+
scp -F "$sshConfig" -r "./supervisor" "$workspaceId":"$uploadDest"
42+
echo "Swap complete"
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#!/bin/bash
2+
# Copyright (c) 2022 Gitpod GmbH. All rights reserved.
3+
# Licensed under the GNU Affero General Public License (AGPL).
4+
# See License.AGPL.txt in the project root for license information.
5+
6+
set -Eeuo pipefail
7+
8+
# This script swaps the backend startup endpoint with a built one
9+
# in a workspace and restarts the JB backend.
10+
11+
component=${PWD##*/}
12+
13+
# build
14+
go build .
15+
echo "$component built"
16+
17+
sudo rm /.supervisor/supervisor
18+
sudo mv ./"$component" /.supervisor
19+
echo "Local Swap complete"

components/supervisor/pkg/ports/ports.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -872,3 +872,13 @@ func defaultRoutableIP() string {
872872

873873
return addresses[0].(*net.IPNet).IP.String()
874874
}
875+
876+
func (pm *Manager) IsServed(port uint32) bool {
877+
served := pm.served
878+
for _, served := range served {
879+
if served.Port == port {
880+
return true
881+
}
882+
}
883+
return false
884+
}

components/supervisor/pkg/run/run.go

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
// Copyright (c) 2022 Gitpod GmbH. All rights reserved.
2+
// Licensed under the GNU Affero General Public License (AGPL).
3+
// See License.AGPL.txt in the project root for license information.
4+
5+
package run
6+
7+
import (
8+
"context"
9+
"fmt"
10+
"sync"
11+
12+
"github.com/gitpod-io/gitpod/supervisor/api"
13+
"github.com/gitpod-io/gitpod/supervisor/pkg/ports"
14+
"google.golang.org/grpc"
15+
"google.golang.org/grpc/credentials/insecure"
16+
)
17+
18+
type Option struct {
19+
Port uint32
20+
Ports *ports.Manager
21+
}
22+
23+
type Client struct {
24+
option *Option
25+
26+
conn *grpc.ClientConn
27+
closeOnce sync.Once
28+
29+
Status api.StatusServiceClient
30+
Terminal api.TerminalServiceClient
31+
}
32+
33+
func New(ctx context.Context, option *Option) (*Client, error) {
34+
url := fmt.Sprintf("localhost:%d", option.Port)
35+
conn, err := grpc.DialContext(ctx, url, grpc.WithTransportCredentials(insecure.NewCredentials()))
36+
if err != nil {
37+
return nil, err
38+
}
39+
return &Client{
40+
option: option,
41+
conn: conn,
42+
Status: api.NewStatusServiceClient(conn),
43+
Terminal: api.NewTerminalServiceClient(conn),
44+
}, nil
45+
}
46+
47+
func (client *Client) Close() {
48+
client.closeOnce.Do(func() {
49+
client.conn.Close()
50+
})
51+
}
52+
53+
func (client *Client) Available() bool {
54+
if client == nil {
55+
return false
56+
}
57+
return client.option.Ports.IsServed(client.option.Port)
58+
}

components/supervisor/pkg/supervisor/config.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,9 @@ type StaticConfig struct {
8585

8686
// SSHPort is the port we run the SSH server on
8787
SSHPort int `json:"sshPort"`
88+
89+
// RunEndpointPort is the port where to serve the run API endpoint on
90+
RunEndpointPort *int `json:"runEndpointPort,omitempty"`
8891
}
8992

9093
// Validate validates this configuration.

components/supervisor/pkg/supervisor/services.go

Lines changed: 55 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import (
2626
csapi "github.com/gitpod-io/gitpod/content-service/api"
2727
"github.com/gitpod-io/gitpod/supervisor/api"
2828
"github.com/gitpod-io/gitpod/supervisor/pkg/ports"
29+
"github.com/gitpod-io/gitpod/supervisor/pkg/run"
2930
)
3031

3132
// RegisterableService can register a service.
@@ -98,6 +99,7 @@ type statusService struct {
9899
ideReady *ideReadyState
99100
desktopIdeReady *ideReadyState
100101
topService *TopService
102+
runClient *run.Client
101103

102104
api.UnimplementedStatusServiceServer
103105
}
@@ -244,10 +246,37 @@ func (s *statusService) TasksStatus(req *api.TasksStatusRequest, srv api.StatusS
244246
case <-s.Tasks.ready:
245247
}
246248

249+
var (
250+
runStream api.StatusService_TasksStatusClient
251+
err error
252+
)
253+
if s.runClient.Available() {
254+
runStream, err = s.runClient.Status.TasksStatus(srv.Context(), req)
255+
if err != nil {
256+
log.WithError(err).Error("failed to stream run tasks state")
257+
}
258+
}
259+
260+
var runTasks []*api.TaskStatus
261+
var subTasks []*api.TaskStatus
262+
doSend := func() error {
263+
var tasks []*api.TaskStatus
264+
tasks = append(tasks, runTasks...)
265+
tasks = append(tasks, subTasks...)
266+
return srv.Send(&api.TasksStatusResponse{Tasks: tasks})
267+
}
268+
247269
if !req.Observe {
248-
return srv.Send(&api.TasksStatusResponse{
249-
Tasks: s.Tasks.Status(),
250-
})
270+
if runStream != nil {
271+
resp, err := runStream.Recv()
272+
if err != nil {
273+
log.WithError(err).Error("failed to receive run tasks state")
274+
} else {
275+
runTasks = resp.Tasks
276+
}
277+
}
278+
subTasks = s.Tasks.Status()
279+
return doSend()
251280
}
252281

253282
sub := s.Tasks.Subscribe()
@@ -256,15 +285,37 @@ func (s *statusService) TasksStatus(req *api.TasksStatusRequest, srv api.StatusS
256285
}
257286
defer sub.Close()
258287

288+
respChan := make(chan []*api.TaskStatus, 5)
289+
if runStream != nil {
290+
go func() {
291+
for {
292+
resp, err := runStream.Recv()
293+
if err != nil {
294+
return
295+
}
296+
respChan <- resp.GetTasks()
297+
}
298+
}()
299+
}
259300
for {
260301
select {
261302
case <-srv.Context().Done():
262303
return nil
304+
case update := <-respChan:
305+
if update == nil {
306+
return nil
307+
}
308+
runTasks = update
309+
err := doSend()
310+
if err != nil {
311+
return err
312+
}
263313
case update := <-sub.Updates():
264314
if update == nil {
265315
return nil
266316
}
267-
err := srv.Send(&api.TasksStatusResponse{Tasks: update})
317+
subTasks = update
318+
err := doSend()
268319
if err != nil {
269320
return err
270321
}

0 commit comments

Comments
 (0)