Skip to content

Commit 3ecb0f7

Browse files
easyCZroboquat
authored andcommitted
Cleanup local-app entrypoint
1 parent e30502e commit 3ecb0f7

File tree

2 files changed

+67
-39
lines changed

2 files changed

+67
-39
lines changed

components/local-app/main.go

Lines changed: 41 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,10 @@ package main
77
import (
88
_ "embed"
99
"path/filepath"
10-
"runtime"
1110
"strconv"
1211
"time"
1312

1413
"context"
15-
"log"
1614
"net/http"
1715
"net/url"
1816
"os"
@@ -25,26 +23,22 @@ import (
2523
"github.com/gitpod-io/local-app/pkg/bastion"
2624
"github.com/improbable-eng/grpc-web/go/grpcweb"
2725
"github.com/sirupsen/logrus"
28-
cli "github.com/urfave/cli/v2"
29-
keyring "github.com/zalando/go-keyring"
26+
"github.com/urfave/cli/v2"
27+
"github.com/zalando/go-keyring"
3028
"google.golang.org/grpc"
3129
)
3230

3331
var (
3432
// Version : current version
35-
Version string = strings.TrimSpace(version)
33+
Version = strings.TrimSpace(version)
3634
//go:embed version.txt
3735
version string
3836
)
3937

4038
func main() {
4139
sshConfig := os.Getenv("GITPOD_LCA_SSH_CONFIG")
4240
if sshConfig == "" {
43-
if runtime.GOOS == "windows" {
44-
sshConfig = filepath.Join(os.TempDir(), "gitpod_ssh_config")
45-
} else {
46-
sshConfig = filepath.Join("/tmp", "gitpod_ssh_config")
47-
}
41+
sshConfig = filepath.Join(os.TempDir(), "gitpod_ssh_config")
4842
}
4943

5044
app := cli.App{
@@ -124,8 +118,17 @@ func main() {
124118
if c.Bool("mock-keyring") {
125119
keyring.MockInit()
126120
}
127-
return run(c.String("gitpod-host"), c.String("ssh_config"), c.Int("api-port"), c.Bool("allow-cors-from-port"),
128-
c.Bool("auto-tunnel"), c.String("auth-redirect-url"), c.Bool("verbose"), c.Duration("auth-timeout"), c.Duration("timeout"))
121+
return run(runOptions{
122+
origin: c.String("gitpod-host"),
123+
sshConfigPath: c.String("ssh_config"),
124+
apiPort: c.Int("api-port"),
125+
allowCORSFromPort: c.Bool("allow-cors-from-port"),
126+
autoTunnel: c.Bool("auto-tunnel"),
127+
authRedirectURL: c.String("auth-redirect-url"),
128+
verbose: c.Bool("verbose"),
129+
authTimeout: c.Duration("auth-timeout"),
130+
localAppTimeout: c.Duration("timeout"),
131+
})
129132
},
130133
Flags: []cli.Flag{
131134
&cli.PathFlag{
@@ -139,7 +142,7 @@ func main() {
139142
}
140143
err := app.Run(os.Args)
141144
if err != nil {
142-
log.Fatal(err)
145+
logrus.WithError(err).Fatal("Failed to start application.")
143146
}
144147
}
145148

@@ -149,21 +152,33 @@ func DefaultCommand(name string) cli.ActionFunc {
149152
}
150153
}
151154

152-
func run(origin, sshConfig string, apiPort int, allowCORSFromPort bool, autoTunnel bool, authRedirectUrl string, verbose bool, authTimeout time.Duration, localAppTimeout time.Duration) error {
153-
if verbose {
155+
type runOptions struct {
156+
origin string
157+
sshConfigPath string
158+
apiPort int
159+
allowCORSFromPort bool
160+
autoTunnel bool
161+
authRedirectURL string
162+
verbose bool
163+
authTimeout time.Duration
164+
localAppTimeout time.Duration
165+
}
166+
167+
func run(opts runOptions) error {
168+
if opts.verbose {
154169
logrus.SetLevel(logrus.DebugLevel)
155170
}
156-
logrus.WithField("ssh_config", sshConfig).Info("writing workspace ssh_config file")
171+
logrus.WithField("ssh_config", opts.sshConfigPath).Info("writing workspace ssh_config file")
157172

158173
// Trailing slash(es) result in connection issues, so remove them preemptively
159-
origin = strings.TrimRight(origin, "/")
174+
origin := strings.TrimRight(opts.origin, "/")
160175
originURL, err := url.Parse(origin)
161176
if err != nil {
162177
return err
163178
}
164179
wsHostRegex := "(\\.[^.]+)\\." + strings.ReplaceAll(originURL.Host, ".", "\\.")
165180
wsHostRegex = "([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}|[0-9a-z]{2,16}-[0-9a-z]{2,16}-[0-9a-z]{8,11})" + wsHostRegex
166-
if allowCORSFromPort {
181+
if opts.allowCORSFromPort {
167182
wsHostRegex = "([0-9]+)-" + wsHostRegex
168183
}
169184
hostRegex, err := regexp.Compile("^" + wsHostRegex)
@@ -173,7 +188,7 @@ func run(origin, sshConfig string, apiPort int, allowCORSFromPort bool, autoTunn
173188

174189
var b *bastion.Bastion
175190

176-
client, err := connectToServer(auth.LoginOpts{GitpodURL: origin, RedirectURL: authRedirectUrl, AuthTimeout: authTimeout}, func() {
191+
client, err := connectToServer(auth.LoginOpts{GitpodURL: origin, RedirectURL: opts.authRedirectURL, AuthTimeout: opts.authTimeout}, func() {
177192
if b != nil {
178193
b.FullUpdate()
179194
}
@@ -188,21 +203,22 @@ func run(origin, sshConfig string, apiPort int, allowCORSFromPort bool, autoTunn
188203
cb := bastion.CompositeCallbacks{
189204
&logCallbacks{},
190205
}
191-
s := &bastion.SSHConfigWritingCallback{Path: sshConfig}
192-
if sshConfig != "" {
206+
207+
s := &bastion.SSHConfigWritingCallback{Path: opts.sshConfigPath}
208+
if opts.sshConfigPath != "" {
193209
cb = append(cb, s)
194210
}
195211

196-
b = bastion.New(client, localAppTimeout, cb)
197-
b.EnableAutoTunnel = autoTunnel
212+
b = bastion.New(client, opts.localAppTimeout, cb)
213+
b.EnableAutoTunnel = opts.autoTunnel
198214
grpcServer := grpc.NewServer()
199215
appapi.RegisterLocalAppServer(grpcServer, bastion.NewLocalAppService(b, s))
200216
allowOrigin := func(origin string) bool {
201217
// Is the origin a subdomain of the installations hostname?
202218
return hostRegex.Match([]byte(origin))
203219
}
204220
go func() {
205-
err := http.ListenAndServe("localhost:"+strconv.Itoa(apiPort), grpcweb.WrapServer(grpcServer,
221+
err := http.ListenAndServe("localhost:"+strconv.Itoa(opts.apiPort), grpcweb.WrapServer(grpcServer,
206222
grpcweb.WithCorsForRegisteredEndpointsOnly(false),
207223
grpcweb.WithOriginFunc(allowOrigin),
208224
grpcweb.WithWebsockets(true),
@@ -312,5 +328,5 @@ func login(loginOpts auth.LoginOpts) (string, error) {
312328
type logCallbacks struct{}
313329

314330
func (*logCallbacks) InstanceUpdate(w *bastion.Workspace) {
315-
logrus.WithField("workspace", w).Info("instance update")
331+
logrus.WithField("workspace", w).Info("Instance update")
316332
}

components/local-app/pkg/auth/auth.go

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -120,26 +120,25 @@ const html = `
120120
</html>`
121121

122122
// NOTE: the port ranges all need to be valid redirect URI's in the backend
123-
const STARTING_PORT_NUM = 63110
124-
const ENDING_PORT_NUM = 63120
123+
const (
124+
StartingPortNum = 63110
125+
EndingPortNum = 63120
126+
)
125127

126128
// Login walks through the login flow for obtaining a Gitpod token
127129
func Login(ctx context.Context, opts LoginOpts) (token string, err error) {
128130
// Try a range of ports for local redirect server
129-
var rl net.Listener
130-
var port int
131-
for port = STARTING_PORT_NUM; port < ENDING_PORT_NUM || rl == nil; port++ {
132-
rl, err = net.Listen("tcp4", fmt.Sprintf("127.0.0.1:%d", port))
133-
if err != nil {
134-
logrus.Infof("Could not open port:%d got error:%s\nTrying next port\n", port, err)
135-
continue
136-
}
137-
defer rl.Close()
138-
}
139-
if rl == nil {
140-
return "", xerrors.Errorf("could not open any valid port in range %d - %d", STARTING_PORT_NUM, ENDING_PORT_NUM)
131+
rl, port, err := findOpenPortInRange(StartingPortNum, EndingPortNum)
132+
if err != nil {
133+
return "", err
141134
}
142135

136+
defer func() {
137+
if closeErr := rl.Close(); closeErr != nil {
138+
logrus.WithField("port", port).WithError(closeErr).Warn("Failed to to close listener")
139+
}
140+
}()
141+
143142
var (
144143
errChan = make(chan error, 1)
145144
queryChan = make(chan url.Values, 1)
@@ -244,3 +243,16 @@ func Login(ctx context.Context, opts LoginOpts) (token string, err error) {
244243
gitpodToken := claims["jti"].(string)
245244
return gitpodToken, nil
246245
}
246+
247+
func findOpenPortInRange(start, end int) (net.Listener, int, error) {
248+
for port := start; port < end; port++ {
249+
rl, err := net.Listen("tcp4", fmt.Sprintf("127.0.0.1:%d", port))
250+
if err != nil {
251+
logrus.WithField("port", port).WithError(err).Info("Could not open port, trying next port")
252+
continue
253+
}
254+
255+
return rl, port, nil
256+
}
257+
return nil, 0, xerrors.Errorf("could not open any valid port in range %d - %d", start, end)
258+
}

0 commit comments

Comments
 (0)