feat: remove server subcommand from slim binaries (#5747)

This commit is contained in:
Dean Sheather 2023-01-17 10:58:00 -06:00 committed by GitHub
parent 1b0560ceb4
commit 7f5dcc3d6c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 170 additions and 29 deletions

View File

@ -21,8 +21,12 @@ var (
version string
readVersion sync.Once
// Injected with ldflags at build!
tag string
// Updated by buildinfo_slim.go on start.
slim bool
// Injected with ldflags at build, see scripts/build_go.sh
tag string
agpl string // either "true" or "false", ldflags does not support bools
)
const (
@ -73,6 +77,16 @@ func IsDev() bool {
return strings.HasPrefix(Version(), develPrefix)
}
// IsSlim returns true if this is a slim build.
func IsSlim() bool {
return slim
}
// IsAGPL returns true if this is an AGPL build.
func IsAGPL() bool {
return strings.Contains(agpl, "t")
}
// ExternalURL returns a URL referencing the current Coder version.
// For production builds, this will link directly to a release.
// For development builds, this will link to a commit.

View File

@ -0,0 +1,7 @@
//go:build slim
package buildinfo
func init() {
slim = true
}

View File

@ -181,3 +181,26 @@ func workspaceAgent() *cobra.Command {
cliflag.StringVarP(cmd.Flags(), &pprofAddress, "pprof-address", "", "CODER_AGENT_PPROF_ADDRESS", "127.0.0.1:6060", "The address to serve pprof.")
return cmd
}
func serveHandler(ctx context.Context, logger slog.Logger, handler http.Handler, addr, name string) (closeFunc func()) {
logger.Debug(ctx, "http server listening", slog.F("addr", addr), slog.F("name", name))
// ReadHeaderTimeout is purposefully not enabled. It caused some issues with
// websockets over the dev tunnel.
// See: https://github.com/coder/coder/pull/3730
//nolint:gosec
srv := &http.Server{
Addr: addr,
Handler: handler,
}
go func() {
err := srv.ListenAndServe()
if err != nil && !xerrors.Is(err, http.ErrServerClosed) {
logger.Error(ctx, "http server listen", slog.F("name", name), slog.Error(err))
}
}()
return func() {
_ = srv.Close()
}
}

View File

@ -213,12 +213,22 @@ func versionCmd() *cobra.Command {
Short: "Show coder version",
RunE: func(cmd *cobra.Command, args []string) error {
var str strings.Builder
_, _ = str.WriteString(fmt.Sprintf("Coder %s", buildinfo.Version()))
_, _ = str.WriteString("Coder ")
if buildinfo.IsAGPL() {
_, _ = str.WriteString("(AGPL) ")
}
_, _ = str.WriteString(buildinfo.Version())
buildTime, valid := buildinfo.Time()
if valid {
_, _ = str.WriteString(" " + buildTime.Format(time.UnixDate))
}
_, _ = str.WriteString("\r\n" + buildinfo.ExternalURL() + "\r\n")
_, _ = str.WriteString("\r\n" + buildinfo.ExternalURL() + "\r\n\r\n")
if buildinfo.IsSlim() {
_, _ = str.WriteString(fmt.Sprintf("Slim build of Coder, does not support the %s subcommand.\n", cliui.Styles.Code.Render("server")))
} else {
_, _ = str.WriteString(fmt.Sprintf("Full build of Coder, supports the %s subcommand.\n", cliui.Styles.Code.Render("server")))
}
_, _ = fmt.Fprint(cmd.OutOrStdout(), str.String())
return nil

View File

@ -1,3 +1,5 @@
//go:build !slim
package cli
import (
@ -1370,29 +1372,6 @@ func configureGithubOAuth2(accessURL *url.URL, clientID, clientSecret string, al
}, nil
}
func serveHandler(ctx context.Context, logger slog.Logger, handler http.Handler, addr, name string) (closeFunc func()) {
logger.Debug(ctx, "http server listening", slog.F("addr", addr), slog.F("name", name))
// ReadHeaderTimeout is purposefully not enabled. It caused some issues with
// websockets over the dev tunnel.
// See: https://github.com/coder/coder/pull/3730
//nolint:gosec
srv := &http.Server{
Addr: addr,
Handler: handler,
}
go func() {
err := srv.ListenAndServe()
if err != nil && !xerrors.Is(err, http.ErrServerClosed) {
logger.Error(ctx, "http server listen", slog.F("name", name), slog.Error(err))
}
}()
return func() {
_ = srv.Close()
}
}
// embeddedPostgresURL returns the URL for the embedded PostgreSQL deployment.
func embeddedPostgresURL(cfg config.Root) (string, error) {
pgPassword, err := cfg.PostgresPassword().Read()

68
cli/server_slim.go Normal file
View File

@ -0,0 +1,68 @@
//go:build slim
package cli
import (
"context"
"fmt"
"io"
"os"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"github.com/coder/coder/cli/cliui"
"github.com/coder/coder/cli/deployment"
"github.com/coder/coder/coderd"
)
func Server(vip *viper.Viper, _ func(context.Context, *coderd.Options) (*coderd.API, io.Closer, error)) *cobra.Command {
root := &cobra.Command{
Use: "server",
Short: "Start a Coder server",
Hidden: true,
RunE: func(cmd *cobra.Command, args []string) error {
serverUnsupported(cmd.ErrOrStderr())
return nil
},
}
var pgRawURL bool
postgresBuiltinURLCmd := &cobra.Command{
Use: "postgres-builtin-url",
Short: "Output the connection URL for the built-in PostgreSQL deployment.",
Hidden: true,
RunE: func(cmd *cobra.Command, _ []string) error {
serverUnsupported(cmd.ErrOrStderr())
return nil
},
}
postgresBuiltinServeCmd := &cobra.Command{
Use: "postgres-builtin-serve",
Short: "Run the built-in PostgreSQL deployment.",
Hidden: true,
RunE: func(cmd *cobra.Command, args []string) error {
serverUnsupported(cmd.ErrOrStderr())
return nil
},
}
// We still have to attach the flags to the commands so users don't get
// an error when they try to use them.
postgresBuiltinURLCmd.Flags().BoolVar(&pgRawURL, "raw-url", false, "Output the raw connection URL instead of a psql command.")
postgresBuiltinServeCmd.Flags().BoolVar(&pgRawURL, "raw-url", false, "Output the raw connection URL instead of a psql command.")
root.AddCommand(postgresBuiltinURLCmd, postgresBuiltinServeCmd)
deployment.AttachFlags(root.Flags(), vip, false)
return root
}
func serverUnsupported(w io.Writer) {
_, _ = fmt.Fprintf(w, "You are using a 'slim' build of Coder, which does not support the %s subcommand.\n", cliui.Styles.Code.Render("server"))
_, _ = fmt.Fprintln(w, "")
_, _ = fmt.Fprintln(w, "Please use a build of Coder from GitHub releases:")
_, _ = fmt.Fprintln(w, " https://github.com/coder/coder/releases")
os.Exit(1)
}

View File

@ -1,3 +1,5 @@
//go:build !slim
package cli
import (

View File

@ -0,0 +1,27 @@
//go:build slim
package cli
import (
"context"
"io"
"github.com/spf13/cobra"
"golang.org/x/xerrors"
"github.com/coder/coder/cli/deployment"
agpl "github.com/coder/coder/cli"
agplcoderd "github.com/coder/coder/coderd"
)
func server() *cobra.Command {
vip := deployment.NewViper()
cmd := agpl.Server(vip, func(ctx context.Context, options *agplcoderd.Options) (*agplcoderd.API, io.Closer, error) {
return nil, nil, xerrors.Errorf("slim build does not support `coder server`")
})
deployment.AttachFlags(cmd.Flags(), vip, true)
return cmd
}

View File

@ -93,12 +93,23 @@ if [[ "$sign_darwin" == 1 ]]; then
requiredenvs AC_CERTIFICATE_FILE AC_CERTIFICATE_PASSWORD_FILE
fi
build_args=(
-ldflags "-s -w -X 'github.com/coder/coder/buildinfo.tag=$version'"
ldflags=(
-s
-w
-X "'github.com/coder/coder/buildinfo.tag=$version'"
)
if [[ "$slim" == 0 ]]; then
build_args+=(-tags embed)
else
build_args+=(-tags slim)
fi
if [[ "$agpl" == 1 ]]; then
# We don't use a tag to control AGPL because we don't want code to depend on
# a flag to control AGPL vs. enterprise behavior.
ldflags+=(-X "'github.com/coder/coder/buildinfo.agpl=true'")
fi
build_args+=(-ldflags "${ldflags[*]}")
# Compute default output path.
if [[ "$output_path" == "" ]]; then