Skip to content

SSH Gateway #7411

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 4 additions & 8 deletions components/ide/jetbrains/image/BUILD.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,9 @@ packages:
srcs:
- "startup.sh"
- "supervisor-ide-config_intellij.json"
- "status/go.mod"
- "status/main.go"
deps:
- components/ide/jetbrains/backend-plugin:plugin
- components/ide/jetbrains/image/status:app
argdeps:
- imageRepoBase
config:
Expand All @@ -34,10 +33,9 @@ packages:
srcs:
- "startup.sh"
- "supervisor-ide-config_goland.json"
- "status/go.mod"
- "status/main.go"
deps:
- components/ide/jetbrains/backend-plugin:plugin
- components/ide/jetbrains/image/status:app
argdeps:
- imageRepoBase
config:
Expand All @@ -55,10 +53,9 @@ packages:
srcs:
- "startup.sh"
- "supervisor-ide-config_pycharm.json"
- "status/go.mod"
- "status/main.go"
deps:
- components/ide/jetbrains/backend-plugin:plugin
- components/ide/jetbrains/image/status:app
argdeps:
- imageRepoBase
config:
Expand All @@ -76,10 +73,9 @@ packages:
srcs:
- "startup.sh"
- "supervisor-ide-config_phpstorm.json"
- "status/go.mod"
- "status/main.go"
deps:
- components/ide/jetbrains/backend-plugin:plugin
- components/ide/jetbrains/image/status:app
argdeps:
- imageRepoBase
config:
Expand Down
7 changes: 1 addition & 6 deletions components/ide/jetbrains/image/leeway.Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,6 @@
# 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.15 as download
ARG JETBRAINS_BACKEND_URL
WORKDIR /workdir
Expand All @@ -19,5 +14,5 @@ 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/
COPY --chown=33333:33333 components-ide-jetbrains-image-status--app/status /ide-desktop/
13 changes: 2 additions & 11 deletions components/ide/jetbrains/image/startup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,7 @@ set -euo pipefail
trap "jobs -p | xargs -r kill" SIGINT SIGTERM EXIT

/ide-desktop/status "$1" "$2" &

echo "Desktop IDE: Waiting for the content initializer ..."
until curl -sS "$SUPERVISOR_ADDR"/_supervisor/v1/status/content/wait/true | grep '"available":true' > /dev/null; do
sleep 1
done
echo "Desktop IDE: Content available."

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" > >(sed 's/^/JetBrains remote-dev-server.sh (out): /') 2> >(sed 's/^/JetBrains remote-dev-server.sh (err): /' >&2)
/ide-desktop/backend/bin/remote-dev-server.sh run "$GITPOD_REPO_ROOT" > >(sed 's/^/JetBrains remote-dev-server.sh (out): /') 2> >(sed 's/^/JetBrains remote-dev-server.sh (err): /' >&2)

echo "Desktop IDE startup script exited"
echo "Desktop IDE startup script exited"
14 changes: 14 additions & 0 deletions components/ide/jetbrains/image/status/BUILD.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
packages:
- name: app
type: go
srcs:
- "**/*.go"
- "go.mod"
- "go.sum"
env:
- CGO_ENABLED=0
- GOOS=linux
deps:
- components/supervisor-api/go:lib
config:
packaging: app
18 changes: 18 additions & 0 deletions components/ide/jetbrains/image/status/go.mod
Original file line number Diff line number Diff line change
@@ -1,3 +1,21 @@
module github.com/gitpod-io/gitpod/jetbrains/status

go 1.17


require google.golang.org/grpc v1.42.0

require github.com/grpc-ecosystem/grpc-gateway/v2 v2.5.0 // indirect

require (
github.com/gitpod-io/gitpod/supervisor/api v0.0.0-00010101000000-000000000000
github.com/golang/protobuf v1.5.2 // indirect
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4 // indirect
golang.org/x/sys v0.0.0-20210510120138-977fb7262007 // indirect
golang.org/x/text v0.3.5 // indirect
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1
google.golang.org/genproto v0.0.0-20210617175327-b9e0b3197ced // indirect
google.golang.org/protobuf v1.27.1 // indirect
)

replace github.com/gitpod-io/gitpod/supervisor/api => ../../../../supervisor-api/go // leeway
410 changes: 410 additions & 0 deletions components/ide/jetbrains/image/status/go.sum

Large diffs are not rendered by default.

78 changes: 35 additions & 43 deletions components/ide/jetbrains/image/status/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,75 +5,50 @@
package main

import (
"context"
"encoding/json"
"fmt"
"io/ioutil"
"log"
"net/http"
"net/url"
"os"
"time"

supervisor "github.com/gitpod-io/gitpod/supervisor/api"
"golang.org/x/xerrors"
"google.golang.org/grpc"
)

// 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 <port> [<link label>]\n", os.Args[0])
os.Exit(1)
}
port := os.Args[1]
label := "Open JetBrains IDE"

label := "Open in Jetbrain Gateway"
if len(os.Args) > 2 {
label = os.Args[2]
}

errlog := log.New(os.Stderr, "JetBrains IDE status: ", log.LstdFlags)
errlog := log.New(os.Stderr, "Jetbrains IDE status: ", log.LstdFlags)

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)
wsInfo, err := GetWSInfo(context.Background())
if err != nil {
errlog.Printf("Error reading body: %v\n", err)
errlog.Printf("cannot get workspace info: %v\n", err)
http.Error(w, err.Error(), http.StatusServiceUnavailable)
return
}

if resp.StatusCode != http.StatusOK {
errlog.Printf("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"`
//jetbrains-gateway://connect#idePath=%2Fworkspace%2FIDE&projectPath=%2Fworkspace%2Ftemplate-golang-cli&host=35.205.211.83&port=22&user=10.96.17.249&type=ssh&deploy=false
hash := fmt.Sprintf("idePath=%s&projectPath=%s&host=%s&port=22&user=%s&type=ssh&deploy=false", url.QueryEscape("/ide-desktop/backend"), url.QueryEscape(wsInfo.CheckoutLocation), "35.205.160.148", url.QueryEscape(wsInfo.WorkspaceId))
fmt.Println(hash)
link := url.URL{
Scheme: "jetbrains-gateway",
Host: "connect",
}
jsonResp := &Response{}
err = json.Unmarshal(bodyBytes, &jsonResp)

if err != nil {
errlog.Printf("Error parsing JSON body from IDE status probe: %v\n", err)
http.Error(w, "Error parsing JSON body from IDE status probe.", http.StatusServiceUnavailable)
return
}
if len(jsonResp.Projects) != 1 {
errlog.Printf("projects size != 1\n")
http.Error(w, "projects size != 1", http.StatusServiceUnavailable)
return
}
response := make(map[string]string)
response["link"] = jsonResp.Projects[0].JoinLink
response["link"] = link.String() + "#" + hash
response["label"] = label
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(response)
Expand All @@ -84,3 +59,20 @@ func main() {
log.Fatal(err)
}
}

func GetWSInfo(ctx context.Context) (*supervisor.WorkspaceInfoResponse, error) {
supervisorAddr := os.Getenv("SUPERVISOR_ADDR")
if supervisorAddr == "" {
supervisorAddr = "localhost:22999"
}
supervisorConn, err := grpc.Dial(supervisorAddr, grpc.WithInsecure())
if err != nil {
return nil, xerrors.Errorf("failed connecting to supervisor: %w", err)
}
defer supervisorConn.Close()
wsinfo, err := supervisor.NewInfoServiceClient(supervisorConn).WorkspaceInfo(ctx, &supervisor.WorkspaceInfoRequest{})
if err != nil {
return nil, xerrors.Errorf("failed getting workspace info from supervisor: %w", err)
}
return wsinfo, nil
}
Loading