Skip to content

Commit b894407

Browse files
chore: improve coder server ux (#14761)
1 parent a3ebcd7 commit b894407

File tree

9 files changed

+46
-25
lines changed

9 files changed

+46
-25
lines changed

cli/cliui/cliui.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ type Styles struct {
2222
DateTimeStamp,
2323
Error,
2424
Field,
25+
Hyperlink,
2526
Keyword,
2627
Placeholder,
2728
Prompt,
@@ -149,6 +150,10 @@ func init() {
149150
pretty.Wrap("> ", ""),
150151
pretty.FgColor(brightBlue),
151152
},
153+
Hyperlink: pretty.Style{
154+
pretty.FgColor(magenta),
155+
pretty.Underline(),
156+
},
152157
Keyword: pretty.Style{
153158
pretty.FgColor(green),
154159
},

cli/login.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -416,6 +416,9 @@ func isWSL() (bool, error) {
416416

417417
// openURL opens the provided URL via user's default browser
418418
func openURL(inv *serpent.Invocation, urlToOpen string) error {
419+
if !isTTYOut(inv) {
420+
return xerrors.New("skipping browser open in non-interactive mode")
421+
}
419422
noOpen, err := inv.ParsedFlags().GetBool(varNoOpen)
420423
if err != nil {
421424
panic(err)

cli/root.go

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -695,14 +695,7 @@ func namedWorkspace(ctx context.Context, client *codersdk.Client, identifier str
695695
func initAppearance(client *codersdk.Client, outConfig *codersdk.AppearanceConfig) serpent.MiddlewareFunc {
696696
return func(next serpent.HandlerFunc) serpent.HandlerFunc {
697697
return func(inv *serpent.Invocation) error {
698-
var err error
699-
cfg, err := client.Appearance(inv.Context())
700-
if err != nil {
701-
var sdkErr *codersdk.Error
702-
if !(xerrors.As(err, &sdkErr) && sdkErr.StatusCode() == http.StatusNotFound) {
703-
return err
704-
}
705-
}
698+
cfg, _ := client.Appearance(inv.Context())
706699
if cfg.DocsURL == "" {
707700
cfg.DocsURL = codersdk.DefaultDocsURL()
708701
}

cli/server.go

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import (
3232
"sync/atomic"
3333
"time"
3434

35+
"github.com/charmbracelet/lipgloss"
3536
"github.com/coreos/go-oidc/v3/oidc"
3637
"github.com/coreos/go-systemd/daemon"
3738
embeddedpostgres "github.com/fergusstrange/embedded-postgres"
@@ -483,8 +484,15 @@ func (r *RootCmd) Server(newAPI func(context.Context, *coderd.Options) (*coderd.
483484
)
484485
}
485486

486-
// A newline is added before for visibility in terminal output.
487-
cliui.Infof(inv.Stdout, "\nView the Web UI: %s", vals.AccessURL.String())
487+
accessURL := vals.AccessURL.String()
488+
cliui.Infof(inv.Stdout, lipgloss.NewStyle().
489+
Border(lipgloss.DoubleBorder()).
490+
Align(lipgloss.Center).
491+
Padding(0, 3).
492+
BorderForeground(lipgloss.Color("12")).
493+
Render(fmt.Sprintf("View the Web UI:\n%s",
494+
pretty.Sprint(cliui.DefaultStyles.Hyperlink, accessURL))))
495+
_ = openURL(inv, accessURL)
488496

489497
// Used for zero-trust instance identity with Google Cloud.
490498
googleTokenValidator, err := idtoken.NewValidator(ctx, option.WithoutAuthentication())
@@ -1438,6 +1446,7 @@ func newProvisionerDaemon(
14381446

14391447
// Omit any duplicates
14401448
provisionerTypes = slice.Unique(provisionerTypes)
1449+
provisionerLogger := logger.Named(fmt.Sprintf("provisionerd-%s", name))
14411450

14421451
// Populate the connector with the supported types.
14431452
connector := provisionerd.LocalProvisioners{}
@@ -1494,7 +1503,7 @@ func newProvisionerDaemon(
14941503
err := terraform.Serve(ctx, &terraform.ServeOptions{
14951504
ServeOptions: &provisionersdk.ServeOptions{
14961505
Listener: terraformServer,
1497-
Logger: logger.Named("terraform"),
1506+
Logger: provisionerLogger,
14981507
WorkDirectory: workDir,
14991508
},
15001509
CachePath: tfDir,
@@ -1519,7 +1528,7 @@ func newProvisionerDaemon(
15191528
// in provisionerdserver.go to learn more!
15201529
return coderAPI.CreateInMemoryProvisionerDaemon(dialCtx, name, provisionerTypes)
15211530
}, &provisionerd.Options{
1522-
Logger: logger.Named(fmt.Sprintf("provisionerd-%s", name)),
1531+
Logger: provisionerLogger,
15231532
UpdateInterval: time.Second,
15241533
ForceCancelInterval: cfg.Provisioner.ForceCancelInterval.Value(),
15251534
Connector: connector,

cli/server_test.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,8 @@ func TestServer(t *testing.T) {
221221
_ = waitAccessURL(t, cfg)
222222

223223
pty.ExpectMatch("this may cause unexpected problems when creating workspaces")
224-
pty.ExpectMatch("View the Web UI: http://localhost:3000/")
224+
pty.ExpectMatch("View the Web UI:")
225+
pty.ExpectMatch("http://localhost:3000/")
225226
})
226227

227228
// Validate that an https scheme is prepended to a remote access URL
@@ -244,7 +245,8 @@ func TestServer(t *testing.T) {
244245
_ = waitAccessURL(t, cfg)
245246

246247
pty.ExpectMatch("this may cause unexpected problems when creating workspaces")
247-
pty.ExpectMatch("View the Web UI: https://foobarbaz.mydomain")
248+
pty.ExpectMatch("View the Web UI:")
249+
pty.ExpectMatch("https://foobarbaz.mydomain")
248250
})
249251

250252
t.Run("NoWarningWithRemoteAccessURL", func(t *testing.T) {
@@ -262,7 +264,8 @@ func TestServer(t *testing.T) {
262264
// Just wait for startup
263265
_ = waitAccessURL(t, cfg)
264266

265-
pty.ExpectMatch("View the Web UI: https://google.com")
267+
pty.ExpectMatch("View the Web UI:")
268+
pty.ExpectMatch("https://google.com")
266269
})
267270

268271
t.Run("NoSchemeAccessURL", func(t *testing.T) {

coderd/coderd.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1505,7 +1505,7 @@ func (api *API) CreateInMemoryTaggedProvisionerDaemon(dialCtx context.Context, n
15051505
}
15061506

15071507
mux := drpcmux.New()
1508-
api.Logger.Info(dialCtx, "starting in-memory provisioner daemon", slog.F("name", name))
1508+
api.Logger.Debug(dialCtx, "starting in-memory provisioner daemon", slog.F("name", name))
15091509
logger := api.Logger.Named(fmt.Sprintf("inmem-provisionerd-%s", name))
15101510
srv, err := provisionerdserver.NewServer(
15111511
api.ctx, // use the same ctx as the API

coderd/database/pubsub/pubsub.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -413,15 +413,15 @@ func (d logDialer) DialContext(ctx context.Context, network, address string) (ne
413413

414414
logger := d.logger.With(slog.F("network", network), slog.F("address", address), slog.F("timeout_ms", timeoutMS))
415415

416-
logger.Info(ctx, "pubsub dialing postgres")
416+
logger.Debug(ctx, "pubsub dialing postgres")
417417
start := time.Now()
418418
conn, err := d.d.DialContext(ctx, network, address)
419419
if err != nil {
420420
logger.Error(ctx, "pubsub failed to dial postgres")
421421
return nil, err
422422
}
423423
elapsed := time.Since(start)
424-
logger.Info(ctx, "pubsub postgres TCP connection established", slog.F("elapsed_ms", elapsed.Milliseconds()))
424+
logger.Debug(ctx, "pubsub postgres TCP connection established", slog.F("elapsed_ms", elapsed.Milliseconds()))
425425
return conn, nil
426426
}
427427

@@ -466,7 +466,7 @@ func (p *PGPubsub) startListener(ctx context.Context, connectURL string) error {
466466
Listener: pq.NewConnectorListener(connector, connectURL, time.Second, time.Minute, func(t pq.ListenerEventType, err error) {
467467
switch t {
468468
case pq.ListenerEventConnected:
469-
p.logger.Info(ctx, "pubsub connected to postgres")
469+
p.logger.Debug(ctx, "pubsub connected to postgres")
470470
p.connected.Set(1.0)
471471
case pq.ListenerEventDisconnected:
472472
p.logger.Error(ctx, "pubsub disconnected from postgres", slog.Error(err))
@@ -618,7 +618,7 @@ func New(startCtx context.Context, logger slog.Logger, db *sql.DB, connectURL st
618618
return nil, err
619619
}
620620
go p.listen()
621-
logger.Info(startCtx, "pubsub has started")
621+
logger.Debug(startCtx, "pubsub has started")
622622
return p, nil
623623
}
624624

enterprise/cli/proxyserver.go

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414
rpprof "runtime/pprof"
1515
"time"
1616

17+
"github.com/charmbracelet/lipgloss"
1718
"github.com/coreos/go-systemd/daemon"
1819
"github.com/prometheus/client_golang/prometheus"
1920
"github.com/prometheus/client_golang/prometheus/collectors"
@@ -29,6 +30,7 @@ import (
2930
"github.com/coder/coder/v2/coderd/workspaceapps/appurl"
3031
"github.com/coder/coder/v2/codersdk"
3132
"github.com/coder/coder/v2/enterprise/wsproxy"
33+
"github.com/coder/pretty"
3234
"github.com/coder/serpent"
3335
)
3436

@@ -202,8 +204,14 @@ func (r *RootCmd) proxyServer() *serpent.Command {
202204
headerTransport.Transport = httpClient.Transport
203205
httpClient.Transport = headerTransport
204206

205-
// A newline is added before for visibility in terminal output.
206-
cliui.Infof(inv.Stdout, "\nView the Web UI: %s", cfg.AccessURL.String())
207+
accessURL := cfg.AccessURL.String()
208+
cliui.Infof(inv.Stdout, lipgloss.NewStyle().
209+
Border(lipgloss.DoubleBorder()).
210+
Align(lipgloss.Center).
211+
Padding(0, 3).
212+
BorderForeground(lipgloss.Color("12")).
213+
Render(fmt.Sprintf("View the Web UI:\n%s",
214+
pretty.Sprint(cliui.DefaultStyles.Hyperlink, accessURL))))
207215

208216
var appHostnameRegex *regexp.Regexp
209217
appHostname := cfg.WildcardAccessURL.String()

tailnet/configmaps.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -147,22 +147,22 @@ func (c *configMaps) configLoop() {
147147
if c.derpMapDirty {
148148
derpMap := c.derpMapLocked()
149149
actions = append(actions, func() {
150-
c.logger.Info(context.Background(), "updating engine DERP map", slog.F("derp_map", (*derpMapStringer)(derpMap)))
150+
c.logger.Debug(context.Background(), "updating engine DERP map", slog.F("derp_map", (*derpMapStringer)(derpMap)))
151151
c.engine.SetDERPMap(derpMap)
152152
})
153153
}
154154
if c.netmapDirty {
155155
nm := c.netMapLocked()
156156
actions = append(actions, func() {
157-
c.logger.Info(context.Background(), "updating engine network map", slog.F("network_map", nm))
157+
c.logger.Debug(context.Background(), "updating engine network map", slog.F("network_map", nm))
158158
c.engine.SetNetworkMap(nm)
159159
c.reconfig(nm)
160160
})
161161
}
162162
if c.filterDirty {
163163
f := c.filterLocked()
164164
actions = append(actions, func() {
165-
c.logger.Info(context.Background(), "updating engine filter", slog.F("filter", f))
165+
c.logger.Debug(context.Background(), "updating engine filter", slog.F("filter", f))
166166
c.engine.SetFilter(f)
167167
})
168168
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy