Skip to content

Commit 7f5dcc3

Browse files
authored
feat: remove server subcommand from slim binaries (#5747)
1 parent 1b0560c commit 7f5dcc3

File tree

9 files changed

+170
-29
lines changed

9 files changed

+170
-29
lines changed

buildinfo/buildinfo.go

+16-2
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,12 @@ var (
2121
version string
2222
readVersion sync.Once
2323

24-
// Injected with ldflags at build!
25-
tag string
24+
// Updated by buildinfo_slim.go on start.
25+
slim bool
26+
27+
// Injected with ldflags at build, see scripts/build_go.sh
28+
tag string
29+
agpl string // either "true" or "false", ldflags does not support bools
2630
)
2731

2832
const (
@@ -73,6 +77,16 @@ func IsDev() bool {
7377
return strings.HasPrefix(Version(), develPrefix)
7478
}
7579

80+
// IsSlim returns true if this is a slim build.
81+
func IsSlim() bool {
82+
return slim
83+
}
84+
85+
// IsAGPL returns true if this is an AGPL build.
86+
func IsAGPL() bool {
87+
return strings.Contains(agpl, "t")
88+
}
89+
7690
// ExternalURL returns a URL referencing the current Coder version.
7791
// For production builds, this will link directly to a release.
7892
// For development builds, this will link to a commit.

buildinfo/buildinfo_slim.go

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
//go:build slim
2+
3+
package buildinfo
4+
5+
func init() {
6+
slim = true
7+
}

cli/agent.go

+23
Original file line numberDiff line numberDiff line change
@@ -181,3 +181,26 @@ func workspaceAgent() *cobra.Command {
181181
cliflag.StringVarP(cmd.Flags(), &pprofAddress, "pprof-address", "", "CODER_AGENT_PPROF_ADDRESS", "127.0.0.1:6060", "The address to serve pprof.")
182182
return cmd
183183
}
184+
185+
func serveHandler(ctx context.Context, logger slog.Logger, handler http.Handler, addr, name string) (closeFunc func()) {
186+
logger.Debug(ctx, "http server listening", slog.F("addr", addr), slog.F("name", name))
187+
188+
// ReadHeaderTimeout is purposefully not enabled. It caused some issues with
189+
// websockets over the dev tunnel.
190+
// See: https://github.com/coder/coder/pull/3730
191+
//nolint:gosec
192+
srv := &http.Server{
193+
Addr: addr,
194+
Handler: handler,
195+
}
196+
go func() {
197+
err := srv.ListenAndServe()
198+
if err != nil && !xerrors.Is(err, http.ErrServerClosed) {
199+
logger.Error(ctx, "http server listen", slog.F("name", name), slog.Error(err))
200+
}
201+
}()
202+
203+
return func() {
204+
_ = srv.Close()
205+
}
206+
}

cli/root.go

+12-2
Original file line numberDiff line numberDiff line change
@@ -213,12 +213,22 @@ func versionCmd() *cobra.Command {
213213
Short: "Show coder version",
214214
RunE: func(cmd *cobra.Command, args []string) error {
215215
var str strings.Builder
216-
_, _ = str.WriteString(fmt.Sprintf("Coder %s", buildinfo.Version()))
216+
_, _ = str.WriteString("Coder ")
217+
if buildinfo.IsAGPL() {
218+
_, _ = str.WriteString("(AGPL) ")
219+
}
220+
_, _ = str.WriteString(buildinfo.Version())
217221
buildTime, valid := buildinfo.Time()
218222
if valid {
219223
_, _ = str.WriteString(" " + buildTime.Format(time.UnixDate))
220224
}
221-
_, _ = str.WriteString("\r\n" + buildinfo.ExternalURL() + "\r\n")
225+
_, _ = str.WriteString("\r\n" + buildinfo.ExternalURL() + "\r\n\r\n")
226+
227+
if buildinfo.IsSlim() {
228+
_, _ = str.WriteString(fmt.Sprintf("Slim build of Coder, does not support the %s subcommand.\n", cliui.Styles.Code.Render("server")))
229+
} else {
230+
_, _ = str.WriteString(fmt.Sprintf("Full build of Coder, supports the %s subcommand.\n", cliui.Styles.Code.Render("server")))
231+
}
222232

223233
_, _ = fmt.Fprint(cmd.OutOrStdout(), str.String())
224234
return nil

cli/server.go

+2-23
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
//go:build !slim
2+
13
package cli
24

35
import (
@@ -1370,29 +1372,6 @@ func configureGithubOAuth2(accessURL *url.URL, clientID, clientSecret string, al
13701372
}, nil
13711373
}
13721374

1373-
func serveHandler(ctx context.Context, logger slog.Logger, handler http.Handler, addr, name string) (closeFunc func()) {
1374-
logger.Debug(ctx, "http server listening", slog.F("addr", addr), slog.F("name", name))
1375-
1376-
// ReadHeaderTimeout is purposefully not enabled. It caused some issues with
1377-
// websockets over the dev tunnel.
1378-
// See: https://github.com/coder/coder/pull/3730
1379-
//nolint:gosec
1380-
srv := &http.Server{
1381-
Addr: addr,
1382-
Handler: handler,
1383-
}
1384-
go func() {
1385-
err := srv.ListenAndServe()
1386-
if err != nil && !xerrors.Is(err, http.ErrServerClosed) {
1387-
logger.Error(ctx, "http server listen", slog.F("name", name), slog.Error(err))
1388-
}
1389-
}()
1390-
1391-
return func() {
1392-
_ = srv.Close()
1393-
}
1394-
}
1395-
13961375
// embeddedPostgresURL returns the URL for the embedded PostgreSQL deployment.
13971376
func embeddedPostgresURL(cfg config.Root) (string, error) {
13981377
pgPassword, err := cfg.PostgresPassword().Read()

cli/server_slim.go

+68
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
//go:build slim
2+
3+
package cli
4+
5+
import (
6+
"context"
7+
"fmt"
8+
"io"
9+
"os"
10+
11+
"github.com/spf13/cobra"
12+
"github.com/spf13/viper"
13+
14+
"github.com/coder/coder/cli/cliui"
15+
"github.com/coder/coder/cli/deployment"
16+
"github.com/coder/coder/coderd"
17+
)
18+
19+
func Server(vip *viper.Viper, _ func(context.Context, *coderd.Options) (*coderd.API, io.Closer, error)) *cobra.Command {
20+
root := &cobra.Command{
21+
Use: "server",
22+
Short: "Start a Coder server",
23+
Hidden: true,
24+
RunE: func(cmd *cobra.Command, args []string) error {
25+
serverUnsupported(cmd.ErrOrStderr())
26+
return nil
27+
},
28+
}
29+
30+
var pgRawURL bool
31+
postgresBuiltinURLCmd := &cobra.Command{
32+
Use: "postgres-builtin-url",
33+
Short: "Output the connection URL for the built-in PostgreSQL deployment.",
34+
Hidden: true,
35+
RunE: func(cmd *cobra.Command, _ []string) error {
36+
serverUnsupported(cmd.ErrOrStderr())
37+
return nil
38+
},
39+
}
40+
postgresBuiltinServeCmd := &cobra.Command{
41+
Use: "postgres-builtin-serve",
42+
Short: "Run the built-in PostgreSQL deployment.",
43+
Hidden: true,
44+
RunE: func(cmd *cobra.Command, args []string) error {
45+
serverUnsupported(cmd.ErrOrStderr())
46+
return nil
47+
},
48+
}
49+
50+
// We still have to attach the flags to the commands so users don't get
51+
// an error when they try to use them.
52+
postgresBuiltinURLCmd.Flags().BoolVar(&pgRawURL, "raw-url", false, "Output the raw connection URL instead of a psql command.")
53+
postgresBuiltinServeCmd.Flags().BoolVar(&pgRawURL, "raw-url", false, "Output the raw connection URL instead of a psql command.")
54+
55+
root.AddCommand(postgresBuiltinURLCmd, postgresBuiltinServeCmd)
56+
57+
deployment.AttachFlags(root.Flags(), vip, false)
58+
59+
return root
60+
}
61+
62+
func serverUnsupported(w io.Writer) {
63+
_, _ = fmt.Fprintf(w, "You are using a 'slim' build of Coder, which does not support the %s subcommand.\n", cliui.Styles.Code.Render("server"))
64+
_, _ = fmt.Fprintln(w, "")
65+
_, _ = fmt.Fprintln(w, "Please use a build of Coder from GitHub releases:")
66+
_, _ = fmt.Fprintln(w, " https://github.com/coder/coder/releases")
67+
os.Exit(1)
68+
}

enterprise/cli/server.go

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
//go:build !slim
2+
13
package cli
24

35
import (

enterprise/cli/server_slim.go

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
//go:build slim
2+
3+
package cli
4+
5+
import (
6+
"context"
7+
"io"
8+
9+
"github.com/spf13/cobra"
10+
"golang.org/x/xerrors"
11+
12+
"github.com/coder/coder/cli/deployment"
13+
14+
agpl "github.com/coder/coder/cli"
15+
agplcoderd "github.com/coder/coder/coderd"
16+
)
17+
18+
func server() *cobra.Command {
19+
vip := deployment.NewViper()
20+
cmd := agpl.Server(vip, func(ctx context.Context, options *agplcoderd.Options) (*agplcoderd.API, io.Closer, error) {
21+
return nil, nil, xerrors.Errorf("slim build does not support `coder server`")
22+
})
23+
24+
deployment.AttachFlags(cmd.Flags(), vip, true)
25+
26+
return cmd
27+
}

scripts/build_go.sh

+13-2
Original file line numberDiff line numberDiff line change
@@ -93,12 +93,23 @@ if [[ "$sign_darwin" == 1 ]]; then
9393
requiredenvs AC_CERTIFICATE_FILE AC_CERTIFICATE_PASSWORD_FILE
9494
fi
9595

96-
build_args=(
97-
-ldflags "-s -w -X 'github.com/coder/coder/buildinfo.tag=$version'"
96+
ldflags=(
97+
-s
98+
-w
99+
-X "'github.com/coder/coder/buildinfo.tag=$version'"
98100
)
101+
99102
if [[ "$slim" == 0 ]]; then
100103
build_args+=(-tags embed)
104+
else
105+
build_args+=(-tags slim)
106+
fi
107+
if [[ "$agpl" == 1 ]]; then
108+
# We don't use a tag to control AGPL because we don't want code to depend on
109+
# a flag to control AGPL vs. enterprise behavior.
110+
ldflags+=(-X "'github.com/coder/coder/buildinfo.agpl=true'")
101111
fi
112+
build_args+=(-ldflags "${ldflags[*]}")
102113

103114
# Compute default output path.
104115
if [[ "$output_path" == "" ]]; then

0 commit comments

Comments
 (0)